@fluidframework/sequence 2.0.0-internal.5.1.0 → 2.0.0-internal.5.2.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +4 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/intervalCollection.d.ts +9 -19
  7. package/dist/intervalCollection.d.ts.map +1 -1
  8. package/dist/intervalCollection.js +11 -102
  9. package/dist/intervalCollection.js.map +1 -1
  10. package/dist/intervalIndex/index.d.ts +8 -0
  11. package/dist/intervalIndex/index.d.ts.map +1 -0
  12. package/dist/intervalIndex/index.js +12 -0
  13. package/dist/intervalIndex/index.js.map +1 -0
  14. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +32 -0
  15. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
  16. package/dist/intervalIndex/overlappingIntervalsIndex.js +103 -0
  17. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -0
  18. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +8 -0
  19. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
  20. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +33 -0
  21. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -0
  22. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +33 -0
  23. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
  24. package/dist/intervalIndex/sequenceIntervalIndexes.js +7 -0
  25. package/dist/intervalIndex/sequenceIntervalIndexes.js.map +1 -0
  26. package/dist/packageVersion.d.ts +1 -1
  27. package/dist/packageVersion.js +1 -1
  28. package/dist/packageVersion.js.map +1 -1
  29. package/lib/index.d.ts +1 -0
  30. package/lib/index.d.ts.map +1 -1
  31. package/lib/index.js +1 -0
  32. package/lib/index.js.map +1 -1
  33. package/lib/intervalCollection.d.ts +9 -19
  34. package/lib/intervalCollection.d.ts.map +1 -1
  35. package/lib/intervalCollection.js +10 -102
  36. package/lib/intervalCollection.js.map +1 -1
  37. package/lib/intervalIndex/index.d.ts +8 -0
  38. package/lib/intervalIndex/index.d.ts.map +1 -0
  39. package/lib/intervalIndex/index.js +7 -0
  40. package/lib/intervalIndex/index.js.map +1 -0
  41. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +32 -0
  42. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
  43. package/lib/intervalIndex/overlappingIntervalsIndex.js +98 -0
  44. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -0
  45. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +8 -0
  46. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
  47. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js +29 -0
  48. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -0
  49. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts +33 -0
  50. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
  51. package/lib/intervalIndex/sequenceIntervalIndexes.js +6 -0
  52. package/lib/intervalIndex/sequenceIntervalIndexes.js.map +1 -0
  53. package/lib/packageVersion.d.ts +1 -1
  54. package/lib/packageVersion.js +1 -1
  55. package/lib/packageVersion.js.map +1 -1
  56. package/package.json +16 -16
  57. package/src/index.ts +6 -0
  58. package/src/intervalCollection.ts +16 -139
  59. package/src/intervalIndex/index.ts +11 -0
  60. package/src/intervalIndex/overlappingIntervalsIndex.ts +166 -0
  61. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +71 -0
  62. package/src/intervalIndex/sequenceIntervalIndexes.ts +32 -0
  63. package/src/packageVersion.ts +1 -1
@@ -0,0 +1,8 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { SequenceIntervalIndexes } from "./sequenceIntervalIndexes";
6
+ export { IOverlappingIntervalsIndex, createOverlappingIntervalsIndex, } from "./overlappingIntervalsIndex";
7
+ export { createOverlappingSequenceIntervalsIndex } from "./overlappingSequenceIntervalsIndex";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/intervalIndex/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,uCAAuC,EAAE,MAAM,qCAAqC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { createOverlappingIntervalsIndex, } from "./overlappingIntervalsIndex";
6
+ export { createOverlappingSequenceIntervalsIndex } from "./overlappingSequenceIntervalsIndex";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/intervalIndex/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,+BAA+B,GAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,uCAAuC,EAAE,MAAM,qCAAqC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { SequenceIntervalIndexes } from \"./sequenceIntervalIndexes\";\nexport {\n\tIOverlappingIntervalsIndex,\n\tcreateOverlappingIntervalsIndex,\n} from \"./overlappingIntervalsIndex\";\nexport { createOverlappingSequenceIntervalsIndex } from \"./overlappingSequenceIntervalsIndex\";\n"]}
@@ -0,0 +1,32 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { Client } from "@fluidframework/merge-tree";
6
+ import { IIntervalHelpers, IntervalIndex, ISerializableInterval } from "../intervalCollection";
7
+ import { IntervalTree } from "../intervalTree";
8
+ export interface IOverlappingIntervalsIndex<TInterval extends ISerializableInterval> extends IntervalIndex<TInterval> {
9
+ /**
10
+ * @returns an array of all intervals contained in this collection that overlap the range
11
+ * `[start end]`.
12
+ */
13
+ findOverlappingIntervals(start: number, end: number): TInterval[];
14
+ /**
15
+ * Gathers the interval results based on specified parameters.
16
+ */
17
+ gatherIterationResults(results: TInterval[], iteratesForward: boolean, start?: number, end?: number): void;
18
+ }
19
+ export declare class OverlappingIntervalsIndex<TInterval extends ISerializableInterval> implements IOverlappingIntervalsIndex<TInterval> {
20
+ protected readonly intervalTree: IntervalTree<TInterval>;
21
+ protected readonly client: Client;
22
+ protected readonly helpers: IIntervalHelpers<TInterval>;
23
+ constructor(client: Client, helpers: IIntervalHelpers<TInterval>);
24
+ map(fn: (interval: TInterval) => void): void;
25
+ mapUntil(fn: (interval: TInterval) => boolean): void;
26
+ gatherIterationResults(results: TInterval[], iteratesForward: boolean, start?: number, end?: number): void;
27
+ findOverlappingIntervals(start: number, end: number): TInterval[];
28
+ remove(interval: TInterval): void;
29
+ add(interval: TInterval): void;
30
+ }
31
+ export declare function createOverlappingIntervalsIndex<TInterval extends ISerializableInterval>(client: Client, helpers: IIntervalHelpers<TInterval>): IOverlappingIntervalsIndex<TInterval>;
32
+ //# sourceMappingURL=overlappingIntervalsIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlappingIntervalsIndex.d.ts","sourceRoot":"","sources":["../../src/intervalIndex/overlappingIntervalsIndex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAEN,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAgB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,WAAW,0BAA0B,CAAC,SAAS,SAAS,qBAAqB,CAClF,SAAQ,aAAa,CAAC,SAAS,CAAC;IAChC;;;OAGG;IACH,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC;IAElE;;OAEG;IACH,sBAAsB,CACrB,OAAO,EAAE,SAAS,EAAE,EACpB,eAAe,EAAE,OAAO,EACxB,KAAK,CAAC,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,GACV,IAAI,CAAC;CACR;AAED,qBAAa,yBAAyB,CAAC,SAAS,SAAS,qBAAqB,CAC7E,YAAW,0BAA0B,CAAC,SAAS,CAAC;IAEhD,SAAS,CAAC,QAAQ,CAAC,YAAY,0BAAiC;IAChE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;gBAE5C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAKzD,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,IAAI;IAIrC,QAAQ,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,OAAO;IAI7C,sBAAsB,CAC5B,OAAO,EAAE,SAAS,EAAE,EACpB,eAAe,EAAE,OAAO,EACxB,KAAK,CAAC,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,GACV,IAAI;IA6EA,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE;IAgBjE,MAAM,CAAC,QAAQ,EAAE,SAAS;IAI1B,GAAG,CAAC,QAAQ,EAAE,SAAS;CAG9B;AAED,wBAAgB,+BAA+B,CAAC,SAAS,SAAS,qBAAqB,EACtF,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,GAClC,0BAA0B,CAAC,SAAS,CAAC,CAEvC"}
@@ -0,0 +1,98 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { IntervalType, } from "../intervalCollection";
6
+ import { IntervalTree } from "../intervalTree";
7
+ export class OverlappingIntervalsIndex {
8
+ constructor(client, helpers) {
9
+ this.intervalTree = new IntervalTree();
10
+ this.client = client;
11
+ this.helpers = helpers;
12
+ }
13
+ map(fn) {
14
+ this.intervalTree.map(fn);
15
+ }
16
+ mapUntil(fn) {
17
+ this.intervalTree.mapUntil(fn);
18
+ }
19
+ gatherIterationResults(results, iteratesForward, start, end) {
20
+ if (this.intervalTree.intervals.isEmpty()) {
21
+ return;
22
+ }
23
+ if (start === undefined && end === undefined) {
24
+ // No start/end provided. Gather the whole tree in the specified order.
25
+ if (iteratesForward) {
26
+ this.intervalTree.map((interval) => {
27
+ results.push(interval);
28
+ });
29
+ }
30
+ else {
31
+ this.intervalTree.mapBackward((interval) => {
32
+ results.push(interval);
33
+ });
34
+ }
35
+ }
36
+ else {
37
+ const transientInterval = this.helpers.create("transient", start, end, this.client, IntervalType.Transient);
38
+ if (start === undefined) {
39
+ // Only end position provided. Since the tree is not sorted by end position,
40
+ // walk the whole tree in the specified order, gathering intervals that match the end.
41
+ if (iteratesForward) {
42
+ this.intervalTree.map((interval) => {
43
+ if (transientInterval.compareEnd(interval) === 0) {
44
+ results.push(interval);
45
+ }
46
+ });
47
+ }
48
+ else {
49
+ this.intervalTree.mapBackward((interval) => {
50
+ if (transientInterval.compareEnd(interval) === 0) {
51
+ results.push(interval);
52
+ }
53
+ });
54
+ }
55
+ }
56
+ else {
57
+ // Start and (possibly) end provided. Walk the subtrees that may contain
58
+ // this start position.
59
+ const compareFn = end === undefined
60
+ ? (node) => {
61
+ return transientInterval.compareStart(node.key);
62
+ }
63
+ : (node) => {
64
+ return transientInterval.compare(node.key);
65
+ };
66
+ const continueLeftFn = (cmpResult) => cmpResult <= 0;
67
+ const continueRightFn = (cmpResult) => cmpResult >= 0;
68
+ const actionFn = (node) => {
69
+ results.push(node.key);
70
+ };
71
+ if (iteratesForward) {
72
+ this.intervalTree.intervals.walkExactMatchesForward(compareFn, actionFn, continueLeftFn, continueRightFn);
73
+ }
74
+ else {
75
+ this.intervalTree.intervals.walkExactMatchesBackward(compareFn, actionFn, continueLeftFn, continueRightFn);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ findOverlappingIntervals(start, end) {
81
+ if (end < start || this.intervalTree.intervals.isEmpty()) {
82
+ return [];
83
+ }
84
+ const transientInterval = this.helpers.create("transient", start, end, this.client, IntervalType.Transient);
85
+ const overlappingIntervalNodes = this.intervalTree.match(transientInterval);
86
+ return overlappingIntervalNodes.map((node) => node.key);
87
+ }
88
+ remove(interval) {
89
+ this.intervalTree.removeExisting(interval);
90
+ }
91
+ add(interval) {
92
+ this.intervalTree.put(interval);
93
+ }
94
+ }
95
+ export function createOverlappingIntervalsIndex(client, helpers) {
96
+ return new OverlappingIntervalsIndex(client, helpers);
97
+ }
98
+ //# sourceMappingURL=overlappingIntervalsIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlappingIntervalsIndex.js","sourceRoot":"","sources":["../../src/intervalIndex/overlappingIntervalsIndex.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 { Client } from \"@fluidframework/merge-tree\";\nimport {\n\tIntervalType,\n\tIIntervalHelpers,\n\tIntervalIndex,\n\tISerializableInterval,\n} from \"../intervalCollection\";\nimport { IntervalNode, IntervalTree } from \"../intervalTree\";\n\nexport interface IOverlappingIntervalsIndex<TInterval extends ISerializableInterval>\n\textends IntervalIndex<TInterval> {\n\t/**\n\t * @returns an array of all intervals contained in this collection that overlap the range\n\t * `[start end]`.\n\t */\n\tfindOverlappingIntervals(start: number, end: number): TInterval[];\n\n\t/**\n\t * Gathers the interval results based on specified parameters.\n\t */\n\tgatherIterationResults(\n\t\tresults: TInterval[],\n\t\titeratesForward: boolean,\n\t\tstart?: number,\n\t\tend?: number,\n\t): void;\n}\n\nexport class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>\n\timplements IOverlappingIntervalsIndex<TInterval>\n{\n\tprotected readonly intervalTree = new IntervalTree<TInterval>();\n\tprotected readonly client: Client;\n\tprotected readonly helpers: IIntervalHelpers<TInterval>;\n\n\tconstructor(client: Client, helpers: IIntervalHelpers<TInterval>) {\n\t\tthis.client = client;\n\t\tthis.helpers = helpers;\n\t}\n\n\tpublic map(fn: (interval: TInterval) => void) {\n\t\tthis.intervalTree.map(fn);\n\t}\n\n\tpublic mapUntil(fn: (interval: TInterval) => boolean) {\n\t\tthis.intervalTree.mapUntil(fn);\n\t}\n\n\tpublic gatherIterationResults(\n\t\tresults: TInterval[],\n\t\titeratesForward: boolean,\n\t\tstart?: number,\n\t\tend?: number,\n\t): void {\n\t\tif (this.intervalTree.intervals.isEmpty()) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (start === undefined && end === undefined) {\n\t\t\t// No start/end provided. Gather the whole tree in the specified order.\n\t\t\tif (iteratesForward) {\n\t\t\t\tthis.intervalTree.map((interval: TInterval) => {\n\t\t\t\t\tresults.push(interval);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.intervalTree.mapBackward((interval: TInterval) => {\n\t\t\t\t\tresults.push(interval);\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tconst transientInterval: TInterval = this.helpers.create(\n\t\t\t\t\"transient\",\n\t\t\t\tstart,\n\t\t\t\tend,\n\t\t\t\tthis.client,\n\t\t\t\tIntervalType.Transient,\n\t\t\t);\n\n\t\t\tif (start === undefined) {\n\t\t\t\t// Only end position provided. Since the tree is not sorted by end position,\n\t\t\t\t// walk the whole tree in the specified order, gathering intervals that match the end.\n\t\t\t\tif (iteratesForward) {\n\t\t\t\t\tthis.intervalTree.map((interval: TInterval) => {\n\t\t\t\t\t\tif (transientInterval.compareEnd(interval) === 0) {\n\t\t\t\t\t\t\tresults.push(interval);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthis.intervalTree.mapBackward((interval: TInterval) => {\n\t\t\t\t\t\tif (transientInterval.compareEnd(interval) === 0) {\n\t\t\t\t\t\t\tresults.push(interval);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Start and (possibly) end provided. Walk the subtrees that may contain\n\t\t\t\t// this start position.\n\t\t\t\tconst compareFn =\n\t\t\t\t\tend === undefined\n\t\t\t\t\t\t? (node: IntervalNode<TInterval>) => {\n\t\t\t\t\t\t\t\treturn transientInterval.compareStart(node.key);\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: (node: IntervalNode<TInterval>) => {\n\t\t\t\t\t\t\t\treturn transientInterval.compare(node.key);\n\t\t\t\t\t\t };\n\t\t\t\tconst continueLeftFn = (cmpResult: number) => cmpResult <= 0;\n\t\t\t\tconst continueRightFn = (cmpResult: number) => cmpResult >= 0;\n\t\t\t\tconst actionFn = (node: IntervalNode<TInterval>) => {\n\t\t\t\t\tresults.push(node.key);\n\t\t\t\t};\n\n\t\t\t\tif (iteratesForward) {\n\t\t\t\t\tthis.intervalTree.intervals.walkExactMatchesForward(\n\t\t\t\t\t\tcompareFn,\n\t\t\t\t\t\tactionFn,\n\t\t\t\t\t\tcontinueLeftFn,\n\t\t\t\t\t\tcontinueRightFn,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.intervalTree.intervals.walkExactMatchesBackward(\n\t\t\t\t\t\tcompareFn,\n\t\t\t\t\t\tactionFn,\n\t\t\t\t\t\tcontinueLeftFn,\n\t\t\t\t\t\tcontinueRightFn,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic findOverlappingIntervals(start: number, end: number): TInterval[] {\n\t\tif (end < start || this.intervalTree.intervals.isEmpty()) {\n\t\t\treturn [];\n\t\t}\n\t\tconst transientInterval = this.helpers.create(\n\t\t\t\"transient\",\n\t\t\tstart,\n\t\t\tend,\n\t\t\tthis.client,\n\t\t\tIntervalType.Transient,\n\t\t);\n\n\t\tconst overlappingIntervalNodes = this.intervalTree.match(transientInterval);\n\t\treturn overlappingIntervalNodes.map((node) => node.key);\n\t}\n\n\tpublic remove(interval: TInterval) {\n\t\tthis.intervalTree.removeExisting(interval);\n\t}\n\n\tpublic add(interval: TInterval) {\n\t\tthis.intervalTree.put(interval);\n\t}\n}\n\nexport function createOverlappingIntervalsIndex<TInterval extends ISerializableInterval>(\n\tclient: Client,\n\thelpers: IIntervalHelpers<TInterval>,\n): IOverlappingIntervalsIndex<TInterval> {\n\treturn new OverlappingIntervalsIndex<TInterval>(client, helpers);\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { Client } from "@fluidframework/merge-tree";
6
+ import { SequenceIntervalIndexes } from "./sequenceIntervalIndexes";
7
+ export declare function createOverlappingSequenceIntervalsIndex(client: Client): SequenceIntervalIndexes.Overlapping;
8
+ //# sourceMappingURL=overlappingSequenceIntervalsIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlappingSequenceIntervalsIndex.d.ts","sourceRoot":"","sources":["../../src/intervalIndex/overlappingSequenceIntervalsIndex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,MAAM,EAKN,MAAM,4BAA4B,CAAC;AAOpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAgDpE,wBAAgB,uCAAuC,CACtD,MAAM,EAAE,MAAM,GACZ,uBAAuB,CAAC,WAAW,CAErC"}
@@ -0,0 +1,29 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { ReferenceType, compareReferencePositions, reservedRangeLabelsKey, } from "@fluidframework/merge-tree";
6
+ import { sequenceIntervalHelpers, IntervalType, SequenceInterval, createPositionReferenceFromSegoff, } from "../intervalCollection";
7
+ import { OverlappingIntervalsIndex } from "./overlappingIntervalsIndex";
8
+ class OverlappingSequenceIntervalsIndex extends OverlappingIntervalsIndex {
9
+ constructor(client) {
10
+ super(client, sequenceIntervalHelpers);
11
+ }
12
+ findOverlappingIntervalsBySegoff(startSegoff, endSegoff) {
13
+ if (this.intervalTree.intervals.isEmpty()) {
14
+ return [];
15
+ }
16
+ const startLref = createPositionReferenceFromSegoff(this.client, startSegoff, ReferenceType.Transient);
17
+ const endLref = createPositionReferenceFromSegoff(this.client, endSegoff, ReferenceType.Transient);
18
+ if (compareReferencePositions(startLref, endLref) > 0) {
19
+ return [];
20
+ }
21
+ const transientInterval = new SequenceInterval(this.client, startLref, endLref, IntervalType.Transient, { [reservedRangeLabelsKey]: ["transient"] });
22
+ const overlappingIntervalNodes = this.intervalTree.match(transientInterval);
23
+ return overlappingIntervalNodes.map((node) => node.key);
24
+ }
25
+ }
26
+ export function createOverlappingSequenceIntervalsIndex(client) {
27
+ return new OverlappingSequenceIntervalsIndex(client);
28
+ }
29
+ //# sourceMappingURL=overlappingSequenceIntervalsIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlappingSequenceIntervalsIndex.js","sourceRoot":"","sources":["../../src/intervalIndex/overlappingSequenceIntervalsIndex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGN,aAAa,EACb,yBAAyB,EACzB,sBAAsB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACN,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,iCAAiC,GACjC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,MAAM,iCACL,SAAQ,yBAA2C;IAGnD,YAAY,MAAc;QACzB,KAAK,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACxC,CAAC;IAEM,gCAAgC,CACtC,WAA0E,EAC1E,SAAwE;QAExE,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE;YAC1C,OAAO,EAAE,CAAC;SACV;QAED,MAAM,SAAS,GAAG,iCAAiC,CAClD,IAAI,CAAC,MAAM,EACX,WAAW,EACX,aAAa,CAAC,SAAS,CACvB,CAAC;QAEF,MAAM,OAAO,GAAG,iCAAiC,CAChD,IAAI,CAAC,MAAM,EACX,SAAS,EACT,aAAa,CAAC,SAAS,CACvB,CAAC;QAEF,IAAI,yBAAyB,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE;YACtD,OAAO,EAAE,CAAC;SACV;QAED,MAAM,iBAAiB,GAAG,IAAI,gBAAgB,CAC7C,IAAI,CAAC,MAAM,EACX,SAAS,EACT,OAAO,EACP,YAAY,CAAC,SAAS,EACtB,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAC3C,CAAC;QAEF,MAAM,wBAAwB,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC5E,OAAO,wBAAwB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;CACD;AAED,MAAM,UAAU,uCAAuC,CACtD,MAAc;IAEd,OAAO,IAAI,iCAAiC,CAAC,MAAM,CAAC,CAAC;AACtD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tClient,\n\tISegment,\n\tReferenceType,\n\tcompareReferencePositions,\n\treservedRangeLabelsKey,\n} from \"@fluidframework/merge-tree\";\nimport {\n\tsequenceIntervalHelpers,\n\tIntervalType,\n\tSequenceInterval,\n\tcreatePositionReferenceFromSegoff,\n} from \"../intervalCollection\";\nimport { SequenceIntervalIndexes } from \"./sequenceIntervalIndexes\";\nimport { OverlappingIntervalsIndex } from \"./overlappingIntervalsIndex\";\n\nclass OverlappingSequenceIntervalsIndex\n\textends OverlappingIntervalsIndex<SequenceInterval>\n\timplements SequenceIntervalIndexes.Overlapping\n{\n\tconstructor(client: Client) {\n\t\tsuper(client, sequenceIntervalHelpers);\n\t}\n\n\tpublic findOverlappingIntervalsBySegoff(\n\t\tstartSegoff: { segment: ISegment | undefined; offset: number | undefined },\n\t\tendSegoff: { segment: ISegment | undefined; offset: number | undefined },\n\t): Iterable<SequenceInterval> {\n\t\tif (this.intervalTree.intervals.isEmpty()) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst startLref = createPositionReferenceFromSegoff(\n\t\t\tthis.client,\n\t\t\tstartSegoff,\n\t\t\tReferenceType.Transient,\n\t\t);\n\n\t\tconst endLref = createPositionReferenceFromSegoff(\n\t\t\tthis.client,\n\t\t\tendSegoff,\n\t\t\tReferenceType.Transient,\n\t\t);\n\n\t\tif (compareReferencePositions(startLref, endLref) > 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst transientInterval = new SequenceInterval(\n\t\t\tthis.client,\n\t\t\tstartLref,\n\t\t\tendLref,\n\t\t\tIntervalType.Transient,\n\t\t\t{ [reservedRangeLabelsKey]: [\"transient\"] },\n\t\t);\n\n\t\tconst overlappingIntervalNodes = this.intervalTree.match(transientInterval);\n\t\treturn overlappingIntervalNodes.map((node) => node.key);\n\t}\n}\n\nexport function createOverlappingSequenceIntervalsIndex(\n\tclient: Client,\n): SequenceIntervalIndexes.Overlapping {\n\treturn new OverlappingSequenceIntervalsIndex(client);\n}\n"]}
@@ -0,0 +1,33 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { ISegment } from "@fluidframework/merge-tree";
6
+ import { SequenceInterval } from "../intervalCollection";
7
+ import { IOverlappingIntervalsIndex } from "./overlappingIntervalsIndex";
8
+ /**
9
+ * This namespace contains specialiazations of indexes which support spatial queries
10
+ * specifically for `SequenceInterval`s.
11
+ */
12
+ export declare namespace SequenceIntervalIndexes {
13
+ /**
14
+ * Collection of intervals.
15
+ *
16
+ * Provides additional APIs to support efficiently querying a collection of intervals based on segments and offset.
17
+ */
18
+ interface Overlapping extends IOverlappingIntervalsIndex<SequenceInterval> {
19
+ /**
20
+ * Finds overlapping intervals within the specified range.
21
+ *
22
+ * @returns an array of all intervals that overlap with the specified SegOff range (includes both ends)
23
+ */
24
+ findOverlappingIntervalsBySegoff(startSegoff: {
25
+ segment: ISegment | undefined;
26
+ offset: number | undefined;
27
+ }, endSegoff: {
28
+ segment: ISegment | undefined;
29
+ offset: number | undefined;
30
+ }): any;
31
+ }
32
+ }
33
+ //# sourceMappingURL=sequenceIntervalIndexes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequenceIntervalIndexes.d.ts","sourceRoot":"","sources":["../../src/intervalIndex/sequenceIntervalIndexes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEzE;;;GAGG;AAEH,yBAAiB,uBAAuB,CAAC;IACxC;;;;OAIG;IACH,UAAiB,WAAY,SAAQ,0BAA0B,CAAC,gBAAgB,CAAC;QAChF;;;;WAIG;QACH,gCAAgC,CAC/B,WAAW,EAAE;YAAE,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;YAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE,EAC1E,SAAS,EAAE;YAAE,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;YAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE,OACvE;KACF;CACD"}
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=sequenceIntervalIndexes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequenceIntervalIndexes.js","sourceRoot":"","sources":["../../src/intervalIndex/sequenceIntervalIndexes.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISegment } from \"@fluidframework/merge-tree\";\nimport { SequenceInterval } from \"../intervalCollection\";\nimport { IOverlappingIntervalsIndex } from \"./overlappingIntervalsIndex\";\n\n/**\n * This namespace contains specialiazations of indexes which support spatial queries\n * specifically for `SequenceInterval`s.\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace SequenceIntervalIndexes {\n\t/**\n\t * Collection of intervals.\n\t *\n\t * Provides additional APIs to support efficiently querying a collection of intervals based on segments and offset.\n\t */\n\texport interface Overlapping extends IOverlappingIntervalsIndex<SequenceInterval> {\n\t\t/**\n\t\t * Finds overlapping intervals within the specified range.\n\t\t *\n\t\t * @returns an array of all intervals that overlap with the specified SegOff range (includes both ends)\n\t\t */\n\t\tfindOverlappingIntervalsBySegoff(\n\t\t\tstartSegoff: { segment: ISegment | undefined; offset: number | undefined },\n\t\t\tendSegoff: { segment: ISegment | undefined; offset: number | undefined },\n\t\t);\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/sequence";
8
- export declare const pkgVersion = "2.0.0-internal.5.1.0";
8
+ export declare const pkgVersion = "2.0.0-internal.5.2.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/sequence";
8
- export const pkgVersion = "2.0.0-internal.5.1.0";
8
+ export const pkgVersion = "2.0.0-internal.5.2.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,0BAA0B,CAAC;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/sequence\";\nexport const pkgVersion = \"2.0.0-internal.5.1.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,0BAA0B,CAAC;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/sequence\";\nexport const pkgVersion = \"2.0.0-internal.5.2.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/sequence",
3
- "version": "2.0.0-internal.5.1.0",
3
+ "version": "2.0.0-internal.5.2.0",
4
4
  "description": "Distributed sequence",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -37,30 +37,30 @@
37
37
  "dependencies": {
38
38
  "@fluidframework/common-definitions": "^0.20.1",
39
39
  "@fluidframework/common-utils": "^1.1.1",
40
- "@fluidframework/container-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
41
- "@fluidframework/core-interfaces": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
42
- "@fluidframework/datastore-definitions": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
43
- "@fluidframework/merge-tree": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
40
+ "@fluidframework/container-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
41
+ "@fluidframework/core-interfaces": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
42
+ "@fluidframework/datastore-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
43
+ "@fluidframework/merge-tree": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
44
44
  "@fluidframework/protocol-definitions": "^1.1.0",
45
- "@fluidframework/runtime-definitions": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
46
- "@fluidframework/runtime-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
47
- "@fluidframework/shared-object-base": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
48
- "@fluidframework/telemetry-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
45
+ "@fluidframework/runtime-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
46
+ "@fluidframework/runtime-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
47
+ "@fluidframework/shared-object-base": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
48
+ "@fluidframework/telemetry-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
49
49
  "uuid": "^8.3.1"
50
50
  },
51
51
  "devDependencies": {
52
- "@fluid-internal/stochastic-test-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
53
- "@fluid-internal/test-dds-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
54
- "@fluid-tools/benchmark": "^0.47.0",
55
- "@fluid-tools/build-cli": "^0.19.0",
52
+ "@fluid-internal/stochastic-test-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
53
+ "@fluid-internal/test-dds-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
54
+ "@fluid-tools/benchmark": "^0.48.0",
55
+ "@fluid-tools/build-cli": "^0.20.0",
56
56
  "@fluidframework/build-common": "^1.2.0",
57
- "@fluidframework/build-tools": "^0.19.0",
57
+ "@fluidframework/build-tools": "^0.20.0",
58
58
  "@fluidframework/eslint-config-fluid": "^2.0.0",
59
59
  "@fluidframework/gitresources": "^0.1039.1000",
60
- "@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
60
+ "@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
61
61
  "@fluidframework/sequence-previous": "npm:@fluidframework/sequence@2.0.0-internal.5.0.0",
62
62
  "@fluidframework/server-services-client": "^0.1039.1000",
63
- "@fluidframework/test-runtime-utils": ">=2.0.0-internal.5.1.0 <2.0.0-internal.5.2.0",
63
+ "@fluidframework/test-runtime-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
64
64
  "@microsoft/api-extractor": "^7.34.4",
65
65
  "@types/diff": "^3.5.1",
66
66
  "@types/mocha": "^9.1.1",
package/src/index.ts CHANGED
@@ -39,6 +39,12 @@ export {
39
39
  createStartpointInRangeIndex,
40
40
  } from "./intervalCollection";
41
41
  export { IInterval, IntervalConflictResolver } from "./intervalTree";
42
+ export {
43
+ SequenceIntervalIndexes,
44
+ IOverlappingIntervalsIndex,
45
+ createOverlappingIntervalsIndex,
46
+ createOverlappingSequenceIntervalsIndex,
47
+ } from "./intervalIndex";
42
48
  export {
43
49
  appendAddIntervalToRevertibles,
44
50
  appendChangeIntervalToRevertibles,
@@ -43,7 +43,8 @@ import {
43
43
  IValueTypeOperationValue,
44
44
  SequenceOptions,
45
45
  } from "./defaultMapInterfaces";
46
- import { IInterval, IntervalConflictResolver, IntervalTree, IntervalNode } from "./intervalTree";
46
+ import { IInterval, IntervalConflictResolver } from "./intervalTree";
47
+ import { IOverlappingIntervalsIndex, createOverlappingIntervalsIndex } from "./intervalIndex";
47
48
 
48
49
  const reservedIntervalIdKey = "intervalId";
49
50
 
@@ -772,7 +773,7 @@ export class SequenceInterval implements ISerializableInterval {
772
773
  }
773
774
  }
774
775
 
775
- function createPositionReferenceFromSegoff(
776
+ export function createPositionReferenceFromSegoff(
776
777
  client: Client,
777
778
  segoff: { segment: ISegment | undefined; offset: number | undefined },
778
779
  refType: ReferenceType,
@@ -889,6 +890,7 @@ export function createSequenceInterval(
889
890
  undefined,
890
891
  startReferenceSlidingPreference(stickiness),
891
892
  );
893
+
892
894
  const endLref = createPositionReference(
893
895
  client,
894
896
  end,
@@ -898,6 +900,7 @@ export function createSequenceInterval(
898
900
  undefined,
899
901
  endReferenceSlidingPreference(stickiness),
900
902
  );
903
+
901
904
  const rangeProp = {
902
905
  [reservedRangeLabelsKey]: [label],
903
906
  };
@@ -949,135 +952,6 @@ export interface IntervalIndex<TInterval extends ISerializableInterval> {
949
952
  remove(interval: TInterval): void;
950
953
  }
951
954
 
952
- class OverlappingIntervalsIndex<TInterval extends ISerializableInterval>
953
- implements IntervalIndex<TInterval>
954
- {
955
- private readonly intervalTree = new IntervalTree<TInterval>();
956
-
957
- constructor(
958
- private readonly client: Client,
959
- private readonly helpers: IIntervalHelpers<TInterval>,
960
- ) {}
961
-
962
- public map(fn: (interval: TInterval) => void) {
963
- this.intervalTree.map(fn);
964
- }
965
-
966
- public mapUntil(fn: (interval: TInterval) => boolean) {
967
- this.intervalTree.mapUntil(fn);
968
- }
969
-
970
- public gatherIterationResults(
971
- results: TInterval[],
972
- iteratesForward: boolean,
973
- start?: number,
974
- end?: number,
975
- ) {
976
- if (this.intervalTree.intervals.isEmpty()) {
977
- return;
978
- }
979
-
980
- if (start === undefined && end === undefined) {
981
- // No start/end provided. Gather the whole tree in the specified order.
982
- if (iteratesForward) {
983
- this.intervalTree.map((interval: TInterval) => {
984
- results.push(interval);
985
- });
986
- } else {
987
- this.intervalTree.mapBackward((interval: TInterval) => {
988
- results.push(interval);
989
- });
990
- }
991
- } else {
992
- const transientInterval: TInterval = this.helpers.create(
993
- "transient",
994
- start,
995
- end,
996
- this.client,
997
- IntervalType.Transient,
998
- );
999
-
1000
- if (start === undefined) {
1001
- // Only end position provided. Since the tree is not sorted by end position,
1002
- // walk the whole tree in the specified order, gathering intervals that match the end.
1003
- if (iteratesForward) {
1004
- this.intervalTree.map((interval: TInterval) => {
1005
- if (transientInterval.compareEnd(interval) === 0) {
1006
- results.push(interval);
1007
- }
1008
- });
1009
- } else {
1010
- this.intervalTree.mapBackward((interval: TInterval) => {
1011
- if (transientInterval.compareEnd(interval) === 0) {
1012
- results.push(interval);
1013
- }
1014
- });
1015
- }
1016
- } else {
1017
- // Start and (possibly) end provided. Walk the subtrees that may contain
1018
- // this start position.
1019
- const compareFn =
1020
- end === undefined
1021
- ? (node: IntervalNode<TInterval>) => {
1022
- return transientInterval.compareStart(node.key);
1023
- }
1024
- : (node: IntervalNode<TInterval>) => {
1025
- return transientInterval.compare(node.key);
1026
- };
1027
- const continueLeftFn = (cmpResult: number) => cmpResult <= 0;
1028
- const continueRightFn = (cmpResult: number) => cmpResult >= 0;
1029
- const actionFn = (node: IntervalNode<TInterval>) => {
1030
- results.push(node.key);
1031
- };
1032
-
1033
- if (iteratesForward) {
1034
- this.intervalTree.intervals.walkExactMatchesForward(
1035
- compareFn,
1036
- actionFn,
1037
- continueLeftFn,
1038
- continueRightFn,
1039
- );
1040
- } else {
1041
- this.intervalTree.intervals.walkExactMatchesBackward(
1042
- compareFn,
1043
- actionFn,
1044
- continueLeftFn,
1045
- continueRightFn,
1046
- );
1047
- }
1048
- }
1049
- }
1050
- }
1051
-
1052
- /**
1053
- * @returns an array of all intervals contained in this collection that overlap the range
1054
- * `[startPosition, endPosition)`.
1055
- */
1056
- public findOverlappingIntervals(startPosition: number, endPosition: number) {
1057
- if (endPosition < startPosition || this.intervalTree.intervals.isEmpty()) {
1058
- return [];
1059
- }
1060
- const transientInterval = this.helpers.create(
1061
- "transient",
1062
- startPosition,
1063
- endPosition,
1064
- this.client,
1065
- IntervalType.Transient,
1066
- );
1067
-
1068
- const overlappingIntervalNodes = this.intervalTree.match(transientInterval);
1069
- return overlappingIntervalNodes.map((node) => node.key);
1070
- }
1071
-
1072
- public remove(interval: TInterval) {
1073
- this.intervalTree.removeExisting(interval);
1074
- }
1075
-
1076
- public add(interval: TInterval) {
1077
- this.intervalTree.put(interval);
1078
- }
1079
- }
1080
-
1081
955
  class IdIntervalIndex<TInterval extends ISerializableInterval>
1082
956
  implements IntervalIndex<TInterval>, Iterable<TInterval>
1083
957
  {
@@ -1380,7 +1254,7 @@ export function createStartpointInRangeIndex<TInterval extends ISerializableInte
1380
1254
 
1381
1255
  export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
1382
1256
  private static readonly legacyIdPrefix = "legacy";
1383
- public readonly overlappingIntervalsIndex: OverlappingIntervalsIndex<TInterval>;
1257
+ public readonly overlappingIntervalsIndex: IOverlappingIntervalsIndex<TInterval>;
1384
1258
  public readonly idIntervalIndex: IdIntervalIndex<TInterval>;
1385
1259
  public readonly endIntervalIndex: EndpointIndex<TInterval>;
1386
1260
  private readonly indexes: Set<IntervalIndex<TInterval>>;
@@ -1395,7 +1269,7 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
1395
1269
  previousInterval: TInterval,
1396
1270
  ) => void,
1397
1271
  ) {
1398
- this.overlappingIntervalsIndex = new OverlappingIntervalsIndex(client, helpers);
1272
+ this.overlappingIntervalsIndex = createOverlappingIntervalsIndex(client, helpers);
1399
1273
  this.idIntervalIndex = new IdIntervalIndex();
1400
1274
  this.endIntervalIndex = new EndpointIndex(client, helpers);
1401
1275
  this.indexes = new Set([
@@ -1839,6 +1713,7 @@ export interface IIntervalCollectionEvent<TInterval extends ISerializableInterva
1839
1713
  * endpoints. These references should be used for position information only.
1840
1714
  * `local` reflects whether the change originated locally.
1841
1715
  * `op` is defined if and only if the server has acked this change.
1716
+ * `slide` is true if the change is due to sliding on removal of position
1842
1717
  */
1843
1718
  (
1844
1719
  event: "changeInterval",
@@ -1847,6 +1722,7 @@ export interface IIntervalCollectionEvent<TInterval extends ISerializableInterva
1847
1722
  previousInterval: TInterval,
1848
1723
  local: boolean,
1849
1724
  op: ISequencedDocumentMessage | undefined,
1725
+ slide: boolean,
1850
1726
  ) => void,
1851
1727
  );
1852
1728
  /**
@@ -2176,7 +2052,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
2176
2052
  client,
2177
2053
  label,
2178
2054
  this.helpers,
2179
- (interval, previousInterval) => this.emitChange(interval, previousInterval, true),
2055
+ (interval, previousInterval) => this.emitChange(interval, previousInterval, true, true),
2180
2056
  );
2181
2057
  if (this.savedSerializedIntervals) {
2182
2058
  for (const serializedInterval of this.savedSerializedIntervals) {
@@ -2216,6 +2092,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
2216
2092
  interval: TInterval,
2217
2093
  previousInterval: TInterval,
2218
2094
  local: boolean,
2095
+ slide: boolean,
2219
2096
  op?: ISequencedDocumentMessage,
2220
2097
  ): void {
2221
2098
  // Temporarily make references transient so that positional queries work (non-transient refs
@@ -2228,11 +2105,11 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
2228
2105
  endRefType = previousInterval.end.refType;
2229
2106
  previousInterval.start.refType = ReferenceType.Transient;
2230
2107
  previousInterval.end.refType = ReferenceType.Transient;
2231
- this.emit("changeInterval", interval, previousInterval, local, op);
2108
+ this.emit("changeInterval", interval, previousInterval, local, op, slide);
2232
2109
  previousInterval.start.refType = startRefType;
2233
2110
  previousInterval.end.refType = endRefType;
2234
2111
  } else {
2235
- this.emit("changeInterval", interval, previousInterval, local, op);
2112
+ this.emit("changeInterval", interval, previousInterval, local, op, slide);
2236
2113
  }
2237
2114
  }
2238
2115
 
@@ -2402,7 +2279,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
2402
2279
  this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
2403
2280
  this.emitter.emit("change", undefined, serializedInterval, { localSeq });
2404
2281
  this.addPendingChange(id, serializedInterval);
2405
- this.emitChange(newInterval, interval, true);
2282
+ this.emitChange(newInterval, interval, true, false);
2406
2283
  return newInterval;
2407
2284
  }
2408
2285
  // No interval to change
@@ -2538,7 +2415,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
2538
2415
  }
2539
2416
 
2540
2417
  if (newInterval !== interval) {
2541
- this.emitChange(newInterval, interval, local, op);
2418
+ this.emitChange(newInterval, interval, local, false, op);
2542
2419
  }
2543
2420
 
2544
2421
  const changedProperties = Object.keys(newProps).length > 0;
@@ -2761,7 +2638,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
2761
2638
  oldSeg?.localRefs?.addLocalRef(oldInterval.end, oldInterval.end.getOffset());
2762
2639
  }
2763
2640
  this.localCollection.add(interval);
2764
- this.emitChange(interval, oldInterval as TInterval, true, op);
2641
+ this.emitChange(interval, oldInterval as TInterval, true, true, op);
2765
2642
  }
2766
2643
  }
2767
2644