@fluidframework/container-loader 2.0.0-internal.4.0.6 → 2.0.0-internal.4.1.1
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/CHANGELOG.md +14 -0
- package/README.md +38 -0
- package/dist/connectionManager.d.ts +2 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +16 -6
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +7 -0
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +35 -2
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +88 -43
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +3 -3
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +5 -4
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +27 -2
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +64 -6
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/deltaManager.d.ts +1 -3
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +3 -8
- package/dist/deltaManager.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +4 -1
- package/dist/loader.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/protocol.d.ts +1 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +4 -2
- package/dist/protocol.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js.map +1 -1
- package/lib/connectionManager.d.ts +2 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +16 -6
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +7 -0
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +35 -2
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +90 -45
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +3 -3
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +5 -4
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +27 -2
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +62 -6
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/deltaManager.d.ts +1 -3
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +3 -8
- package/lib/deltaManager.js.map +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js +4 -1
- package/lib/loader.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/protocol.d.ts +1 -0
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +3 -1
- package/lib/protocol.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js.map +1 -1
- package/package.json +17 -13
- package/src/connectionManager.ts +17 -7
- package/src/connectionStateHandler.ts +12 -0
- package/src/container.ts +138 -65
- package/src/containerContext.ts +6 -6
- package/src/containerStorageAdapter.ts +88 -5
- package/src/deltaManager.ts +3 -10
- package/src/index.ts +3 -1
- package/src/loader.ts +4 -1
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +4 -1
- package/src/utils.ts +3 -1
package/lib/container.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
// eslint-disable-next-line import/no-internal-modules
|
|
6
6
|
import merge from "lodash/merge";
|
|
7
|
+
// eslint-disable-next-line import/no-internal-modules
|
|
8
|
+
import cloneDeep from "lodash/cloneDeep";
|
|
7
9
|
import { v4 as uuid } from "uuid";
|
|
8
10
|
import { assert, performance, unreachableCase } from "@fluidframework/common-utils";
|
|
9
11
|
import { AttachState, isFluidCodeDetails, } from "@fluidframework/container-definitions";
|
|
@@ -18,14 +20,14 @@ import { DeltaManager } from "./deltaManager";
|
|
|
18
20
|
import { DeltaManagerProxy } from "./deltaManagerProxy";
|
|
19
21
|
import { RelativeLoader } from "./loader";
|
|
20
22
|
import { pkgVersion } from "./packageVersion";
|
|
21
|
-
import { ContainerStorageAdapter } from "./containerStorageAdapter";
|
|
23
|
+
import { ContainerStorageAdapter, getBlobContentsFromTree, getBlobContentsFromTreeWithBlobContents, } from "./containerStorageAdapter";
|
|
22
24
|
import { createConnectionStateHandler } from "./connectionStateHandler";
|
|
23
25
|
import { getProtocolSnapshotTree, getSnapshotTreeFromSerializedContainer } from "./utils";
|
|
24
26
|
import { initQuorumValuesFromCodeDetails, getCodeDetailsFromQuorumValues, QuorumProxy, } from "./quorum";
|
|
25
27
|
import { CollabWindowTracker } from "./collabWindowTracker";
|
|
26
28
|
import { ConnectionManager } from "./connectionManager";
|
|
27
29
|
import { ConnectionState } from "./connectionState";
|
|
28
|
-
import { ProtocolHandler } from "./protocol";
|
|
30
|
+
import { OnlyValidTermValue, ProtocolHandler, } from "./protocol";
|
|
29
31
|
const detachedContainerRefSeqNumber = 0;
|
|
30
32
|
const dirtyContainerEvent = "dirty";
|
|
31
33
|
const savedContainerEvent = "saved";
|
|
@@ -123,8 +125,11 @@ const summarizerClientType = "summarizer";
|
|
|
123
125
|
* @deprecated - In the next release Container will no longer be exported, IContainer should be used in its place.
|
|
124
126
|
*/
|
|
125
127
|
export class Container extends EventEmitterWithErrorHandling {
|
|
128
|
+
/**
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
126
131
|
constructor(loader, config, protocolHandlerBuilder) {
|
|
127
|
-
var _a, _b;
|
|
132
|
+
var _a, _b, _c;
|
|
128
133
|
super((name, error) => {
|
|
129
134
|
this.mc.logger.sendErrorEvent({
|
|
130
135
|
eventName: "ContainerEventHandlerException",
|
|
@@ -160,6 +165,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
160
165
|
this.messageCountAfterDisconnection = 0;
|
|
161
166
|
this.attachStarted = false;
|
|
162
167
|
this._dirtyContainer = false;
|
|
168
|
+
this.savedOps = [];
|
|
163
169
|
this.setAutoReconnectTime = performance.now();
|
|
164
170
|
this._disposed = false;
|
|
165
171
|
this.clientDetailsOverride = config.clientDetailsOverride;
|
|
@@ -204,9 +210,8 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
204
210
|
});
|
|
205
211
|
// Prefix all events in this file with container-loader
|
|
206
212
|
this.mc = loggerToMonitoringContext(ChildLogger.create(this.subLogger, "Container"));
|
|
207
|
-
this.options =
|
|
213
|
+
this.options = cloneDeep(this.loader.services.options);
|
|
208
214
|
this._deltaManager = this.createDeltaManager();
|
|
209
|
-
this._clientId = (_a = config.serializedContainerState) === null || _a === void 0 ? void 0 : _a.clientId;
|
|
210
215
|
this.connectionStateHandler = createConnectionStateHandler({
|
|
211
216
|
logger: this.mc.logger,
|
|
212
217
|
connectionStateChanged: (value, oldState, reason) => {
|
|
@@ -245,7 +250,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
245
250
|
this.connect();
|
|
246
251
|
}
|
|
247
252
|
},
|
|
248
|
-
}, this.deltaManager,
|
|
253
|
+
}, this.deltaManager, (_a = config.serializedContainerState) === null || _a === void 0 ? void 0 : _a.clientId);
|
|
249
254
|
this.on(savedContainerEvent, () => {
|
|
250
255
|
this.connectionStateHandler.containerSaved();
|
|
251
256
|
});
|
|
@@ -258,7 +263,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
258
263
|
// Whether the combined summary tree has been forced on by either the loader option or the monitoring context.
|
|
259
264
|
// Even if not forced on via this flag, combined summaries may still be enabled by service policy.
|
|
260
265
|
const forceEnableSummarizeProtocolTree = (_b = this.mc.config.getBoolean("Fluid.Container.summarizeProtocolTree2")) !== null && _b !== void 0 ? _b : this.loader.services.options.summarizeProtocolTree;
|
|
261
|
-
this.storageAdapter = new ContainerStorageAdapter(this.loader.services.detachedBlobStorage, this.mc.logger, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree);
|
|
266
|
+
this.storageAdapter = new ContainerStorageAdapter(this.loader.services.detachedBlobStorage, this.mc.logger, (_c = config.serializedContainerState) === null || _c === void 0 ? void 0 : _c.snapshotBlobs, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree);
|
|
262
267
|
const isDomAvailable = typeof document === "object" &&
|
|
263
268
|
document !== null &&
|
|
264
269
|
typeof document.addEventListener === "function" &&
|
|
@@ -282,6 +287,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
282
287
|
}
|
|
283
288
|
/**
|
|
284
289
|
* Load an existing container.
|
|
290
|
+
* @internal
|
|
285
291
|
*/
|
|
286
292
|
static async load(loader, loadOptions, pendingLocalState, protocolHandlerBuilder) {
|
|
287
293
|
const container = new Container(loader, {
|
|
@@ -430,6 +436,12 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
430
436
|
get clientDetails() {
|
|
431
437
|
return this._deltaManager.clientDetails;
|
|
432
438
|
}
|
|
439
|
+
get offlineLoadEnabled() {
|
|
440
|
+
var _a;
|
|
441
|
+
// summarizer will not have any pending state we want to save
|
|
442
|
+
return (((_a = this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad")) !== null && _a !== void 0 ? _a : false) &&
|
|
443
|
+
this.clientDetails.capabilities.interactive);
|
|
444
|
+
}
|
|
433
445
|
/**
|
|
434
446
|
* Get the code details that are currently specified for the container.
|
|
435
447
|
* @returns The current code details if any are specified, undefined if none are specified.
|
|
@@ -607,15 +619,21 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
607
619
|
// runtime matches pending ops to successful ones by clientId and client seq num, so we need to close the
|
|
608
620
|
// container at the same time we get pending state, otherwise this container could reconnect and resubmit with
|
|
609
621
|
// a new clientId and a future container using stale pending state without the new clientId would resubmit them
|
|
622
|
+
if (!this.offlineLoadEnabled) {
|
|
623
|
+
throw new UsageError("Can't get pending local state unless offline load is enabled");
|
|
624
|
+
}
|
|
610
625
|
assert(this.attachState === AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
611
626
|
assert(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
612
627
|
assert(!!this._protocolHandler, 0x2e3 /* "Must have a valid protocol handler instance" */);
|
|
613
|
-
assert(this.
|
|
628
|
+
assert(!!this.baseSnapshot, 0x5d4 /* no base snapshot */);
|
|
629
|
+
assert(!!this.baseSnapshotBlobs, 0x5d5 /* no snapshot blobs */);
|
|
614
630
|
const pendingState = {
|
|
615
631
|
pendingRuntimeState: this.context.getPendingLocalState(),
|
|
632
|
+
baseSnapshot: this.baseSnapshot,
|
|
633
|
+
snapshotBlobs: this.baseSnapshotBlobs,
|
|
634
|
+
savedOps: this.savedOps,
|
|
616
635
|
url: this.resolvedUrl.url,
|
|
617
|
-
|
|
618
|
-
term: this._protocolHandler.attributes.term,
|
|
636
|
+
term: OnlyValidTermValue,
|
|
619
637
|
clientId: this.clientId,
|
|
620
638
|
};
|
|
621
639
|
this.mc.logger.sendTelemetryEvent({ eventName: "CloseAndGetPendingLocalState" });
|
|
@@ -667,7 +685,13 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
667
685
|
// starting to attach the container to storage.
|
|
668
686
|
// Also, this should only be fired in detached container.
|
|
669
687
|
this._attachState = AttachState.Attaching;
|
|
670
|
-
this.
|
|
688
|
+
this.emit("attaching");
|
|
689
|
+
if (this.offlineLoadEnabled) {
|
|
690
|
+
const snapshot = getSnapshotTreeFromSerializedContainer(summary);
|
|
691
|
+
this.baseSnapshot = snapshot;
|
|
692
|
+
this.baseSnapshotBlobs =
|
|
693
|
+
getBlobContentsFromTreeWithBlobContents(snapshot);
|
|
694
|
+
}
|
|
671
695
|
}
|
|
672
696
|
// Actually go and create the resolved document
|
|
673
697
|
const createNewResolvedUrl = await this.urlResolver.resolve(request);
|
|
@@ -704,7 +728,13 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
704
728
|
const protocolSummary = this.captureProtocolSummary();
|
|
705
729
|
summary = combineAppAndProtocolSummary(appSummary, protocolSummary);
|
|
706
730
|
this._attachState = AttachState.Attaching;
|
|
707
|
-
this.
|
|
731
|
+
this.emit("attaching");
|
|
732
|
+
if (this.offlineLoadEnabled) {
|
|
733
|
+
const snapshot = getSnapshotTreeFromSerializedContainer(summary);
|
|
734
|
+
this.baseSnapshot = snapshot;
|
|
735
|
+
this.baseSnapshotBlobs =
|
|
736
|
+
getBlobContentsFromTreeWithBlobContents(snapshot);
|
|
737
|
+
}
|
|
708
738
|
await this.storageAdapter.uploadSummaryWithContext(summary, {
|
|
709
739
|
referenceSequenceNumber: 0,
|
|
710
740
|
ackHandle: undefined,
|
|
@@ -862,6 +892,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
862
892
|
* @param specifiedVersion - Version SHA to load snapshot. If not specified, will fetch the latest snapshot.
|
|
863
893
|
*/
|
|
864
894
|
async load(specifiedVersion, loadMode, pendingLocalState) {
|
|
895
|
+
var _a;
|
|
865
896
|
if (this._resolvedUrl === undefined) {
|
|
866
897
|
throw new Error("Attempting to load without a resolved url");
|
|
867
898
|
}
|
|
@@ -882,7 +913,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
882
913
|
};
|
|
883
914
|
// Start websocket connection as soon as possible. Note that there is no op handler attached yet, but the
|
|
884
915
|
// DeltaManager is resilient to this and will wait to start processing ops until after it is attached.
|
|
885
|
-
if (loadMode.deltaConnection === undefined) {
|
|
916
|
+
if (loadMode.deltaConnection === undefined && !pendingLocalState) {
|
|
886
917
|
this.connectToDeltaStream(connectionArgs);
|
|
887
918
|
}
|
|
888
919
|
if (!pendingLocalState) {
|
|
@@ -900,15 +931,23 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
900
931
|
// Fetch specified snapshot.
|
|
901
932
|
const { snapshot, versionId } = pendingLocalState === undefined
|
|
902
933
|
? await this.fetchSnapshotTree(specifiedVersion)
|
|
903
|
-
: { snapshot:
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
934
|
+
: { snapshot: pendingLocalState.baseSnapshot, versionId: undefined };
|
|
935
|
+
if (pendingLocalState) {
|
|
936
|
+
this.baseSnapshot = pendingLocalState.baseSnapshot;
|
|
937
|
+
this.baseSnapshotBlobs = pendingLocalState.snapshotBlobs;
|
|
938
|
+
}
|
|
939
|
+
else {
|
|
940
|
+
assert(snapshot !== undefined, 0x237 /* "Snapshot should exist" */);
|
|
941
|
+
if (this.offlineLoadEnabled) {
|
|
942
|
+
this.baseSnapshot = snapshot;
|
|
943
|
+
// Save contents of snapshot now, otherwise closeAndGetPendingLocalState() must be async
|
|
944
|
+
this.baseSnapshotBlobs = await getBlobContentsFromTree(snapshot, this.storage);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
const attributes = await this.getDocumentAttributes(this.storageAdapter, snapshot);
|
|
948
|
+
// If we saved ops, we will replay them and don't need DeltaManager to fetch them
|
|
949
|
+
const sequenceNumber = (_a = pendingLocalState === null || pendingLocalState === void 0 ? void 0 : pendingLocalState.savedOps[pendingLocalState.savedOps.length - 1]) === null || _a === void 0 ? void 0 : _a.sequenceNumber;
|
|
950
|
+
const dmAttributes = sequenceNumber !== undefined ? Object.assign(Object.assign({}, attributes), { sequenceNumber }) : attributes;
|
|
912
951
|
let opsBeforeReturnP;
|
|
913
952
|
// Attach op handlers to finish initialization and be able to start processing ops
|
|
914
953
|
// Kick off any ops fetching if required.
|
|
@@ -916,32 +955,35 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
916
955
|
case undefined:
|
|
917
956
|
// Start prefetch, but not set opsBeforeReturnP - boot is not blocked by it!
|
|
918
957
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
919
|
-
this.attachDeltaManagerOpHandler(
|
|
958
|
+
this.attachDeltaManagerOpHandler(dmAttributes, loadMode.deltaConnection !== "none" ? "all" : "none");
|
|
920
959
|
break;
|
|
921
960
|
case "cached":
|
|
922
|
-
opsBeforeReturnP = this.attachDeltaManagerOpHandler(
|
|
961
|
+
opsBeforeReturnP = this.attachDeltaManagerOpHandler(dmAttributes, "cached");
|
|
923
962
|
break;
|
|
924
963
|
case "all":
|
|
925
|
-
opsBeforeReturnP = this.attachDeltaManagerOpHandler(
|
|
964
|
+
opsBeforeReturnP = this.attachDeltaManagerOpHandler(dmAttributes, "all");
|
|
926
965
|
break;
|
|
927
966
|
default:
|
|
928
967
|
unreachableCase(loadMode.opsBeforeReturn);
|
|
929
968
|
}
|
|
930
969
|
// ...load in the existing quorum
|
|
931
970
|
// Initialize the protocol handler
|
|
932
|
-
|
|
933
|
-
await this.initializeProtocolStateFromSnapshot(attributes, this.storageAdapter, snapshot);
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
this.initializeProtocolState(attributes, {
|
|
937
|
-
members: pendingLocalState.protocol.members,
|
|
938
|
-
proposals: pendingLocalState.protocol.proposals,
|
|
939
|
-
values: pendingLocalState.protocol.values,
|
|
940
|
-
});
|
|
941
|
-
}
|
|
971
|
+
await this.initializeProtocolStateFromSnapshot(attributes, this.storageAdapter, snapshot);
|
|
942
972
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
943
973
|
await this.instantiateContext(true, // existing
|
|
944
974
|
codeDetails, snapshot, pendingLocalState === null || pendingLocalState === void 0 ? void 0 : pendingLocalState.pendingRuntimeState);
|
|
975
|
+
// replay saved ops
|
|
976
|
+
if (pendingLocalState) {
|
|
977
|
+
for (const message of pendingLocalState.savedOps) {
|
|
978
|
+
this.processRemoteMessage(message);
|
|
979
|
+
// allow runtime to apply stashed ops at this op's sequence number
|
|
980
|
+
await this.context.notifyOpReplay(message);
|
|
981
|
+
}
|
|
982
|
+
pendingLocalState.savedOps = [];
|
|
983
|
+
// now set clientId to stashed clientId so live ops are correctly processed as local
|
|
984
|
+
assert(this.clientId === undefined, 0x5d6 /* Unexpected clientId when setting stashed clientId */);
|
|
985
|
+
this._clientId = pendingLocalState === null || pendingLocalState === void 0 ? void 0 : pendingLocalState.clientId;
|
|
986
|
+
}
|
|
945
987
|
// We might have hit some failure that did not manifest itself in exception in this flow,
|
|
946
988
|
// do not start op processing in such case - static version of Container.load() will handle it correctly.
|
|
947
989
|
if (!this.closed) {
|
|
@@ -954,6 +996,11 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
954
996
|
}
|
|
955
997
|
switch (loadMode.deltaConnection) {
|
|
956
998
|
case undefined:
|
|
999
|
+
if (pendingLocalState) {
|
|
1000
|
+
// connect to delta stream now since we did not before
|
|
1001
|
+
this.connectToDeltaStream(connectionArgs);
|
|
1002
|
+
}
|
|
1003
|
+
// intentional fallthrough
|
|
957
1004
|
case "delayed":
|
|
958
1005
|
assert(this.inboundQueuePausedFromInit, 0x346 /* inboundQueuePausedFromInit should be true */);
|
|
959
1006
|
this.inboundQueuePausedFromInit = false;
|
|
@@ -986,7 +1033,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
986
1033
|
async createDetached(source) {
|
|
987
1034
|
const attributes = {
|
|
988
1035
|
sequenceNumber: detachedContainerRefSeqNumber,
|
|
989
|
-
term:
|
|
1036
|
+
term: OnlyValidTermValue,
|
|
990
1037
|
minimumSequenceNumber: 0,
|
|
991
1038
|
};
|
|
992
1039
|
await this.attachDeltaManagerOpHandler(attributes);
|
|
@@ -1029,7 +1076,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1029
1076
|
return {
|
|
1030
1077
|
minimumSequenceNumber: 0,
|
|
1031
1078
|
sequenceNumber: 0,
|
|
1032
|
-
term:
|
|
1079
|
+
term: OnlyValidTermValue,
|
|
1033
1080
|
};
|
|
1034
1081
|
}
|
|
1035
1082
|
// Backward compatibility: old docs would have ".attributes" instead of "attributes"
|
|
@@ -1037,10 +1084,6 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1037
1084
|
? tree.trees[".protocol"].blobs.attributes
|
|
1038
1085
|
: tree.blobs[".attributes"];
|
|
1039
1086
|
const attributes = await readAndParse(storage, attributesHash);
|
|
1040
|
-
// Backward compatibility for older summaries with no term
|
|
1041
|
-
if (attributes.term === undefined) {
|
|
1042
|
-
attributes.term = 1;
|
|
1043
|
-
}
|
|
1044
1087
|
return attributes;
|
|
1045
1088
|
}
|
|
1046
1089
|
async initializeProtocolStateFromSnapshot(attributes, storage, snapshot) {
|
|
@@ -1160,7 +1203,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1160
1203
|
}
|
|
1161
1204
|
createDeltaManager() {
|
|
1162
1205
|
const serviceProvider = () => this.service;
|
|
1163
|
-
const deltaManager = new DeltaManager(serviceProvider, ChildLogger.create(this.subLogger, "DeltaManager"), () => this.activeConnection(), (props) => new ConnectionManager(serviceProvider, this.client, this._canReconnect, ChildLogger.create(this.subLogger, "ConnectionManager"), props));
|
|
1206
|
+
const deltaManager = new DeltaManager(serviceProvider, ChildLogger.create(this.subLogger, "DeltaManager"), () => this.activeConnection(), (props) => new ConnectionManager(serviceProvider, () => this.isDirty, this.client, this._canReconnect, ChildLogger.create(this.subLogger, "ConnectionManager"), props));
|
|
1164
1207
|
// Disable inbound queues as Container is not ready to accept any ops until we are fully loaded!
|
|
1165
1208
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1166
1209
|
deltaManager.inbound.pause();
|
|
@@ -1199,8 +1242,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1199
1242
|
return deltaManager;
|
|
1200
1243
|
}
|
|
1201
1244
|
async attachDeltaManagerOpHandler(attributes, prefetchType) {
|
|
1202
|
-
|
|
1203
|
-
return this._deltaManager.attachOpHandler(attributes.minimumSequenceNumber, attributes.sequenceNumber, (_a = attributes.term) !== null && _a !== void 0 ? _a : 1, {
|
|
1245
|
+
return this._deltaManager.attachOpHandler(attributes.minimumSequenceNumber, attributes.sequenceNumber, {
|
|
1204
1246
|
process: (message) => this.processRemoteMessage(message),
|
|
1205
1247
|
processSignal: (message) => {
|
|
1206
1248
|
this.processSignal(message);
|
|
@@ -1263,7 +1305,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1263
1305
|
this.messageCountAfterDisconnection = 0;
|
|
1264
1306
|
}
|
|
1265
1307
|
// Both protocol and context should not be undefined if we got so far.
|
|
1266
|
-
this.setContextConnectedState(state, (_a = this.
|
|
1308
|
+
this.setContextConnectedState(state, (_a = this.readOnlyInfo.readonly) !== null && _a !== void 0 ? _a : false);
|
|
1267
1309
|
this.protocolHandler.setConnectionState(state, this.clientId);
|
|
1268
1310
|
raiseConnectedEvent(this.mc.logger, this, state, this.clientId, disconnectedReason);
|
|
1269
1311
|
if (logOpsOnReconnect) {
|
|
@@ -1321,6 +1363,9 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1321
1363
|
return this._deltaManager.submit(type, contents, batch, metadata, compression, referenceSequenceNumber);
|
|
1322
1364
|
}
|
|
1323
1365
|
processRemoteMessage(message) {
|
|
1366
|
+
if (this.offlineLoadEnabled) {
|
|
1367
|
+
this.savedOps.push(message);
|
|
1368
|
+
}
|
|
1324
1369
|
const local = this.clientId === message.clientId;
|
|
1325
1370
|
// Allow the protocol handler to process the message
|
|
1326
1371
|
const result = this.protocolHandler.processMessage(message, local);
|