@fluidframework/sequence 2.0.0-dev-rc.4.0.0.261659 → 2.0.0-dev-rc.5.0.0.263932

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/sequence",
3
- "version": "2.0.0-dev-rc.4.0.0.261659",
3
+ "version": "2.0.0-dev-rc.5.0.0.263932",
4
4
  "description": "Distributed sequence",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -87,34 +87,34 @@
87
87
  "temp-directory": "nyc/.nyc_output"
88
88
  },
89
89
  "dependencies": {
90
- "@fluid-internal/client-utils": "2.0.0-dev-rc.4.0.0.261659",
91
- "@fluidframework/core-interfaces": "2.0.0-dev-rc.4.0.0.261659",
92
- "@fluidframework/core-utils": "2.0.0-dev-rc.4.0.0.261659",
93
- "@fluidframework/datastore-definitions": "2.0.0-dev-rc.4.0.0.261659",
94
- "@fluidframework/merge-tree": "2.0.0-dev-rc.4.0.0.261659",
90
+ "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.263932",
91
+ "@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.263932",
92
+ "@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.263932",
93
+ "@fluidframework/datastore-definitions": "2.0.0-dev-rc.5.0.0.263932",
94
+ "@fluidframework/merge-tree": "2.0.0-dev-rc.5.0.0.263932",
95
95
  "@fluidframework/protocol-definitions": "^3.2.0",
96
- "@fluidframework/runtime-definitions": "2.0.0-dev-rc.4.0.0.261659",
97
- "@fluidframework/runtime-utils": "2.0.0-dev-rc.4.0.0.261659",
98
- "@fluidframework/shared-object-base": "2.0.0-dev-rc.4.0.0.261659",
99
- "@fluidframework/telemetry-utils": "2.0.0-dev-rc.4.0.0.261659",
96
+ "@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.263932",
97
+ "@fluidframework/runtime-utils": "2.0.0-dev-rc.5.0.0.263932",
98
+ "@fluidframework/shared-object-base": "2.0.0-dev-rc.5.0.0.263932",
99
+ "@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.263932",
100
100
  "double-ended-queue": "^2.1.0-0",
101
101
  "uuid": "^9.0.0"
102
102
  },
103
103
  "devDependencies": {
104
104
  "@arethetypeswrong/cli": "^0.15.2",
105
105
  "@biomejs/biome": "^1.6.2",
106
- "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.4.0.0.261659",
107
- "@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.4.0.0.261659",
108
- "@fluid-private/test-dds-utils": "2.0.0-dev-rc.4.0.0.261659",
106
+ "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.263932",
107
+ "@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.5.0.0.263932",
108
+ "@fluid-private/test-dds-utils": "2.0.0-dev-rc.5.0.0.263932",
109
109
  "@fluid-tools/benchmark": "^0.48.0",
110
- "@fluid-tools/build-cli": "0.38.0-259537",
110
+ "@fluid-tools/build-cli": "^0.38.0",
111
111
  "@fluidframework/build-common": "^2.0.3",
112
- "@fluidframework/build-tools": "0.38.0-259537",
113
- "@fluidframework/container-definitions": "2.0.0-dev-rc.4.0.0.261659",
112
+ "@fluidframework/build-tools": "^0.38.0",
113
+ "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.263932",
114
114
  "@fluidframework/eslint-config-fluid": "^5.1.0",
115
115
  "@fluidframework/sequence-previous": "npm:@fluidframework/sequence@2.0.0-rc.3.0.0",
116
- "@fluidframework/test-runtime-utils": "2.0.0-dev-rc.4.0.0.261659",
117
- "@microsoft/api-extractor": "^7.42.3",
116
+ "@fluidframework/test-runtime-utils": "2.0.0-dev-rc.5.0.0.263932",
117
+ "@microsoft/api-extractor": "^7.43.1",
118
118
  "@types/diff": "^3.5.1",
119
119
  "@types/double-ended-queue": "^2.1.0",
120
120
  "@types/mocha": "^9.1.1",
@@ -146,11 +146,21 @@
146
146
  "typeValidation": {
147
147
  "broken": {
148
148
  "RemovedClassDeclaration_SharedString": {
149
- "backCompat": false
149
+ "backCompat": false,
150
+ "forwardCompat": false
150
151
  },
151
152
  "InterfaceDeclaration_ISharedString": {
152
153
  "forwardCompat": false
153
154
  },
155
+ "ClassDeclaration_SharedIntervalCollection": {
156
+ "forwardCompat": false
157
+ },
158
+ "ClassDeclaration_SharedSegmentSequence": {
159
+ "forwardCompat": false
160
+ },
161
+ "ClassDeclaration_SharedSequence": {
162
+ "forwardCompat": false
163
+ },
154
164
  "RemovedClassDeclaration_SharedStringFactory": {
155
165
  "backCompat": false,
156
166
  "forwardCompat": false
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/sequence";
9
- export const pkgVersion = "2.0.0-dev-rc.4.0.0.261659";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.263932";
package/src/sequence.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { bufferToString } from "@fluid-internal/client-utils";
7
7
  import { IEventThisPlaceHolder } from "@fluidframework/core-interfaces";
8
- import { assert, Deferred } from "@fluidframework/core-utils/internal";
8
+ import { assert } from "@fluidframework/core-utils/internal";
9
9
  import {
10
10
  IChannelAttributes,
11
11
  IChannelStorageService,
@@ -117,8 +117,13 @@ export abstract class SharedSegmentSequence<T extends ISegment>
117
117
  extends SharedObject<ISharedSegmentSequenceEvents>
118
118
  implements ISharedIntervalCollection<SequenceInterval>, MergeTreeRevertibleDriver
119
119
  {
120
+ /**
121
+ * This promise is always immediately resolved, and awaiting it has no effect.
122
+ * @deprecated SharedSegmentSequence no longer supports partial loading.
123
+ * References to this promise may safely be deleted without affecting behavior.
124
+ */
120
125
  get loaded(): Promise<void> {
121
- return this.loadedDeferred.promise;
126
+ return Promise.resolve();
122
127
  }
123
128
 
124
129
  /**
@@ -240,25 +245,15 @@ export abstract class SharedSegmentSequence<T extends ISegment>
240
245
  * DDS submits over the wire. See `inFlightRefSeqs` for more details.
241
246
  */
242
247
  private get currentRefSeq() {
243
- return this.ongoingResubmitRefSeq ?? this.runtime.deltaManager.lastSequenceNumber;
248
+ return this.ongoingResubmitRefSeq ?? this.deltaManager.lastSequenceNumber;
244
249
  }
245
250
 
246
251
  // eslint-disable-next-line import/no-deprecated
247
252
  protected client: Client;
248
- /** `Deferred` that triggers once the object is loaded */
249
- protected loadedDeferred = new Deferred<void>();
250
- // cache out going ops created when partial loading
251
- // eslint-disable-next-line import/no-deprecated
252
- private readonly loadedDeferredOutgoingOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] =
253
- [];
254
- // cache incoming ops that arrive when partial loading
255
- private deferIncomingOps = true;
256
- private readonly loadedDeferredIncomingOps: ISequencedDocumentMessage[] = [];
257
-
258
253
  private messagesSinceMSNChange: ISequencedDocumentMessage[] = [];
259
254
  private readonly intervalCollections: IntervalCollectionMap<SequenceInterval>;
260
255
  constructor(
261
- private readonly dataStoreRuntime: IFluidDataStoreRuntime,
256
+ dataStoreRuntime: IFluidDataStoreRuntime,
262
257
  public id: string,
263
258
  attributes: IChannelAttributes,
264
259
  public readonly segmentFromSpec: (spec: IJSONSegment) => ISegment,
@@ -279,10 +274,6 @@ export abstract class SharedSegmentSequence<T extends ISegment>
279
274
  }
280
275
  });
281
276
 
282
- this.loadedDeferred.promise.catch((error) => {
283
- this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
284
- });
285
-
286
277
  // eslint-disable-next-line import/no-deprecated
287
278
  this.client = new Client(
288
279
  segmentFromSpec,
@@ -481,14 +472,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
481
472
  message.type === MergeTreeDeltaType.GROUP ? message.ops.length : 1,
482
473
  );
483
474
 
484
- // if loading isn't complete, we need to cache
485
- // local ops until loading is complete, and then
486
- // they will be present
487
- if (!this.loadedDeferred.isCompleted) {
488
- this.loadedDeferredOutgoingOps.push(metadata ? [message, metadata] : (message as any));
489
- } else {
490
- this.submitLocalMessage(message, metadata);
491
- }
475
+ this.submitLocalMessage(message, metadata);
492
476
  }
493
477
 
494
478
  /**
@@ -689,47 +673,38 @@ export abstract class SharedSegmentSequence<T extends ISegment>
689
673
  this.serializer,
690
674
  );
691
675
 
692
- // setup a promise to process the
693
- // catch up ops, and finishing the loading process
694
- const loadCatchUpOps = catchupOpsP
695
- .then((msgs) => {
696
- msgs.forEach((m) => {
697
- const collabWindow = this.client.getCollabWindow();
698
- if (
699
- m.minimumSequenceNumber < collabWindow.minSeq ||
700
- m.referenceSequenceNumber < collabWindow.minSeq ||
701
- m.sequenceNumber <= collabWindow.minSeq ||
702
- // sequenceNumber could be the same if messages are part of a grouped batch
703
- m.sequenceNumber < collabWindow.currentSeq
704
- ) {
705
- throw new Error(
706
- `Invalid catchup operations in snapshot: ${JSON.stringify({
707
- op: {
708
- seq: m.sequenceNumber,
709
- minSeq: m.minimumSequenceNumber,
710
- refSeq: m.referenceSequenceNumber,
711
- },
712
- collabWindow: {
713
- seq: collabWindow.currentSeq,
714
- minSeq: collabWindow.minSeq,
715
- },
716
- })}`,
717
- );
718
- }
719
- this.processMergeTreeMsg(m);
720
- });
721
- this.loadFinished();
722
- })
723
- .catch((error) => {
724
- this.loadFinished(error);
725
- });
726
- if (this.dataStoreRuntime.options.sequenceInitializeFromHeaderOnly !== true) {
727
- // if we not doing partial load, await the catch up ops,
728
- // and the finalization of the load
729
- await loadCatchUpOps;
730
- }
676
+ // process the catch up ops, and finishing the loading process
677
+ (await catchupOpsP).forEach((m) => {
678
+ const collabWindow = this.client.getCollabWindow();
679
+ if (
680
+ m.minimumSequenceNumber < collabWindow.minSeq ||
681
+ m.referenceSequenceNumber < collabWindow.minSeq ||
682
+ m.sequenceNumber <= collabWindow.minSeq ||
683
+ // sequenceNumber could be the same if messages are part of a grouped batch
684
+ m.sequenceNumber < collabWindow.currentSeq
685
+ ) {
686
+ throw new Error(
687
+ `Invalid catchup operations in snapshot: ${JSON.stringify({
688
+ op: {
689
+ seq: m.sequenceNumber,
690
+ minSeq: m.minimumSequenceNumber,
691
+ refSeq: m.referenceSequenceNumber,
692
+ },
693
+ collabWindow: {
694
+ seq: collabWindow.currentSeq,
695
+ minSeq: collabWindow.minSeq,
696
+ },
697
+ })}`,
698
+ );
699
+ }
700
+ this.processMergeTreeMsg(m);
701
+ });
702
+
703
+ // Initialize the interval collections
704
+ this.initializeIntervalCollections();
731
705
  } catch (error) {
732
- this.loadFinished(error);
706
+ this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
707
+ throw error;
733
708
  }
734
709
  }
735
710
 
@@ -753,27 +728,20 @@ export abstract class SharedSegmentSequence<T extends ISegment>
753
728
  // assert(recordedRefSeq <= message.referenceSequenceNumber, "RefSeq mismatch");
754
729
  }
755
730
 
756
- // if loading isn't complete, we need to cache all
757
- // incoming ops to be applied after loading is complete
758
- if (this.deferIncomingOps) {
759
- assert(!local, 0x072 /* "Unexpected local op when loading not finished" */);
760
- this.loadedDeferredIncomingOps.push(message);
761
- } else {
762
- assert(
763
- message.type === MessageType.Operation,
764
- 0x073 /* "Sequence message not operation" */,
765
- );
731
+ assert(
732
+ message.type === MessageType.Operation,
733
+ 0x073 /* "Sequence message not operation" */,
734
+ );
766
735
 
767
- const handled = this.intervalCollections.tryProcessMessage(
768
- message.contents as IMapOperation,
769
- local,
770
- message,
771
- localOpMetadata,
772
- );
736
+ const handled = this.intervalCollections.tryProcessMessage(
737
+ message.contents as IMapOperation,
738
+ local,
739
+ message,
740
+ localOpMetadata,
741
+ );
773
742
 
774
- if (!handled) {
775
- this.processMergeTreeMsg(message, local);
776
- }
743
+ if (!handled) {
744
+ this.processMergeTreeMsg(message, local);
777
745
  }
778
746
  }
779
747
 
@@ -793,7 +761,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
793
761
  */
794
762
  protected initializeLocalCore() {
795
763
  super.initializeLocalCore();
796
- this.loadFinished();
764
+ this.initializeIntervalCollections();
797
765
  }
798
766
 
799
767
  /**
@@ -806,12 +774,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
806
774
  }
807
775
 
808
776
  private summarizeMergeTree(serializer: IFluidSerializer): ISummaryTreeWithStats {
809
- // Are we fully loaded? If not, things will go south
810
- assert(
811
- this.loadedDeferred.isCompleted,
812
- 0x074 /* "Snapshot called when not fully loaded" */,
813
- );
814
- const minSeq = this.runtime.deltaManager.minimumSequenceNumber;
777
+ const minSeq = this.deltaManager.minimumSequenceNumber;
815
778
 
816
779
  this.processMinSequenceNumberChanged(minSeq);
817
780
 
@@ -883,35 +846,6 @@ export abstract class SharedSegmentSequence<T extends ISegment>
883
846
  }
884
847
  }
885
848
 
886
- private loadFinished(error?: any) {
887
- if (!this.loadedDeferred.isCompleted) {
888
- // Initialize the interval collections
889
- this.initializeIntervalCollections();
890
- if (error) {
891
- this.loadedDeferred.reject(error);
892
- throw error;
893
- } else {
894
- // it is important this series remains synchronous
895
- // first we stop deferring incoming ops, and apply then all
896
- this.deferIncomingOps = false;
897
- for (const message of this.loadedDeferredIncomingOps) {
898
- this.processCore(message, false, undefined);
899
- }
900
- this.loadedDeferredIncomingOps.length = 0;
901
-
902
- // then resolve the loaded promise
903
- // and resubmit all the outstanding ops, as the snapshot
904
- // is fully loaded, and all outstanding ops are applied
905
- this.loadedDeferred.resolve();
906
-
907
- for (const [messageContent, opMetadata] of this.loadedDeferredOutgoingOps) {
908
- this.reSubmitCore(messageContent, opMetadata);
909
- }
910
- this.loadedDeferredOutgoingOps.length = 0;
911
- }
912
- }
913
- }
914
-
915
849
  private initializeIntervalCollections() {
916
850
  // Listen and initialize new SharedIntervalCollections
917
851
  this.intervalCollections.eventEmitter.on(