@fluidframework/sequence 2.0.0-internal.3.0.2 → 2.0.0-internal.3.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 (94) hide show
  1. package/.eslintrc.js +9 -12
  2. package/.mocharc.js +2 -2
  3. package/.vscode/launch.json +15 -14
  4. package/README.md +188 -179
  5. package/api-extractor.json +2 -2
  6. package/dist/defaultMap.d.ts.map +1 -1
  7. package/dist/defaultMap.js +5 -4
  8. package/dist/defaultMap.js.map +1 -1
  9. package/dist/defaultMapInterfaces.d.ts.map +1 -1
  10. package/dist/defaultMapInterfaces.js.map +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/intervalCollection.d.ts.map +1 -1
  15. package/dist/intervalCollection.js +50 -36
  16. package/dist/intervalCollection.js.map +1 -1
  17. package/dist/intervalTree.d.ts.map +1 -1
  18. package/dist/intervalTree.js.map +1 -1
  19. package/dist/localValues.d.ts.map +1 -1
  20. package/dist/localValues.js.map +1 -1
  21. package/dist/packageVersion.d.ts +1 -1
  22. package/dist/packageVersion.js +1 -1
  23. package/dist/packageVersion.js.map +1 -1
  24. package/dist/sequence.d.ts +1 -1
  25. package/dist/sequence.d.ts.map +1 -1
  26. package/dist/sequence.js +13 -17
  27. package/dist/sequence.js.map +1 -1
  28. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  29. package/dist/sequenceDeltaEvent.js.map +1 -1
  30. package/dist/sequenceFactory.d.ts.map +1 -1
  31. package/dist/sequenceFactory.js.map +1 -1
  32. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  33. package/dist/sharedIntervalCollection.js.map +1 -1
  34. package/dist/sharedSequence.d.ts.map +1 -1
  35. package/dist/sharedSequence.js +3 -3
  36. package/dist/sharedSequence.js.map +1 -1
  37. package/dist/sharedString.d.ts.map +1 -1
  38. package/dist/sharedString.js +5 -4
  39. package/dist/sharedString.js.map +1 -1
  40. package/lib/defaultMap.d.ts.map +1 -1
  41. package/lib/defaultMap.js +6 -5
  42. package/lib/defaultMap.js.map +1 -1
  43. package/lib/defaultMapInterfaces.d.ts.map +1 -1
  44. package/lib/defaultMapInterfaces.js.map +1 -1
  45. package/lib/index.d.ts +2 -2
  46. package/lib/index.d.ts.map +1 -1
  47. package/lib/index.js +2 -2
  48. package/lib/index.js.map +1 -1
  49. package/lib/intervalCollection.d.ts.map +1 -1
  50. package/lib/intervalCollection.js +50 -36
  51. package/lib/intervalCollection.js.map +1 -1
  52. package/lib/intervalTree.d.ts.map +1 -1
  53. package/lib/intervalTree.js.map +1 -1
  54. package/lib/localValues.d.ts.map +1 -1
  55. package/lib/localValues.js +1 -1
  56. package/lib/localValues.js.map +1 -1
  57. package/lib/packageVersion.d.ts +1 -1
  58. package/lib/packageVersion.js +1 -1
  59. package/lib/packageVersion.js.map +1 -1
  60. package/lib/sequence.d.ts +1 -1
  61. package/lib/sequence.d.ts.map +1 -1
  62. package/lib/sequence.js +15 -19
  63. package/lib/sequence.js.map +1 -1
  64. package/lib/sequenceDeltaEvent.d.ts.map +1 -1
  65. package/lib/sequenceDeltaEvent.js.map +1 -1
  66. package/lib/sequenceFactory.d.ts.map +1 -1
  67. package/lib/sequenceFactory.js +1 -1
  68. package/lib/sequenceFactory.js.map +1 -1
  69. package/lib/sharedIntervalCollection.d.ts.map +1 -1
  70. package/lib/sharedIntervalCollection.js.map +1 -1
  71. package/lib/sharedSequence.d.ts.map +1 -1
  72. package/lib/sharedSequence.js +4 -4
  73. package/lib/sharedSequence.js.map +1 -1
  74. package/lib/sharedString.d.ts.map +1 -1
  75. package/lib/sharedString.js +5 -4
  76. package/lib/sharedString.js.map +1 -1
  77. package/package.json +55 -55
  78. package/prettier.config.cjs +1 -1
  79. package/src/defaultMap.ts +406 -405
  80. package/src/defaultMapInterfaces.ts +120 -115
  81. package/src/index.ts +27 -17
  82. package/src/intervalCollection.ts +2198 -1997
  83. package/src/intervalTree.ts +139 -139
  84. package/src/localValues.ts +64 -73
  85. package/src/packageVersion.ts +1 -1
  86. package/src/sequence.ts +739 -694
  87. package/src/sequenceDeltaEvent.ts +143 -137
  88. package/src/sequenceFactory.ts +48 -46
  89. package/src/sharedIntervalCollection.ts +150 -136
  90. package/src/sharedSequence.ts +165 -160
  91. package/src/sharedString.ts +385 -343
  92. package/tsconfig.esnext.json +6 -6
  93. package/tsconfig.json +8 -12
  94. package/.editorconfig +0 -7
@@ -5,24 +5,24 @@
5
5
 
6
6
  import { bufferToString } from "@fluidframework/common-utils";
7
7
  import {
8
- IChannelAttributes,
9
- IFluidDataStoreRuntime,
10
- IChannelStorageService,
11
- IChannelServices,
12
- IChannelFactory,
8
+ IChannelAttributes,
9
+ IFluidDataStoreRuntime,
10
+ IChannelStorageService,
11
+ IChannelServices,
12
+ IChannelFactory,
13
13
  } from "@fluidframework/datastore-definitions";
14
14
  import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
15
15
  import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
16
16
  import {
17
- createSingleBlobSummary,
18
- IFluidSerializer,
19
- SharedObject,
17
+ createSingleBlobSummary,
18
+ IFluidSerializer,
19
+ SharedObject,
20
20
  } from "@fluidframework/shared-object-base";
21
21
  import {
22
- Interval,
23
- IntervalCollection,
24
- IntervalCollectionValueType,
25
- ISerializableInterval,
22
+ Interval,
23
+ IntervalCollection,
24
+ IntervalCollectionValueType,
25
+ ISerializableInterval,
26
26
  } from "./intervalCollection";
27
27
  import { DefaultMap } from "./defaultMap";
28
28
  import { pkgVersion } from "./packageVersion";
@@ -35,137 +35,151 @@ const snapshotFileName = "header";
35
35
  * @deprecated `SharedIntervalCollection` is not maintained and is planned to be removed.
36
36
  */
37
37
  export class SharedIntervalCollectionFactory implements IChannelFactory {
38
- public static readonly Type = "https://graph.microsoft.com/types/sharedIntervalCollection";
39
-
40
- public static readonly Attributes: IChannelAttributes = {
41
- type: SharedIntervalCollectionFactory.Type,
42
- snapshotFormatVersion: "0.1",
43
- packageVersion: pkgVersion,
44
- };
45
-
46
- public get type() {
47
- return SharedIntervalCollectionFactory.Type;
48
- }
49
-
50
- public get attributes() {
51
- return SharedIntervalCollectionFactory.Attributes;
52
- }
53
-
54
- /**
55
- * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
56
- */
57
- public async load(
58
- runtime: IFluidDataStoreRuntime,
59
- id: string,
60
- services: IChannelServices,
61
- attributes: IChannelAttributes): Promise<SharedIntervalCollection> {
62
- const map = new SharedIntervalCollection(id, runtime, attributes);
63
- await map.load(services);
64
-
65
- return map;
66
- }
67
-
68
- public create(runtime: IFluidDataStoreRuntime, id: string): SharedIntervalCollection {
69
- const map = new SharedIntervalCollection(
70
- id,
71
- runtime,
72
- this.attributes);
73
- map.initializeLocal();
74
-
75
- return map;
76
- }
38
+ public static readonly Type = "https://graph.microsoft.com/types/sharedIntervalCollection";
39
+
40
+ public static readonly Attributes: IChannelAttributes = {
41
+ type: SharedIntervalCollectionFactory.Type,
42
+ snapshotFormatVersion: "0.1",
43
+ packageVersion: pkgVersion,
44
+ };
45
+
46
+ public get type() {
47
+ return SharedIntervalCollectionFactory.Type;
48
+ }
49
+
50
+ public get attributes() {
51
+ return SharedIntervalCollectionFactory.Attributes;
52
+ }
53
+
54
+ /**
55
+ * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
56
+ */
57
+ public async load(
58
+ runtime: IFluidDataStoreRuntime,
59
+ id: string,
60
+ services: IChannelServices,
61
+ attributes: IChannelAttributes,
62
+ ): Promise<SharedIntervalCollection> {
63
+ const map = new SharedIntervalCollection(id, runtime, attributes);
64
+ await map.load(services);
65
+
66
+ return map;
67
+ }
68
+
69
+ public create(runtime: IFluidDataStoreRuntime, id: string): SharedIntervalCollection {
70
+ const map = new SharedIntervalCollection(id, runtime, this.attributes);
71
+ map.initializeLocal();
72
+
73
+ return map;
74
+ }
77
75
  }
78
76
 
79
77
  export interface ISharedIntervalCollection<TInterval extends ISerializableInterval> {
80
- getIntervalCollection(label: string): IntervalCollection<TInterval>;
78
+ getIntervalCollection(label: string): IntervalCollection<TInterval>;
81
79
  }
82
80
 
83
81
  /**
84
82
  * @deprecated `SharedIntervalCollection` is not maintained and is planned to be removed.
85
83
  */
86
84
  export class SharedIntervalCollection
87
- extends SharedObject implements ISharedIntervalCollection<Interval> {
88
- /**
89
- * Create a SharedIntervalCollection
90
- *
91
- * @param runtime - data store runtime the new shared map belongs to
92
- * @param id - optional name of the shared map
93
- * @returns newly create shared map (but not attached yet)
94
- */
95
- public static create(runtime: IFluidDataStoreRuntime, id?: string) {
96
- return runtime.createChannel(id, SharedIntervalCollectionFactory.Type) as SharedIntervalCollection;
97
- }
98
-
99
- /**
100
- * Get a factory for SharedIntervalCollection to register with the data store.
101
- *
102
- * @returns a factory that creates and load SharedIntervalCollection
103
- */
104
- public static getFactory(): IChannelFactory {
105
- return new SharedIntervalCollectionFactory();
106
- }
107
-
108
- public readonly [Symbol.toStringTag]: string = "SharedIntervalCollection";
109
- private readonly intervalCollections: DefaultMap<IntervalCollection<Interval>>;
110
-
111
- /**
112
- * Constructs a new shared SharedIntervalCollection. If the object is non-local an id and service interfaces will
113
- * be provided
114
- */
115
- constructor(
116
- id: string,
117
- runtime: IFluidDataStoreRuntime,
118
- attributes: IChannelAttributes,
119
- ) {
120
- super(id, runtime, attributes, "fluid_sharedIntervalCollection_");
121
- this.intervalCollections = new DefaultMap(
122
- this.serializer,
123
- this.handle,
124
- (op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata),
125
- new IntervalCollectionValueType(),
126
- );
127
- }
128
-
129
- public getIntervalCollection(label: string): IntervalCollection<Interval> {
130
- const realLabel = this.getIntervalCollectionPath(label);
131
- const sharedCollection = this.intervalCollections.get(realLabel);
132
- return sharedCollection;
133
- }
134
-
135
- protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {
136
- return createSingleBlobSummary(snapshotFileName, this.intervalCollections.serialize(serializer));
137
- }
138
-
139
- protected reSubmitCore(content: any, localOpMetadata: unknown) {
140
- this.intervalCollections.tryResubmitMessage(content, localOpMetadata as IMapMessageLocalMetadata);
141
- }
142
-
143
- protected onDisconnect() { }
144
-
145
- /**
146
- * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
147
- */
148
- protected async loadCore(storage: IChannelStorageService) {
149
- const blob = await storage.readBlob(snapshotFileName);
150
- const header = bufferToString(blob, "utf8");
151
- this.intervalCollections.populate(header);
152
- }
153
-
154
- protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {
155
- if (message.type === MessageType.Operation) {
156
- this.intervalCollections.tryProcessMessage(message.contents, local, message, localOpMetadata);
157
- }
158
- }
159
-
160
- /**
161
- * Creates the full path of the intervalCollection label
162
- * @param label - the incoming label
163
- */
164
- protected getIntervalCollectionPath(label: string): string {
165
- return label;
166
- }
167
-
168
- protected applyStashedOp() {
169
- throw new Error("not implemented");
170
- }
85
+ extends SharedObject
86
+ implements ISharedIntervalCollection<Interval>
87
+ {
88
+ /**
89
+ * Create a SharedIntervalCollection
90
+ *
91
+ * @param runtime - data store runtime the new shared map belongs to
92
+ * @param id - optional name of the shared map
93
+ * @returns newly create shared map (but not attached yet)
94
+ */
95
+ public static create(runtime: IFluidDataStoreRuntime, id?: string) {
96
+ return runtime.createChannel(
97
+ id,
98
+ SharedIntervalCollectionFactory.Type,
99
+ ) as SharedIntervalCollection;
100
+ }
101
+
102
+ /**
103
+ * Get a factory for SharedIntervalCollection to register with the data store.
104
+ *
105
+ * @returns a factory that creates and load SharedIntervalCollection
106
+ */
107
+ public static getFactory(): IChannelFactory {
108
+ return new SharedIntervalCollectionFactory();
109
+ }
110
+
111
+ public readonly [Symbol.toStringTag]: string = "SharedIntervalCollection";
112
+ private readonly intervalCollections: DefaultMap<IntervalCollection<Interval>>;
113
+
114
+ /**
115
+ * Constructs a new shared SharedIntervalCollection. If the object is non-local an id and service interfaces will
116
+ * be provided
117
+ */
118
+ constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes) {
119
+ super(id, runtime, attributes, "fluid_sharedIntervalCollection_");
120
+ this.intervalCollections = new DefaultMap(
121
+ this.serializer,
122
+ this.handle,
123
+ (op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata),
124
+ new IntervalCollectionValueType(),
125
+ );
126
+ }
127
+
128
+ public getIntervalCollection(label: string): IntervalCollection<Interval> {
129
+ const realLabel = this.getIntervalCollectionPath(label);
130
+ const sharedCollection = this.intervalCollections.get(realLabel);
131
+ return sharedCollection;
132
+ }
133
+
134
+ protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {
135
+ return createSingleBlobSummary(
136
+ snapshotFileName,
137
+ this.intervalCollections.serialize(serializer),
138
+ );
139
+ }
140
+
141
+ protected reSubmitCore(content: any, localOpMetadata: unknown) {
142
+ this.intervalCollections.tryResubmitMessage(
143
+ content,
144
+ localOpMetadata as IMapMessageLocalMetadata,
145
+ );
146
+ }
147
+
148
+ protected onDisconnect() {}
149
+
150
+ /**
151
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
152
+ */
153
+ protected async loadCore(storage: IChannelStorageService) {
154
+ const blob = await storage.readBlob(snapshotFileName);
155
+ const header = bufferToString(blob, "utf8");
156
+ this.intervalCollections.populate(header);
157
+ }
158
+
159
+ protected processCore(
160
+ message: ISequencedDocumentMessage,
161
+ local: boolean,
162
+ localOpMetadata: unknown,
163
+ ) {
164
+ if (message.type === MessageType.Operation) {
165
+ this.intervalCollections.tryProcessMessage(
166
+ message.contents,
167
+ local,
168
+ message,
169
+ localOpMetadata,
170
+ );
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Creates the full path of the intervalCollection label
176
+ * @param label - the incoming label
177
+ */
178
+ protected getIntervalCollectionPath(label: string): string {
179
+ return label;
180
+ }
181
+
182
+ protected applyStashedOp() {
183
+ throw new Error("not implemented");
184
+ }
171
185
  }
@@ -4,176 +4,181 @@
4
4
  */
5
5
 
6
6
  import { assert } from "@fluidframework/common-utils";
7
+ import { BaseSegment, IJSONSegment, ISegment, PropertySet } from "@fluidframework/merge-tree";
7
8
  import {
8
- BaseSegment, IJSONSegment, ISegment, PropertySet,
9
- } from "@fluidframework/merge-tree";
10
- import { IChannelAttributes, IFluidDataStoreRuntime, Serializable } from "@fluidframework/datastore-definitions";
9
+ IChannelAttributes,
10
+ IFluidDataStoreRuntime,
11
+ Serializable,
12
+ } from "@fluidframework/datastore-definitions";
11
13
  import { SharedSegmentSequence } from "./sequence";
12
14
 
13
15
  const MaxRun = 128;
14
16
 
15
17
  export interface IJSONRunSegment<T> extends IJSONSegment {
16
- items: Serializable<T>[];
18
+ items: Serializable<T>[];
17
19
  }
18
20
 
19
21
  export class SubSequence<T> extends BaseSegment {
20
- public static readonly typeString: string = "SubSequence";
21
- public static is(segment: ISegment): segment is SubSequence<any> {
22
- return segment.type === SubSequence.typeString;
23
- }
24
- public static fromJSONObject<U>(spec: Serializable) {
25
- if (spec && typeof spec === "object" && "items" in spec) {
26
- const segment = new SubSequence<U>(spec.items);
27
- if (spec.props) {
28
- segment.addProperties(spec.props);
29
- }
30
- return segment;
31
- }
32
- return undefined;
33
- }
34
-
35
- public readonly type = SubSequence.typeString;
36
-
37
- constructor(public items: Serializable<T>[]) {
38
- super();
39
- this.cachedLength = items.length;
40
- }
41
-
42
- public toJSONObject() {
43
- const obj: IJSONRunSegment<T> = { items: this.items };
44
- super.addSerializedProps(obj);
45
- return obj;
46
- }
47
-
48
- public clone(start = 0, end?: number) {
49
- const clonedItems = this.items.slice(start, end);
50
- const b = new SubSequence(clonedItems);
51
- this.cloneInto(b);
52
- return b;
53
- }
54
-
55
- public canAppend(segment: ISegment): boolean {
56
- return SubSequence.is(segment)
57
- && (this.cachedLength <= MaxRun || segment.cachedLength <= MaxRun);
58
- }
59
-
60
- public toString() {
61
- return this.items.toString();
62
- }
63
-
64
- public append(segment: ISegment) {
65
- assert(SubSequence.is(segment), 0x448 /* can only append to another run segment */);
66
- super.append(segment);
67
- this.items = this.items.concat(segment.items);
68
- }
69
-
70
- // TODO: retain removed items for undo
71
- // returns true if entire run removed
72
- public removeRange(start: number, end: number) {
73
- let remnantItems: Serializable<T>[] = [];
74
- const len = this.items.length;
75
- if (start > 0) {
76
- remnantItems = remnantItems.concat(this.items.slice(0, start));
77
- }
78
- if (end < len) {
79
- remnantItems = remnantItems.concat(this.items.slice(end));
80
- }
81
- this.items = remnantItems;
82
- this.cachedLength = this.items.length;
83
- return (this.items.length === 0);
84
- }
85
-
86
- protected createSplitSegmentAt(pos: number) {
87
- if (pos > 0) {
88
- const remainingItems = this.items.slice(pos);
89
- this.items = this.items.slice(0, pos);
90
- this.cachedLength = this.items.length;
91
- const leafSegment = new SubSequence(remainingItems);
92
- return leafSegment;
93
- }
94
- }
22
+ public static readonly typeString: string = "SubSequence";
23
+ public static is(segment: ISegment): segment is SubSequence<any> {
24
+ return segment.type === SubSequence.typeString;
25
+ }
26
+ public static fromJSONObject<U>(spec: Serializable) {
27
+ if (spec && typeof spec === "object" && "items" in spec) {
28
+ const segment = new SubSequence<U>(spec.items);
29
+ if (spec.props) {
30
+ segment.addProperties(spec.props);
31
+ }
32
+ return segment;
33
+ }
34
+ return undefined;
35
+ }
36
+
37
+ public readonly type = SubSequence.typeString;
38
+
39
+ constructor(public items: Serializable<T>[]) {
40
+ super();
41
+ this.cachedLength = items.length;
42
+ }
43
+
44
+ public toJSONObject() {
45
+ const obj: IJSONRunSegment<T> = { items: this.items };
46
+ super.addSerializedProps(obj);
47
+ return obj;
48
+ }
49
+
50
+ public clone(start = 0, end?: number) {
51
+ const clonedItems = this.items.slice(start, end);
52
+ const b = new SubSequence(clonedItems);
53
+ this.cloneInto(b);
54
+ return b;
55
+ }
56
+
57
+ public canAppend(segment: ISegment): boolean {
58
+ return (
59
+ SubSequence.is(segment) &&
60
+ (this.cachedLength <= MaxRun || segment.cachedLength <= MaxRun)
61
+ );
62
+ }
63
+
64
+ public toString() {
65
+ return this.items.toString();
66
+ }
67
+
68
+ public append(segment: ISegment) {
69
+ assert(SubSequence.is(segment), 0x448 /* can only append to another run segment */);
70
+ super.append(segment);
71
+ this.items = this.items.concat(segment.items);
72
+ }
73
+
74
+ // TODO: retain removed items for undo
75
+ // returns true if entire run removed
76
+ public removeRange(start: number, end: number) {
77
+ let remnantItems: Serializable<T>[] = [];
78
+ const len = this.items.length;
79
+ if (start > 0) {
80
+ remnantItems = remnantItems.concat(this.items.slice(0, start));
81
+ }
82
+ if (end < len) {
83
+ remnantItems = remnantItems.concat(this.items.slice(end));
84
+ }
85
+ this.items = remnantItems;
86
+ this.cachedLength = this.items.length;
87
+ return this.items.length === 0;
88
+ }
89
+
90
+ protected createSplitSegmentAt(pos: number) {
91
+ if (pos > 0) {
92
+ const remainingItems = this.items.slice(pos);
93
+ this.items = this.items.slice(0, pos);
94
+ this.cachedLength = this.items.length;
95
+ const leafSegment = new SubSequence(remainingItems);
96
+ return leafSegment;
97
+ }
98
+ }
95
99
  }
96
100
 
97
101
  export class SharedSequence<T> extends SharedSegmentSequence<SubSequence<T>> {
98
- constructor(
99
- document: IFluidDataStoreRuntime,
100
- public id: string,
101
- attributes: IChannelAttributes,
102
- specToSegment: (spec: IJSONSegment) => ISegment,
103
- ) {
104
- super(document, id, attributes, specToSegment);
105
- }
106
-
107
- /**
108
- * @param pos - The position to insert the items at.
109
- * @param items - The items to insert.
110
- * @param props - Optional. Properties to set on the inserted items.
111
- */
112
- public insert(pos: number, items: Serializable<T>[], props?: PropertySet) {
113
- const segment = new SubSequence<T>(items);
114
- if (props) {
115
- segment.addProperties(props);
116
- }
117
- const insertOp = this.client.insertSegmentLocal(pos, segment);
118
- if (insertOp) {
119
- this.submitSequenceMessage(insertOp);
120
- }
121
- }
122
-
123
- /**
124
- * @param start - The inclusive start of the range to remove
125
- * @param end - The exclusive end of the range to remove
126
- */
127
- public remove(start: number, end: number) {
128
- this.removeRange(start, end);
129
- }
130
-
131
- /**
132
- * Returns the total count of items in the sequence
133
- */
134
- public getItemCount(): number {
135
- return this.getLength();
136
- }
137
-
138
- /**
139
- * Gets the items in the specified range
140
- *
141
- * @param start - The inclusive start of the range
142
- * @param end - The exclusive end of the range
143
- */
144
- public getItems(start: number, end?: number): Serializable<T>[] {
145
- const items: Serializable<T>[] = [];
146
- let firstSegment: ISegment | undefined;
147
-
148
- // Return if the range is incorrect.
149
- if (end !== undefined && end <= start) {
150
- return items;
151
- }
152
-
153
- this.walkSegments(
154
- (segment: ISegment) => {
155
- if (SubSequence.is(segment)) {
156
- if (firstSegment === undefined) {
157
- firstSegment = segment;
158
- }
159
- items.push(...segment.items);
160
- }
161
- return true;
162
- },
163
- start,
164
- end);
165
-
166
- // The above call to walkSegments adds all the items in the walked
167
- // segments. However, we only want items beginning at |start| in
168
- // the first segment. Similarly, if |end| is passed in, we only
169
- // want items until |end| in the last segment. Remove the rest of
170
- // the items.
171
- if (firstSegment !== undefined) {
172
- items.splice(0, start - this.getPosition(firstSegment));
173
- }
174
- if (end !== undefined) {
175
- items.splice(end - start);
176
- }
177
- return items;
178
- }
102
+ constructor(
103
+ document: IFluidDataStoreRuntime,
104
+ public id: string,
105
+ attributes: IChannelAttributes,
106
+ specToSegment: (spec: IJSONSegment) => ISegment,
107
+ ) {
108
+ super(document, id, attributes, specToSegment);
109
+ }
110
+
111
+ /**
112
+ * @param pos - The position to insert the items at.
113
+ * @param items - The items to insert.
114
+ * @param props - Optional. Properties to set on the inserted items.
115
+ */
116
+ public insert(pos: number, items: Serializable<T>[], props?: PropertySet) {
117
+ const segment = new SubSequence<T>(items);
118
+ if (props) {
119
+ segment.addProperties(props);
120
+ }
121
+ const insertOp = this.client.insertSegmentLocal(pos, segment);
122
+ if (insertOp) {
123
+ this.submitSequenceMessage(insertOp);
124
+ }
125
+ }
126
+
127
+ /**
128
+ * @param start - The inclusive start of the range to remove
129
+ * @param end - The exclusive end of the range to remove
130
+ */
131
+ public remove(start: number, end: number) {
132
+ this.removeRange(start, end);
133
+ }
134
+
135
+ /**
136
+ * Returns the total count of items in the sequence
137
+ */
138
+ public getItemCount(): number {
139
+ return this.getLength();
140
+ }
141
+
142
+ /**
143
+ * Gets the items in the specified range
144
+ *
145
+ * @param start - The inclusive start of the range
146
+ * @param end - The exclusive end of the range
147
+ */
148
+ public getItems(start: number, end?: number): Serializable<T>[] {
149
+ const items: Serializable<T>[] = [];
150
+ let firstSegment: ISegment | undefined;
151
+
152
+ // Return if the range is incorrect.
153
+ if (end !== undefined && end <= start) {
154
+ return items;
155
+ }
156
+
157
+ this.walkSegments(
158
+ (segment: ISegment) => {
159
+ if (SubSequence.is(segment)) {
160
+ if (firstSegment === undefined) {
161
+ firstSegment = segment;
162
+ }
163
+ items.push(...segment.items);
164
+ }
165
+ return true;
166
+ },
167
+ start,
168
+ end,
169
+ );
170
+
171
+ // The above call to walkSegments adds all the items in the walked
172
+ // segments. However, we only want items beginning at |start| in
173
+ // the first segment. Similarly, if |end| is passed in, we only
174
+ // want items until |end| in the last segment. Remove the rest of
175
+ // the items.
176
+ if (firstSegment !== undefined) {
177
+ items.splice(0, start - this.getPosition(firstSegment));
178
+ }
179
+ if (end !== undefined) {
180
+ items.splice(end - start);
181
+ }
182
+ return items;
183
+ }
179
184
  }