@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.
- package/.eslintrc.js +9 -12
- package/.mocharc.js +2 -2
- package/.vscode/launch.json +15 -14
- package/README.md +188 -179
- package/api-extractor.json +2 -2
- package/dist/defaultMap.d.ts.map +1 -1
- package/dist/defaultMap.js +5 -4
- package/dist/defaultMap.js.map +1 -1
- package/dist/defaultMapInterfaces.d.ts.map +1 -1
- package/dist/defaultMapInterfaces.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +50 -36
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalTree.d.ts.map +1 -1
- package/dist/intervalTree.js.map +1 -1
- package/dist/localValues.d.ts.map +1 -1
- package/dist/localValues.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 +1 -1
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +13 -17
- package/dist/sequence.js.map +1 -1
- package/dist/sequenceDeltaEvent.d.ts.map +1 -1
- package/dist/sequenceDeltaEvent.js.map +1 -1
- package/dist/sequenceFactory.d.ts.map +1 -1
- package/dist/sequenceFactory.js.map +1 -1
- package/dist/sharedIntervalCollection.d.ts.map +1 -1
- package/dist/sharedIntervalCollection.js.map +1 -1
- package/dist/sharedSequence.d.ts.map +1 -1
- package/dist/sharedSequence.js +3 -3
- package/dist/sharedSequence.js.map +1 -1
- package/dist/sharedString.d.ts.map +1 -1
- package/dist/sharedString.js +5 -4
- package/dist/sharedString.js.map +1 -1
- package/lib/defaultMap.d.ts.map +1 -1
- package/lib/defaultMap.js +6 -5
- package/lib/defaultMap.js.map +1 -1
- package/lib/defaultMapInterfaces.d.ts.map +1 -1
- package/lib/defaultMapInterfaces.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +50 -36
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalTree.d.ts.map +1 -1
- package/lib/intervalTree.js.map +1 -1
- package/lib/localValues.d.ts.map +1 -1
- package/lib/localValues.js +1 -1
- package/lib/localValues.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 +1 -1
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +15 -19
- package/lib/sequence.js.map +1 -1
- package/lib/sequenceDeltaEvent.d.ts.map +1 -1
- package/lib/sequenceDeltaEvent.js.map +1 -1
- package/lib/sequenceFactory.d.ts.map +1 -1
- package/lib/sequenceFactory.js +1 -1
- package/lib/sequenceFactory.js.map +1 -1
- package/lib/sharedIntervalCollection.d.ts.map +1 -1
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/lib/sharedSequence.d.ts.map +1 -1
- package/lib/sharedSequence.js +4 -4
- package/lib/sharedSequence.js.map +1 -1
- package/lib/sharedString.d.ts.map +1 -1
- package/lib/sharedString.js +5 -4
- package/lib/sharedString.js.map +1 -1
- package/package.json +55 -55
- package/prettier.config.cjs +1 -1
- package/src/defaultMap.ts +406 -405
- package/src/defaultMapInterfaces.ts +120 -115
- package/src/index.ts +27 -17
- package/src/intervalCollection.ts +2198 -1997
- package/src/intervalTree.ts +139 -139
- package/src/localValues.ts +64 -73
- package/src/packageVersion.ts +1 -1
- package/src/sequence.ts +739 -694
- package/src/sequenceDeltaEvent.ts +143 -137
- package/src/sequenceFactory.ts +48 -46
- package/src/sharedIntervalCollection.ts +150 -136
- package/src/sharedSequence.ts +165 -160
- package/src/sharedString.ts +385 -343
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +8 -12
- package/.editorconfig +0 -7
|
@@ -5,24 +5,24 @@
|
|
|
5
5
|
|
|
6
6
|
import { bufferToString } from "@fluidframework/common-utils";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
createSingleBlobSummary,
|
|
18
|
+
IFluidSerializer,
|
|
19
|
+
SharedObject,
|
|
20
20
|
} from "@fluidframework/shared-object-base";
|
|
21
21
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
}
|
package/src/sharedSequence.ts
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
18
|
+
items: Serializable<T>[];
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export class SubSequence<T> extends BaseSegment {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
}
|