@fluidframework/merge-tree 0.54.3 → 0.55.2

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 (56) hide show
  1. package/dist/client.d.ts +5 -3
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +4 -6
  4. package/dist/client.js.map +1 -1
  5. package/dist/collections.d.ts.map +1 -1
  6. package/dist/collections.js +1 -0
  7. package/dist/collections.js.map +1 -1
  8. package/dist/partialLengths.d.ts.map +1 -1
  9. package/dist/partialLengths.js +4 -2
  10. package/dist/partialLengths.js.map +1 -1
  11. package/dist/snapshotChunks.d.ts +2 -1
  12. package/dist/snapshotChunks.d.ts.map +1 -1
  13. package/dist/snapshotChunks.js.map +1 -1
  14. package/dist/snapshotLoader.d.ts +1 -1
  15. package/dist/snapshotLoader.d.ts.map +1 -1
  16. package/dist/snapshotLoader.js.map +1 -1
  17. package/dist/snapshotV1.d.ts +6 -5
  18. package/dist/snapshotV1.d.ts.map +1 -1
  19. package/dist/snapshotV1.js +12 -28
  20. package/dist/snapshotV1.js.map +1 -1
  21. package/dist/snapshotlegacy.d.ts +7 -5
  22. package/dist/snapshotlegacy.d.ts.map +1 -1
  23. package/dist/snapshotlegacy.js +8 -35
  24. package/dist/snapshotlegacy.js.map +1 -1
  25. package/lib/client.d.ts +5 -3
  26. package/lib/client.d.ts.map +1 -1
  27. package/lib/client.js +4 -6
  28. package/lib/client.js.map +1 -1
  29. package/lib/collections.d.ts.map +1 -1
  30. package/lib/collections.js +1 -0
  31. package/lib/collections.js.map +1 -1
  32. package/lib/partialLengths.d.ts.map +1 -1
  33. package/lib/partialLengths.js +4 -2
  34. package/lib/partialLengths.js.map +1 -1
  35. package/lib/snapshotChunks.d.ts +2 -1
  36. package/lib/snapshotChunks.d.ts.map +1 -1
  37. package/lib/snapshotChunks.js.map +1 -1
  38. package/lib/snapshotLoader.d.ts +1 -1
  39. package/lib/snapshotLoader.d.ts.map +1 -1
  40. package/lib/snapshotLoader.js.map +1 -1
  41. package/lib/snapshotV1.d.ts +6 -5
  42. package/lib/snapshotV1.d.ts.map +1 -1
  43. package/lib/snapshotV1.js +12 -28
  44. package/lib/snapshotV1.js.map +1 -1
  45. package/lib/snapshotlegacy.d.ts +7 -5
  46. package/lib/snapshotlegacy.d.ts.map +1 -1
  47. package/lib/snapshotlegacy.js +8 -35
  48. package/lib/snapshotlegacy.js.map +1 -1
  49. package/package.json +18 -14
  50. package/src/client.ts +9 -9
  51. package/src/collections.ts +1 -0
  52. package/src/partialLengths.ts +4 -2
  53. package/src/snapshotChunks.ts +2 -4
  54. package/src/snapshotLoader.ts +1 -1
  55. package/src/snapshotV1.ts +28 -50
  56. package/src/snapshotlegacy.ts +27 -52
package/src/client.ts CHANGED
@@ -5,9 +5,11 @@
5
5
 
6
6
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
7
7
 
8
- import { IFluidHandle, IFluidSerializer } from "@fluidframework/core-interfaces";
9
- import { ISequencedDocumentMessage, ITree, MessageType } from "@fluidframework/protocol-definitions";
8
+ import { IFluidHandle } from "@fluidframework/core-interfaces";
9
+ import { IFluidSerializer } from "@fluidframework/shared-object-base";
10
+ import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
10
11
  import { IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
12
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
11
13
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
12
14
  import { assert, Trace } from "@fluidframework/common-utils";
13
15
  import { LoggingError } from "@fluidframework/telemetry-utils";
@@ -873,29 +875,27 @@ export class Client {
873
875
  return new MergeTreeTextHelper(this.mergeTree);
874
876
  }
875
877
 
876
- // TODO: Remove `catchUpMsgs` once new snapshot format is adopted as default.
877
- // (See https://github.com/microsoft/FluidFramework/issues/84)
878
- public snapshot(
878
+ public summarize(
879
879
  runtime: IFluidDataStoreRuntime,
880
880
  handle: IFluidHandle,
881
881
  serializer: IFluidSerializer,
882
882
  catchUpMsgs: ISequencedDocumentMessage[],
883
- ): ITree {
883
+ ): ISummaryTreeWithStats {
884
884
  const deltaManager = runtime.deltaManager;
885
885
  const minSeq = deltaManager.minimumSequenceNumber;
886
886
 
887
887
  // Catch up to latest MSN, if we have not had a chance to do it.
888
888
  // Required for case where FluidDataStoreRuntime.attachChannel()
889
- // generates snapshot right after loading data store.
889
+ // generates summary right after loading data store.
890
890
 
891
891
  this.updateSeqNumbers(minSeq, deltaManager.lastSequenceNumber);
892
892
 
893
- // One of the snapshots (from SPO) I observed to have chunk.chunkSequenceNumber > minSeq!
893
+ // One of the summaries (from SPO) I observed to have chunk.chunkSequenceNumber > minSeq!
894
894
  // Not sure why - need to catch it sooner
895
895
  assert(this.getCollabWindow().minSeq === minSeq,
896
896
  0x03e /* "minSeq mismatch between collab window and delta manager!" */);
897
897
 
898
- // TODO: Remove options flag once new snapshot format is adopted as default.
898
+ // Must continue to support legacy
899
899
  // (See https://github.com/microsoft/FluidFramework/issues/84)
900
900
  if (this.mergeTree.options?.newMergeTreeSnapshotFormat === true) {
901
901
  assert(
@@ -61,6 +61,7 @@ export class List<T> {
61
61
  public next: List<T>;
62
62
  public prev: List<T>;
63
63
 
64
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly
64
65
  constructor(public isHead: boolean, private data: T | undefined) {
65
66
  this.prev = this;
66
67
  this.next = this;
@@ -177,7 +177,8 @@ export class PartialSequenceLengths {
177
177
  // Find next earliest sequence number
178
178
  if (indices[k] < childPartialsCounts[k]) {
179
179
  const cpLen = childPartials[k].partialLengths[indices[k]];
180
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
180
+ // eslint-disable-next-line max-len
181
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-type-assertion
181
182
  if ((outerIndexOfEarliest < 0) || (cpLen.seq < earliestPartialLength!.seq)) {
182
183
  outerIndexOfEarliest = k;
183
184
  earliestPartialLength = cpLen;
@@ -185,7 +186,8 @@ export class PartialSequenceLengths {
185
186
  }
186
187
  }
187
188
  if (outerIndexOfEarliest >= 0) {
188
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
189
+ // eslint-disable-next-line max-len
190
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-type-assertion
189
191
  addNext(earliestPartialLength!);
190
192
  indices[outerIndexOfEarliest]++;
191
193
  }
@@ -5,10 +5,8 @@
5
5
 
6
6
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
7
7
 
8
- import {
9
- IFluidSerializer,
10
- IFluidHandle,
11
- } from "@fluidframework/core-interfaces";
8
+ import { IFluidHandle } from "@fluidframework/core-interfaces";
9
+ import { IFluidSerializer } from "@fluidframework/shared-object-base";
12
10
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
13
11
  import { PropertySet } from "./properties";
14
12
  import { SnapshotLegacy } from "./snapshotlegacy";
@@ -6,7 +6,7 @@
6
6
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
7
7
 
8
8
  import { assert, bufferToString } from "@fluidframework/common-utils";
9
- import { IFluidSerializer } from "@fluidframework/core-interfaces";
9
+ import { IFluidSerializer } from "@fluidframework/shared-object-base";
10
10
  import { ChildLogger } from "@fluidframework/telemetry-utils";
11
11
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
12
12
  import { IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
package/src/snapshotV1.ts CHANGED
@@ -4,19 +4,13 @@
4
4
  */
5
5
 
6
6
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
7
- import {
8
- IFluidHandle,
9
- IFluidSerializer,
10
- } from "@fluidframework/core-interfaces";
7
+ import { IFluidHandle } from "@fluidframework/core-interfaces";
8
+ import { IFluidSerializer } from "@fluidframework/shared-object-base";
11
9
  import { assert, bufferToString } from "@fluidframework/common-utils";
12
10
  import { ChildLogger } from "@fluidframework/telemetry-utils";
13
- import {
14
- FileMode,
15
- ITree,
16
- TreeEntry,
17
- ITreeEntry,
18
- } from "@fluidframework/protocol-definitions";
19
11
  import { IChannelStorageService } from "@fluidframework/datastore-definitions";
12
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
13
+ import { SummaryTreeBuilder } from "@fluidframework/runtime-utils";
20
14
  import { UnassignedSequenceNumber } from "./constants";
21
15
  import {
22
16
  ISegment,
@@ -98,13 +92,13 @@ export class SnapshotV1 {
98
92
  }
99
93
 
100
94
  /**
101
- * Emits the snapshot to an ITree. If provided the optional IFluidSerializer will be used when serializing
102
- * the summary data rather than JSON.stringify.
95
+ * Emits the snapshot to an ISummarizeResult. If provided the optional IFluidSerializer will be used when
96
+ * serializing the summary data rather than JSON.stringify.
103
97
  */
104
98
  emit(
105
99
  serializer: IFluidSerializer,
106
100
  bind: IFluidHandle,
107
- ): ITree {
101
+ ): ISummaryTreeWithStats {
108
102
  const chunks: MergeTreeChunkV1[] = [];
109
103
  this.header.totalSegmentCount = 0;
110
104
  this.header.totalLength = 0;
@@ -124,48 +118,32 @@ export class SnapshotV1 {
124
118
  const headerChunk = chunks.shift()!;
125
119
  headerChunk.headerMetadata = this.header;
126
120
  headerChunk.headerMetadata.orderedChunkMetadata = [{ id: SnapshotLegacy.header }];
127
- const entries: ITreeEntry[] = chunks.map<ITreeEntry>((chunk, index) => {
121
+ const blobs: [key: string, content: string][] = [];
122
+ chunks.forEach((chunk, index) => {
128
123
  const id = `${SnapshotLegacy.body}_${index}`;
129
124
  this.header.orderedChunkMetadata.push({ id });
130
- return {
131
- mode: FileMode.File,
132
- path: id,
133
- type: TreeEntry.Blob,
134
- value: {
135
- contents: serializeAsMaxSupportedVersion(
136
- id,
137
- chunk,
138
- this.logger,
139
- this.mergeTree.options,
140
- serializer,
141
- bind),
142
- encoding: "utf-8",
143
- },
144
- };
125
+ blobs.push([id, serializeAsMaxSupportedVersion(
126
+ id,
127
+ chunk,
128
+ this.logger,
129
+ this.mergeTree.options,
130
+ serializer,
131
+ bind)]);
145
132
  });
146
133
 
147
- const tree: ITree = {
148
- entries: [
149
- {
150
- mode: FileMode.File,
151
- path: SnapshotLegacy.header,
152
- type: TreeEntry.Blob,
153
- value: {
154
- contents: serializeAsMaxSupportedVersion(
155
- SnapshotLegacy.header,
156
- headerChunk,
157
- this.logger,
158
- this.mergeTree.options,
159
- serializer,
160
- bind),
161
- encoding: "utf-8",
162
- },
163
- },
164
- ...entries,
165
- ],
166
- };
134
+ const builder = new SummaryTreeBuilder();
135
+ builder.addBlob(SnapshotLegacy.header, serializeAsMaxSupportedVersion(
136
+ SnapshotLegacy.header,
137
+ headerChunk,
138
+ this.logger,
139
+ this.mergeTree.options,
140
+ serializer,
141
+ bind));
142
+ blobs.forEach((value) => {
143
+ builder.addBlob(value[0], value[1]);
144
+ });
167
145
 
168
- return tree;
146
+ return builder.getSummaryTree();
169
147
  }
170
148
 
171
149
  extractSync() {
@@ -7,12 +7,12 @@
7
7
 
8
8
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
9
9
  import { assert } from "@fluidframework/common-utils";
10
- import {
11
- IFluidHandle,
12
- IFluidSerializer,
13
- } from "@fluidframework/core-interfaces";
10
+ import { IFluidHandle } from "@fluidframework/core-interfaces";
11
+ import { IFluidSerializer } from "@fluidframework/shared-object-base";
12
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
14
13
  import { ChildLogger } from "@fluidframework/telemetry-utils";
15
- import { FileMode, ISequencedDocumentMessage, ITree, TreeEntry } from "@fluidframework/protocol-definitions";
14
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
15
+ import { SummaryTreeBuilder } from "@fluidframework/runtime-utils";
16
16
  import { NonCollabClient, UnassignedSequenceNumber } from "./constants";
17
17
  import {
18
18
  ISegment,
@@ -89,57 +89,38 @@ export class SnapshotLegacy {
89
89
  }
90
90
 
91
91
  /**
92
- * Emits the snapshot to an ITree. If provided the optional IFluidSerializer will be used when serializing
93
- * the summary data rather than JSON.stringify.
92
+ * Emits the snapshot to an ISummarizeResult. If provided the optional IFluidSerializer will be used when
93
+ * serializing the summary data rather than JSON.stringify.
94
94
  */
95
95
  emit(
96
96
  catchUpMsgs: ISequencedDocumentMessage[],
97
97
  serializer: IFluidSerializer,
98
98
  bind: IFluidHandle,
99
- ): ITree {
99
+ ): ISummaryTreeWithStats {
100
100
  const chunk1 = this.getSeqLengthSegs(this.segments!, this.segmentLengths!, this.chunkSize);
101
101
  let length: number = chunk1.chunkLengthChars;
102
102
  let segments: number = chunk1.chunkSegmentCount;
103
- const tree: ITree = {
104
- entries: [
105
- {
106
- mode: FileMode.File,
107
- path: SnapshotLegacy.header,
108
- type: TreeEntry.Blob,
109
- value: {
110
- contents: serializeAsMinSupportedVersion(
111
- SnapshotLegacy.header,
112
- chunk1,
113
- this.logger,
114
- this.mergeTree.options,
115
- serializer,
116
- bind),
117
- encoding: "utf-8",
118
- },
119
- },
120
- ],
121
- };
103
+ const builder = new SummaryTreeBuilder();
104
+ builder.addBlob(SnapshotLegacy.header, serializeAsMinSupportedVersion(
105
+ SnapshotLegacy.header,
106
+ chunk1,
107
+ this.logger,
108
+ this.mergeTree.options,
109
+ serializer,
110
+ bind));
122
111
 
123
112
  if (chunk1.chunkSegmentCount < chunk1.totalSegmentCount!) {
124
113
  const chunk2 = this.getSeqLengthSegs(this.segments!, this.segmentLengths!,
125
114
  this.header!.segmentsTotalLength, chunk1.chunkSegmentCount);
126
115
  length += chunk2.chunkLengthChars;
127
116
  segments += chunk2.chunkSegmentCount;
128
- tree.entries.push({
129
- mode: FileMode.File,
130
- path: SnapshotLegacy.body,
131
- type: TreeEntry.Blob,
132
- value: {
133
- contents: serializeAsMinSupportedVersion(
134
- SnapshotLegacy.body,
135
- chunk2,
136
- this.logger,
137
- this.mergeTree.options,
138
- serializer,
139
- bind),
140
- encoding: "utf-8",
141
- },
142
- });
117
+ builder.addBlob(SnapshotLegacy.body, serializeAsMinSupportedVersion(
118
+ SnapshotLegacy.body,
119
+ chunk2,
120
+ this.logger,
121
+ this.mergeTree.options,
122
+ serializer,
123
+ bind));
143
124
  }
144
125
 
145
126
  assert(
@@ -151,18 +132,12 @@ export class SnapshotLegacy {
151
132
  0x05e /* "emit: mismatch in totalSegmentCount" */);
152
133
 
153
134
  if(catchUpMsgs !== undefined && catchUpMsgs.length > 0) {
154
- tree.entries.push({
155
- mode: FileMode.File,
156
- path: this.mergeTree.options?.catchUpBlobName ?? SnapshotLegacy.catchupOps,
157
- type: TreeEntry.Blob,
158
- value: {
159
- contents: serializer ? serializer.stringify(catchUpMsgs, bind) : JSON.stringify(catchUpMsgs),
160
- encoding: "utf-8",
161
- },
162
- });
135
+ builder.addBlob(
136
+ this.mergeTree.options?.catchUpBlobName ?? SnapshotLegacy.catchupOps,
137
+ serializer ? serializer.stringify(catchUpMsgs, bind) : JSON.stringify(catchUpMsgs));
163
138
  }
164
139
 
165
- return tree;
140
+ return builder.getSummaryTree();
166
141
  }
167
142
 
168
143
  extractSync() {