@fluidframework/container-loader 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.5.3.2.178189
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 +31 -0
- package/dist/catchUpMonitor.d.ts +1 -1
- package/dist/catchUpMonitor.d.ts.map +1 -1
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/connectionManager.d.ts +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +4 -1
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +10 -8
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +30 -31
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +180 -108
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +23 -66
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +28 -213
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +1 -1
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +38 -6
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +1 -3
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts +2 -1
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js.map +1 -1
- package/dist/disposal.d.ts +13 -0
- package/dist/disposal.d.ts.map +1 -0
- package/dist/disposal.js +25 -0
- package/dist/disposal.js.map +1 -0
- package/dist/loader.d.ts +1 -2
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js.map +1 -1
- package/dist/noopHeuristic.d.ts +23 -0
- package/dist/noopHeuristic.d.ts.map +1 -0
- package/dist/{collabWindowTracker.js → noopHeuristic.js} +30 -42
- package/dist/noopHeuristic.js.map +1 -0
- 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 +7 -12
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +17 -19
- package/dist/protocol.js.map +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/protocolTreeDocumentStorageService.js.map +1 -1
- package/dist/quorum.d.ts +1 -17
- package/dist/quorum.d.ts.map +1 -1
- package/dist/quorum.js +1 -17
- package/dist/quorum.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts +1 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/lib/catchUpMonitor.d.ts +1 -1
- package/lib/catchUpMonitor.d.ts.map +1 -1
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/connectionManager.d.ts +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +4 -1
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +10 -8
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +30 -31
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +184 -112
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +23 -66
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +28 -213
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +1 -1
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +38 -6
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +1 -3
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts +2 -1
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js.map +1 -1
- package/lib/disposal.d.ts +13 -0
- package/lib/disposal.d.ts.map +1 -0
- package/lib/disposal.js +21 -0
- package/lib/disposal.js.map +1 -0
- package/lib/loader.d.ts +1 -2
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js.map +1 -1
- package/lib/noopHeuristic.d.ts +23 -0
- package/lib/noopHeuristic.d.ts.map +1 -0
- package/lib/{collabWindowTracker.js → noopHeuristic.js} +30 -42
- package/lib/noopHeuristic.js.map +1 -0
- 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 +7 -12
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +15 -18
- package/lib/protocol.js.map +1 -1
- package/lib/protocolTreeDocumentStorageService.d.ts +1 -1
- package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/lib/protocolTreeDocumentStorageService.js.map +1 -1
- package/lib/quorum.d.ts +1 -17
- package/lib/quorum.d.ts.map +1 -1
- package/lib/quorum.js +1 -16
- package/lib/quorum.js.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts +1 -1
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/package.json +18 -14
- package/src/catchUpMonitor.ts +1 -1
- package/src/connectionManager.ts +1 -1
- package/src/connectionStateHandler.ts +15 -10
- package/src/container.ts +279 -139
- package/src/containerContext.ts +33 -335
- package/src/containerStorageAdapter.ts +47 -5
- package/src/contracts.ts +1 -3
- package/src/deltaManager.ts +15 -8
- package/src/disposal.ts +25 -0
- package/src/loader.ts +1 -1
- package/src/{collabWindowTracker.ts → noopHeuristic.ts} +37 -47
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +18 -39
- package/src/protocolTreeDocumentStorageService.ts +1 -1
- package/src/quorum.ts +2 -31
- package/src/retriableDocumentStorageService.ts +2 -1
- package/dist/collabWindowTracker.d.ts +0 -19
- package/dist/collabWindowTracker.d.ts.map +0 -1
- package/dist/collabWindowTracker.js.map +0 -1
- package/dist/deltaManagerProxy.d.ts +0 -42
- package/dist/deltaManagerProxy.d.ts.map +0 -1
- package/dist/deltaManagerProxy.js +0 -79
- package/dist/deltaManagerProxy.js.map +0 -1
- package/lib/collabWindowTracker.d.ts +0 -19
- package/lib/collabWindowTracker.d.ts.map +0 -1
- package/lib/collabWindowTracker.js.map +0 -1
- package/lib/deltaManagerProxy.d.ts +0 -42
- package/lib/deltaManagerProxy.d.ts.map +0 -1
- package/lib/deltaManagerProxy.js +0 -74
- package/lib/deltaManagerProxy.js.map +0 -1
- package/src/deltaManagerProxy.ts +0 -109
package/dist/container.js
CHANGED
|
@@ -21,20 +21,20 @@ const audience_1 = require("./audience");
|
|
|
21
21
|
const containerContext_1 = require("./containerContext");
|
|
22
22
|
const contracts_1 = require("./contracts");
|
|
23
23
|
const deltaManager_1 = require("./deltaManager");
|
|
24
|
-
const deltaManagerProxy_1 = require("./deltaManagerProxy");
|
|
25
24
|
const loader_1 = require("./loader");
|
|
26
25
|
const packageVersion_1 = require("./packageVersion");
|
|
27
26
|
const containerStorageAdapter_1 = require("./containerStorageAdapter");
|
|
28
27
|
const connectionStateHandler_1 = require("./connectionStateHandler");
|
|
29
28
|
const utils_1 = require("./utils");
|
|
30
29
|
const quorum_1 = require("./quorum");
|
|
31
|
-
const
|
|
30
|
+
const noopHeuristic_1 = require("./noopHeuristic");
|
|
32
31
|
const connectionManager_1 = require("./connectionManager");
|
|
33
32
|
const connectionState_1 = require("./connectionState");
|
|
34
33
|
const protocol_1 = require("./protocol");
|
|
35
34
|
const detachedContainerRefSeqNumber = 0;
|
|
36
35
|
const dirtyContainerEvent = "dirty";
|
|
37
36
|
const savedContainerEvent = "saved";
|
|
37
|
+
const packageNotFactoryError = "Code package does not implement IRuntimeFactory";
|
|
38
38
|
/**
|
|
39
39
|
* Waits until container connects to delta storage and gets up-to-date.
|
|
40
40
|
*
|
|
@@ -164,8 +164,23 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
164
164
|
this.attachStarted = false;
|
|
165
165
|
this._dirtyContainer = false;
|
|
166
166
|
this.savedOps = [];
|
|
167
|
+
this.clientsWhoShouldHaveLeft = new Set();
|
|
167
168
|
this.setAutoReconnectTime = common_utils_1.performance.now();
|
|
169
|
+
this._lifecycleEvents = new common_utils_1.TypedEventEmitter();
|
|
168
170
|
this._disposed = false;
|
|
171
|
+
this.getAbsoluteUrl = async (relativeUrl) => {
|
|
172
|
+
if (this.resolvedUrl === undefined) {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, (0, contracts_1.getPackageName)(this._loadedCodeDetails));
|
|
176
|
+
};
|
|
177
|
+
this.updateDirtyContainerState = (dirty) => {
|
|
178
|
+
if (this._dirtyContainer === dirty) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this._dirtyContainer = dirty;
|
|
182
|
+
this.emit(dirty ? dirtyContainerEvent : savedContainerEvent);
|
|
183
|
+
};
|
|
169
184
|
const { canReconnect, clientDetailsOverride, urlResolver, documentServiceFactory, codeLoader, options, scope, subLogger, detachedBlobStorage, protocolHandlerBuilder, } = createProps;
|
|
170
185
|
this.connectionTransitionTimes[connectionState_1.ConnectionState.Disconnected] = common_utils_1.performance.now();
|
|
171
186
|
const pendingLocalState = loadProps === null || loadProps === void 0 ? void 0 : loadProps.pendingLocalState;
|
|
@@ -210,13 +225,18 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
210
225
|
dmInitialSeqNumber: () => { var _a; return (_a = this._deltaManager) === null || _a === void 0 ? void 0 : _a.initialSequenceNumber; },
|
|
211
226
|
dmLastProcessedSeqNumber: () => { var _a; return (_a = this._deltaManager) === null || _a === void 0 ? void 0 : _a.lastSequenceNumber; },
|
|
212
227
|
dmLastKnownSeqNumber: () => { var _a; return (_a = this._deltaManager) === null || _a === void 0 ? void 0 : _a.lastKnownSeqNumber; },
|
|
213
|
-
containerLoadedFromVersionId: () => { var _a; return (_a = this.
|
|
214
|
-
containerLoadedFromVersionDate: () => { var _a; return (_a = this.
|
|
228
|
+
containerLoadedFromVersionId: () => { var _a; return (_a = this._loadedFromVersion) === null || _a === void 0 ? void 0 : _a.id; },
|
|
229
|
+
containerLoadedFromVersionDate: () => { var _a; return (_a = this._loadedFromVersion) === null || _a === void 0 ? void 0 : _a.date; },
|
|
215
230
|
// message information to associate errors with the specific execution state
|
|
216
231
|
// dmLastMsqSeqNumber: if present, same as dmLastProcessedSeqNumber
|
|
217
232
|
dmLastMsqSeqNumber: () => { var _a, _b; return (_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.sequenceNumber; },
|
|
218
233
|
dmLastMsqSeqTimestamp: () => { var _a, _b; return (_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp; },
|
|
219
|
-
dmLastMsqSeqClientId: () => {
|
|
234
|
+
dmLastMsqSeqClientId: () => {
|
|
235
|
+
var _a, _b, _c, _d;
|
|
236
|
+
return ((_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.clientId) === null
|
|
237
|
+
? "null"
|
|
238
|
+
: (_d = (_c = this.deltaManager) === null || _c === void 0 ? void 0 : _c.lastMessage) === null || _d === void 0 ? void 0 : _d.clientId;
|
|
239
|
+
},
|
|
220
240
|
dmLastMsgClientSeq: () => { var _a, _b; return (_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.clientSequenceNumber; },
|
|
221
241
|
connectionStateDuration: () => common_utils_1.performance.now() - this.connectionTransitionTimes[this.connectionState],
|
|
222
242
|
},
|
|
@@ -262,6 +282,9 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
262
282
|
this.connect();
|
|
263
283
|
}
|
|
264
284
|
},
|
|
285
|
+
clientShouldHaveLeft: (clientId) => {
|
|
286
|
+
this.clientsWhoShouldHaveLeft.add(clientId);
|
|
287
|
+
},
|
|
265
288
|
}, this.deltaManager, pendingLocalState === null || pendingLocalState === void 0 ? void 0 : pendingLocalState.clientId);
|
|
266
289
|
this.on(savedContainerEvent, () => {
|
|
267
290
|
this.connectionStateHandler.containerSaved();
|
|
@@ -371,14 +394,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
371
394
|
this._lifecycleState === "disposing" ||
|
|
372
395
|
this._lifecycleState === "disposed");
|
|
373
396
|
}
|
|
374
|
-
get
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
get context() {
|
|
378
|
-
if (this._context === undefined) {
|
|
379
|
-
throw new container_utils_1.GenericError("Attempted to access context before it was defined");
|
|
397
|
+
get runtime() {
|
|
398
|
+
if (this._runtime === undefined) {
|
|
399
|
+
throw new Error("Attempted to access runtime before it was defined");
|
|
380
400
|
}
|
|
381
|
-
return this.
|
|
401
|
+
return this._runtime;
|
|
382
402
|
}
|
|
383
403
|
get protocolHandler() {
|
|
384
404
|
if (this._protocolHandler === undefined) {
|
|
@@ -407,15 +427,9 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
407
427
|
*/
|
|
408
428
|
return (_a = this.service) === null || _a === void 0 ? void 0 : _a.resolvedUrl;
|
|
409
429
|
}
|
|
410
|
-
get loadedFromVersion() {
|
|
411
|
-
return this._loadedFromVersion;
|
|
412
|
-
}
|
|
413
430
|
get readOnlyInfo() {
|
|
414
431
|
return this._deltaManager.readOnlyInfo;
|
|
415
432
|
}
|
|
416
|
-
get closeSignal() {
|
|
417
|
-
return this._deltaManager.closeAbortController.signal;
|
|
418
|
-
}
|
|
419
433
|
/**
|
|
420
434
|
* Tracks host requiring read-only mode.
|
|
421
435
|
*/
|
|
@@ -431,13 +445,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
431
445
|
get connected() {
|
|
432
446
|
return this.connectionStateHandler.connectionState === connectionState_1.ConnectionState.Connected;
|
|
433
447
|
}
|
|
434
|
-
/**
|
|
435
|
-
* Service configuration details. If running in offline mode will be undefined otherwise will contain service
|
|
436
|
-
* configuration details returned as part of the initial connection.
|
|
437
|
-
*/
|
|
438
|
-
get serviceConfiguration() {
|
|
439
|
-
return this._deltaManager.serviceConfiguration;
|
|
440
|
-
}
|
|
441
448
|
/**
|
|
442
449
|
* The server provided id of the client.
|
|
443
450
|
* Set once this.connected is true, otherwise undefined
|
|
@@ -445,21 +452,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
445
452
|
get clientId() {
|
|
446
453
|
return this._clientId;
|
|
447
454
|
}
|
|
448
|
-
/**
|
|
449
|
-
* The server provided claims of the client.
|
|
450
|
-
* Set once this.connected is true, otherwise undefined
|
|
451
|
-
*/
|
|
452
|
-
get scopes() {
|
|
453
|
-
return this._deltaManager.connectionManager.scopes;
|
|
454
|
-
}
|
|
455
|
-
get clientDetails() {
|
|
456
|
-
return this._deltaManager.clientDetails;
|
|
457
|
-
}
|
|
458
455
|
get offlineLoadEnabled() {
|
|
459
456
|
var _a, _b;
|
|
460
457
|
const enabled = (_a = this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad")) !== null && _a !== void 0 ? _a : ((_b = this.options) === null || _b === void 0 ? void 0 : _b.enableOfflineLoad) === true;
|
|
461
458
|
// summarizer will not have any pending state we want to save
|
|
462
|
-
return enabled && this.clientDetails.capabilities.interactive;
|
|
459
|
+
return enabled && this.deltaManager.clientDetails.capabilities.interactive;
|
|
463
460
|
}
|
|
464
461
|
/**
|
|
465
462
|
* Get the code details that are currently specified for the container.
|
|
@@ -474,8 +471,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
474
471
|
* loaded.
|
|
475
472
|
*/
|
|
476
473
|
getLoadedCodeDetails() {
|
|
477
|
-
|
|
478
|
-
return (_a = this._context) === null || _a === void 0 ? void 0 : _a.codeDetails;
|
|
474
|
+
return this._loadedCodeDetails;
|
|
479
475
|
}
|
|
480
476
|
/**
|
|
481
477
|
* Retrieves the audience associated with the document
|
|
@@ -496,32 +492,26 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
496
492
|
*/
|
|
497
493
|
async getEntryPoint() {
|
|
498
494
|
var _a, _b;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (this.
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
while (this._context === undefined) {
|
|
506
|
-
await new Promise((resolve, reject) => {
|
|
507
|
-
const contextChangedHandler = () => {
|
|
508
|
-
resolve();
|
|
509
|
-
this.off("disposed", disposedHandler);
|
|
510
|
-
};
|
|
511
|
-
const disposedHandler = (error) => {
|
|
512
|
-
reject(error !== null && error !== void 0 ? error : "The Container is disposed");
|
|
513
|
-
this.off("contextChanged", contextChangedHandler);
|
|
514
|
-
};
|
|
515
|
-
this.once("contextChanged", contextChangedHandler);
|
|
516
|
-
this.once("disposed", disposedHandler);
|
|
517
|
-
});
|
|
518
|
-
// The Promise above should only resolve (vs reject) if the 'contextChanged' event was emitted and that
|
|
519
|
-
// should have set this._context; making sure.
|
|
520
|
-
(0, common_utils_1.assert)(this._context !== undefined, 0x5a2 /* Context still not defined after contextChanged event */);
|
|
495
|
+
if (this._disposed) {
|
|
496
|
+
throw new container_utils_1.UsageError("The context is already disposed");
|
|
497
|
+
}
|
|
498
|
+
if (this._runtime !== undefined) {
|
|
499
|
+
return (_b = (_a = this._runtime).getEntryPoint) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
521
500
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
501
|
+
return new Promise((resolve, reject) => {
|
|
502
|
+
const runtimeInstantiatedHandler = () => {
|
|
503
|
+
var _a, _b;
|
|
504
|
+
(0, common_utils_1.assert)(this._runtime !== undefined, 0x5a3 /* runtimeInstantiated fired but runtime is still undefined */);
|
|
505
|
+
resolve((_b = (_a = this._runtime).getEntryPoint) === null || _b === void 0 ? void 0 : _b.call(_a));
|
|
506
|
+
this._lifecycleEvents.off("disposed", disposedHandler);
|
|
507
|
+
};
|
|
508
|
+
const disposedHandler = () => {
|
|
509
|
+
reject(new Error("ContainerContext was disposed"));
|
|
510
|
+
this._lifecycleEvents.off("runtimeInstantiated", runtimeInstantiatedHandler);
|
|
511
|
+
};
|
|
512
|
+
this._lifecycleEvents.once("runtimeInstantiated", runtimeInstantiatedHandler);
|
|
513
|
+
this._lifecycleEvents.once("disposed", disposedHandler);
|
|
514
|
+
});
|
|
525
515
|
}
|
|
526
516
|
/**
|
|
527
517
|
* Retrieves the quorum associated with the document
|
|
@@ -575,6 +565,10 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
575
565
|
}
|
|
576
566
|
finally {
|
|
577
567
|
this._lifecycleState = "closed";
|
|
568
|
+
// There is no user for summarizer, so we need to ensure dispose is called
|
|
569
|
+
if (this.client.details.type === summarizerClientType) {
|
|
570
|
+
this.dispose(error);
|
|
571
|
+
}
|
|
578
572
|
}
|
|
579
573
|
}
|
|
580
574
|
disposeCore(error) {
|
|
@@ -588,7 +582,8 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
588
582
|
// This gives us a chance to know what errors happened on open vs. on fully loaded container.
|
|
589
583
|
this.mc.logger.sendTelemetryEvent({
|
|
590
584
|
eventName: "ContainerDispose",
|
|
591
|
-
|
|
585
|
+
// Only log error if container isn't closed
|
|
586
|
+
category: !this.closed && error !== undefined ? "error" : "generic",
|
|
592
587
|
}, error);
|
|
593
588
|
// ! Progressing from "closed" to "disposing" is not allowed
|
|
594
589
|
if (this._lifecycleState !== "closed") {
|
|
@@ -596,7 +591,8 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
596
591
|
}
|
|
597
592
|
(_a = this._protocolHandler) === null || _a === void 0 ? void 0 : _a.close();
|
|
598
593
|
this.connectionStateHandler.dispose();
|
|
599
|
-
|
|
594
|
+
const maybeError = error !== undefined ? new Error(error.message) : undefined;
|
|
595
|
+
(_b = this._runtime) === null || _b === void 0 ? void 0 : _b.dispose(maybeError);
|
|
600
596
|
this.storageAdapter.dispose();
|
|
601
597
|
// Notify storage about critical errors. They may be due to disconnect between client & server knowledge
|
|
602
598
|
// about file, like file being overwritten in storage, but client having stale local cache.
|
|
@@ -614,6 +610,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
614
610
|
}
|
|
615
611
|
finally {
|
|
616
612
|
this._lifecycleState = "disposed";
|
|
613
|
+
this._lifecycleEvents.emit("disposed");
|
|
617
614
|
}
|
|
618
615
|
}
|
|
619
616
|
closeAndGetPendingLocalState() {
|
|
@@ -628,12 +625,15 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
628
625
|
if (!this.offlineLoadEnabled) {
|
|
629
626
|
throw new container_utils_1.UsageError("Can't get pending local state unless offline load is enabled");
|
|
630
627
|
}
|
|
628
|
+
if (this.closed || this._disposed) {
|
|
629
|
+
throw new container_utils_1.UsageError("Pending state cannot be retried if the container is closed or disposed");
|
|
630
|
+
}
|
|
631
631
|
(0, common_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
632
632
|
(0, common_utils_1.assert)(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
633
633
|
(0, common_utils_1.assert)(!!this.baseSnapshot, 0x5d4 /* no base snapshot */);
|
|
634
634
|
(0, common_utils_1.assert)(!!this.baseSnapshotBlobs, 0x5d5 /* no snapshot blobs */);
|
|
635
635
|
const pendingState = {
|
|
636
|
-
pendingRuntimeState: this.
|
|
636
|
+
pendingRuntimeState: this.runtime.getPendingLocalState(),
|
|
637
637
|
baseSnapshot: this.baseSnapshot,
|
|
638
638
|
snapshotBlobs: this.baseSnapshotBlobs,
|
|
639
639
|
savedOps: this.savedOps,
|
|
@@ -649,7 +649,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
649
649
|
}
|
|
650
650
|
serialize() {
|
|
651
651
|
(0, common_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Detached, 0x0d3 /* "Should only be called in detached container" */);
|
|
652
|
-
const appSummary = this.
|
|
652
|
+
const appSummary = this.runtime.createSummary();
|
|
653
653
|
const protocolSummary = this.captureProtocolSummary();
|
|
654
654
|
const combinedSummary = (0, driver_utils_1.combineAppAndProtocolSummary)(appSummary, protocolSummary);
|
|
655
655
|
if (this.detachedBlobStorage && this.detachedBlobStorage.size > 0) {
|
|
@@ -678,7 +678,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
678
678
|
if (!hasAttachmentBlobs) {
|
|
679
679
|
// Get the document state post attach - possibly can just call attach but we need to change the
|
|
680
680
|
// semantics around what the attach means as far as async code goes.
|
|
681
|
-
const appSummary = this.
|
|
681
|
+
const appSummary = this.runtime.createSummary();
|
|
682
682
|
const protocolSummary = this.captureProtocolSummary();
|
|
683
683
|
summary = (0, driver_utils_1.combineAppAndProtocolSummary)(appSummary, protocolSummary);
|
|
684
684
|
// Set the state as attaching as we are starting the process of attaching container.
|
|
@@ -686,6 +686,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
686
686
|
// starting to attach the container to storage.
|
|
687
687
|
// Also, this should only be fired in detached container.
|
|
688
688
|
this._attachState = container_definitions_1.AttachState.Attaching;
|
|
689
|
+
this.runtime.setAttachState(container_definitions_1.AttachState.Attaching);
|
|
689
690
|
this.emit("attaching");
|
|
690
691
|
if (this.offlineLoadEnabled) {
|
|
691
692
|
const snapshot = (0, utils_1.getSnapshotTreeFromSerializedContainer)(summary);
|
|
@@ -700,7 +701,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
700
701
|
(0, common_utils_1.assert)(this.client.details.type !== summarizerClientType &&
|
|
701
702
|
createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
|
|
702
703
|
this.service = await (0, driver_utils_1.runWithRetry)(async () => this.serviceFactory.createContainer(summary, createNewResolvedUrl, this.subLogger, false), "containerAttach", this.mc.logger, {
|
|
703
|
-
cancel: this.
|
|
704
|
+
cancel: this._deltaManager.closeAbortController.signal,
|
|
704
705
|
});
|
|
705
706
|
}
|
|
706
707
|
await this.storageAdapter.connectToService(this.service);
|
|
@@ -722,10 +723,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
722
723
|
}
|
|
723
724
|
}
|
|
724
725
|
// take summary and upload
|
|
725
|
-
const appSummary = this.
|
|
726
|
+
const appSummary = this.runtime.createSummary(redirectTable);
|
|
726
727
|
const protocolSummary = this.captureProtocolSummary();
|
|
727
728
|
summary = (0, driver_utils_1.combineAppAndProtocolSummary)(appSummary, protocolSummary);
|
|
728
729
|
this._attachState = container_definitions_1.AttachState.Attaching;
|
|
730
|
+
this.runtime.setAttachState(container_definitions_1.AttachState.Attaching);
|
|
729
731
|
this.emit("attaching");
|
|
730
732
|
if (this.offlineLoadEnabled) {
|
|
731
733
|
const snapshot = (0, utils_1.getSnapshotTreeFromSerializedContainer)(summary);
|
|
@@ -740,6 +742,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
740
742
|
});
|
|
741
743
|
}
|
|
742
744
|
this._attachState = container_definitions_1.AttachState.Attached;
|
|
745
|
+
this.runtime.setAttachState(container_definitions_1.AttachState.Attached);
|
|
743
746
|
this.emit("attached");
|
|
744
747
|
if (!this.closed) {
|
|
745
748
|
this.resumeInternal({
|
|
@@ -758,7 +761,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
758
761
|
}, { start: true, end: true, cancel: "generic" });
|
|
759
762
|
}
|
|
760
763
|
async request(path) {
|
|
761
|
-
return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Request" }, async () => this.
|
|
764
|
+
return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Request" }, async () => this.runtime.request(path), { end: true, cancel: "error" });
|
|
762
765
|
}
|
|
763
766
|
setAutoReconnectInternal(mode) {
|
|
764
767
|
const currentMode = this._deltaManager.connectionManager.reconnectMode;
|
|
@@ -824,13 +827,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
824
827
|
// Ensure connection to web socket
|
|
825
828
|
this.connectToDeltaStream(args);
|
|
826
829
|
}
|
|
827
|
-
async getAbsoluteUrl(relativeUrl) {
|
|
828
|
-
var _a;
|
|
829
|
-
if (this.resolvedUrl === undefined) {
|
|
830
|
-
return undefined;
|
|
831
|
-
}
|
|
832
|
-
return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, (0, contracts_1.getPackageName)((_a = this._context) === null || _a === void 0 ? void 0 : _a.codeDetails));
|
|
833
|
-
}
|
|
834
830
|
async proposeCodeDetails(codeDetails) {
|
|
835
831
|
if (!(0, container_definitions_1.isFluidCodeDetails)(codeDetails)) {
|
|
836
832
|
throw new Error("Provided codeDetails are not IFluidCodeDetails");
|
|
@@ -852,7 +848,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
852
848
|
this.deltaManager.inbound.pause(),
|
|
853
849
|
this.deltaManager.inboundSignal.pause(),
|
|
854
850
|
]);
|
|
855
|
-
if ((await this.
|
|
851
|
+
if ((await this.satisfies(codeDetails)) === true) {
|
|
856
852
|
this.deltaManager.inbound.resume();
|
|
857
853
|
this.deltaManager.inboundSignal.resume();
|
|
858
854
|
return;
|
|
@@ -861,6 +857,38 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
861
857
|
const error = new container_utils_1.GenericError("Existing context does not satisfy incoming proposal");
|
|
862
858
|
this.close(error);
|
|
863
859
|
}
|
|
860
|
+
/**
|
|
861
|
+
* Determines if the currently loaded module satisfies the incoming constraint code details
|
|
862
|
+
*/
|
|
863
|
+
async satisfies(constraintCodeDetails) {
|
|
864
|
+
var _a, _b;
|
|
865
|
+
// If we have no module, it can't satisfy anything.
|
|
866
|
+
if (this._loadedModule === undefined) {
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
const comparers = [];
|
|
870
|
+
const maybeCompareCodeLoader = this.codeLoader;
|
|
871
|
+
if (maybeCompareCodeLoader.IFluidCodeDetailsComparer !== undefined) {
|
|
872
|
+
comparers.push(maybeCompareCodeLoader.IFluidCodeDetailsComparer);
|
|
873
|
+
}
|
|
874
|
+
const maybeCompareExport = (_a = this._loadedModule) === null || _a === void 0 ? void 0 : _a.module.fluidExport;
|
|
875
|
+
if ((maybeCompareExport === null || maybeCompareExport === void 0 ? void 0 : maybeCompareExport.IFluidCodeDetailsComparer) !== undefined) {
|
|
876
|
+
comparers.push(maybeCompareExport.IFluidCodeDetailsComparer);
|
|
877
|
+
}
|
|
878
|
+
// If there are no comparers, then it's impossible to know if the currently loaded package satisfies
|
|
879
|
+
// the incoming constraint, so we return false. Assuming it does not satisfy is safer, to force a reload
|
|
880
|
+
// rather than potentially running with incompatible code.
|
|
881
|
+
if (comparers.length === 0) {
|
|
882
|
+
return false;
|
|
883
|
+
}
|
|
884
|
+
for (const comparer of comparers) {
|
|
885
|
+
const satisfies = await comparer.satisfies((_b = this._loadedModule) === null || _b === void 0 ? void 0 : _b.details, constraintCodeDetails);
|
|
886
|
+
if (satisfies === false) {
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
return true;
|
|
891
|
+
}
|
|
864
892
|
async getVersion(version) {
|
|
865
893
|
const versions = await this.storageAdapter.getVersions(version, 1);
|
|
866
894
|
return versions[0];
|
|
@@ -878,7 +906,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
878
906
|
* @param specifiedVersion - Version SHA to load snapshot. If not specified, will fetch the latest snapshot.
|
|
879
907
|
*/
|
|
880
908
|
async load(specifiedVersion, loadMode, resolvedUrl, pendingLocalState) {
|
|
881
|
-
var _a;
|
|
909
|
+
var _a, _b, _c;
|
|
882
910
|
this.service = await this.serviceFactory.createDocumentService(resolvedUrl, this.subLogger, this.client.details.type === summarizerClientType);
|
|
883
911
|
// Ideally we always connect as "read" by default.
|
|
884
912
|
// Currently that works with SPO & r11s, because we get "write" connection when connecting to non-existing file.
|
|
@@ -922,7 +950,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
922
950
|
if (this.offlineLoadEnabled) {
|
|
923
951
|
this.baseSnapshot = snapshot;
|
|
924
952
|
// Save contents of snapshot now, otherwise closeAndGetPendingLocalState() must be async
|
|
925
|
-
this.baseSnapshotBlobs = await (0, containerStorageAdapter_1.getBlobContentsFromTree)(snapshot, this.
|
|
953
|
+
this.baseSnapshotBlobs = await (0, containerStorageAdapter_1.getBlobContentsFromTree)(snapshot, this.storageAdapter);
|
|
926
954
|
}
|
|
927
955
|
}
|
|
928
956
|
const attributes = await this.getDocumentAttributes(this.storageAdapter, snapshot);
|
|
@@ -958,7 +986,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
958
986
|
for (const message of pendingLocalState.savedOps) {
|
|
959
987
|
this.processRemoteMessage(message);
|
|
960
988
|
// allow runtime to apply stashed ops at this op's sequence number
|
|
961
|
-
await this.
|
|
989
|
+
await ((_c = (_b = this.runtime).notifyOpReplay) === null || _c === void 0 ? void 0 : _c.call(_b, message));
|
|
962
990
|
}
|
|
963
991
|
pendingLocalState.savedOps = [];
|
|
964
992
|
// now set clientId to stashed clientId so live ops are correctly processed as local
|
|
@@ -1197,7 +1225,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1197
1225
|
});
|
|
1198
1226
|
deltaManager.on("disconnect", (reason, error) => {
|
|
1199
1227
|
var _a;
|
|
1200
|
-
(_a = this.
|
|
1228
|
+
(_a = this.noopHeuristic) === null || _a === void 0 ? void 0 : _a.notifyDisconnect();
|
|
1201
1229
|
if (!this.closed) {
|
|
1202
1230
|
this.connectionStateHandler.receivedDisconnectEvent(reason, error);
|
|
1203
1231
|
}
|
|
@@ -1254,7 +1282,9 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1254
1282
|
else if (value === connectionState_1.ConnectionState.CatchingUp) {
|
|
1255
1283
|
// This info is of most interesting while Catching Up.
|
|
1256
1284
|
checkpointSequenceNumber = this.deltaManager.lastKnownSeqNumber;
|
|
1257
|
-
|
|
1285
|
+
// Need to check that we have already loaded and fetched the snapshot.
|
|
1286
|
+
if (this.deltaManager.hasCheckpointSequenceNumber &&
|
|
1287
|
+
this._lifecycleState === "loaded") {
|
|
1258
1288
|
opsBehind = checkpointSequenceNumber - this.deltaManager.lastSequenceNumber;
|
|
1259
1289
|
}
|
|
1260
1290
|
}
|
|
@@ -1341,7 +1371,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1341
1371
|
return -1;
|
|
1342
1372
|
}
|
|
1343
1373
|
this.messageCountAfterDisconnection += 1;
|
|
1344
|
-
(_a = this.
|
|
1374
|
+
(_a = this.noopHeuristic) === null || _a === void 0 ? void 0 : _a.notifyMessageSent();
|
|
1345
1375
|
return this._deltaManager.submit(type, contents, batch, metadata, compression, referenceSequenceNumber);
|
|
1346
1376
|
}
|
|
1347
1377
|
processRemoteMessage(message) {
|
|
@@ -1349,24 +1379,51 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1349
1379
|
this.savedOps.push(message);
|
|
1350
1380
|
}
|
|
1351
1381
|
const local = this.clientId === message.clientId;
|
|
1382
|
+
// Check and report if we're getting messages from a clientId that we previously
|
|
1383
|
+
// flagged should have left, or from a client that's not in the quorum but should be
|
|
1384
|
+
if (message.clientId != null) {
|
|
1385
|
+
const client = this.protocolHandler.quorum.getMember(message.clientId);
|
|
1386
|
+
if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) {
|
|
1387
|
+
// pre-0.58 error message: messageClientIdMissingFromQuorum
|
|
1388
|
+
throw new Error("Remote message's clientId is missing from the quorum");
|
|
1389
|
+
}
|
|
1390
|
+
// Here checking canBeCoalescedByService is used as an approximation of "is benign to process despite being unexpected".
|
|
1391
|
+
// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the
|
|
1392
|
+
// document we don't need to blow up aggressively.
|
|
1393
|
+
if (this.clientsWhoShouldHaveLeft.has(message.clientId) &&
|
|
1394
|
+
!(0, driver_utils_1.canBeCoalescedByService)(message)) {
|
|
1395
|
+
// pre-0.58 error message: messageClientIdShouldHaveLeft
|
|
1396
|
+
throw new Error("Remote message's clientId already should have left");
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1352
1399
|
// Allow the protocol handler to process the message
|
|
1353
1400
|
const result = this.protocolHandler.processMessage(message, local);
|
|
1354
1401
|
// Forward messages to the loaded runtime for processing
|
|
1355
|
-
this.
|
|
1402
|
+
this.runtime.process(message, local);
|
|
1356
1403
|
// Inactive (not in quorum or not writers) clients don't take part in the minimum sequence number calculation.
|
|
1357
1404
|
if (this.activeConnection()) {
|
|
1358
|
-
if (this.
|
|
1405
|
+
if (this.noopHeuristic === undefined) {
|
|
1406
|
+
const serviceConfiguration = this.deltaManager.serviceConfiguration;
|
|
1359
1407
|
// Note that config from first connection will be used for this container's lifetime.
|
|
1360
1408
|
// That means that if relay service changes settings, such changes will impact only newly booted
|
|
1361
1409
|
// clients.
|
|
1362
1410
|
// All existing will continue to use settings they got earlier.
|
|
1363
|
-
(0, common_utils_1.assert)(
|
|
1364
|
-
this.
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1411
|
+
(0, common_utils_1.assert)(serviceConfiguration !== undefined, 0x2e4 /* "there should be service config for active connection" */);
|
|
1412
|
+
this.noopHeuristic = new noopHeuristic_1.NoopHeuristic(serviceConfiguration.noopTimeFrequency, serviceConfiguration.noopCountFrequency);
|
|
1413
|
+
this.noopHeuristic.on("wantsNoop", () => {
|
|
1414
|
+
// On disconnect we notify the heuristic which should prevent it from wanting a noop.
|
|
1415
|
+
// Hitting this assert would imply we lost activeConnection between notifying the heuristic of a processed message and
|
|
1416
|
+
// running the microtask that the heuristic queued in response.
|
|
1417
|
+
(0, common_utils_1.assert)(this.activeConnection(), 0x241 /* "Trying to send noop without active connection" */);
|
|
1418
|
+
this.submitMessage(protocol_definitions_1.MessageType.NoOp);
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
this.noopHeuristic.notifyMessageProcessed(message);
|
|
1422
|
+
// The contract with the protocolHandler is that returning "immediateNoOp" is equivalent to "please immediately accept the proposal I just processed".
|
|
1423
|
+
if (result.immediateNoOp === true) {
|
|
1424
|
+
// ADO:1385: Remove cast and use MessageType once definition changes propagate
|
|
1425
|
+
this.submitMessage(driver_utils_1.MessageType2.Accept);
|
|
1368
1426
|
}
|
|
1369
|
-
this.collabWindowTracker.scheduleSequenceNumberUpdate(message, result.immediateNoOp === true);
|
|
1370
1427
|
}
|
|
1371
1428
|
this.emit("op", message);
|
|
1372
1429
|
}
|
|
@@ -1375,12 +1432,12 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1375
1432
|
}
|
|
1376
1433
|
processSignal(message) {
|
|
1377
1434
|
// No clientId indicates a system signal message.
|
|
1378
|
-
if (
|
|
1435
|
+
if ((0, protocol_1.protocolHandlerShouldProcessSignal)(message)) {
|
|
1379
1436
|
this.protocolHandler.processSignal(message);
|
|
1380
1437
|
}
|
|
1381
1438
|
else {
|
|
1382
1439
|
const local = this.clientId === message.clientId;
|
|
1383
|
-
this.
|
|
1440
|
+
this.runtime.processSignal(message, local);
|
|
1384
1441
|
}
|
|
1385
1442
|
}
|
|
1386
1443
|
/**
|
|
@@ -1413,21 +1470,37 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1413
1470
|
await this.instantiateContext(existing, codeDetails, snapshot);
|
|
1414
1471
|
}
|
|
1415
1472
|
async instantiateContext(existing, codeDetails, snapshot, pendingLocalState) {
|
|
1416
|
-
var _a;
|
|
1417
|
-
(0, common_utils_1.assert)(((_a = this.
|
|
1473
|
+
var _a, _b;
|
|
1474
|
+
(0, common_utils_1.assert)(((_a = this._runtime) === null || _a === void 0 ? void 0 : _a.disposed) !== false, 0x0dd /* "Existing runtime not disposed" */);
|
|
1418
1475
|
// The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
|
|
1419
1476
|
// are set. Global requests will still go directly to the loader
|
|
1420
1477
|
const maybeLoader = this.scope;
|
|
1421
1478
|
const loader = new loader_1.RelativeLoader(this, maybeLoader.ILoader);
|
|
1422
|
-
|
|
1423
|
-
this.
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1479
|
+
const loadCodeResult = await telemetry_utils_1.PerformanceEvent.timedExecAsync(this.subLogger, { eventName: "CodeLoad" }, async () => this.codeLoader.load(codeDetails));
|
|
1480
|
+
this._loadedModule = {
|
|
1481
|
+
module: loadCodeResult.module,
|
|
1482
|
+
// An older interface ICodeLoader could return an IFluidModule which didn't have details.
|
|
1483
|
+
// If we're using one of those older ICodeLoaders, then we fix up the module with the specified details here.
|
|
1484
|
+
// TODO: Determine if this is still a realistic scenario or if this fixup could be removed.
|
|
1485
|
+
details: (_b = loadCodeResult.details) !== null && _b !== void 0 ? _b : codeDetails,
|
|
1486
|
+
};
|
|
1487
|
+
const fluidExport = this._loadedModule.module.fluidExport;
|
|
1488
|
+
const runtimeFactory = fluidExport === null || fluidExport === void 0 ? void 0 : fluidExport.IRuntimeFactory;
|
|
1489
|
+
if (runtimeFactory === undefined) {
|
|
1490
|
+
throw new Error(packageNotFactoryError);
|
|
1428
1491
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1492
|
+
const getSpecifiedCodeDetails = () => {
|
|
1493
|
+
var _a;
|
|
1494
|
+
return ((_a = this.protocolHandler.quorum.get("code")) !== null && _a !== void 0 ? _a : this.protocolHandler.quorum.get("code2"));
|
|
1495
|
+
};
|
|
1496
|
+
const context = new containerContext_1.ContainerContext(this.options, this.scope, snapshot, this._loadedFromVersion, this._deltaManager, this.storageAdapter, this.protocolHandler.quorum, this.protocolHandler.audience, loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (summaryOp, referenceSequenceNumber) => this.submitSummaryMessage(summaryOp, referenceSequenceNumber), (batch, referenceSequenceNumber) => this.submitBatch(batch, referenceSequenceNumber), (message) => this.submitSignal(message), (error) => this.dispose(error), (error) => this.close(error), this.updateDirtyContainerState, this.getAbsoluteUrl, () => { var _a; return (_a = this.resolvedUrl) === null || _a === void 0 ? void 0 : _a.id; }, () => this.clientId, () => this._deltaManager.serviceConfiguration, () => this.attachState, () => this.connected, getSpecifiedCodeDetails, this._deltaManager.clientDetails, existing, this.subLogger, pendingLocalState);
|
|
1497
|
+
this._lifecycleEvents.once("disposed", () => {
|
|
1498
|
+
context.dispose();
|
|
1499
|
+
});
|
|
1500
|
+
this._runtime = await telemetry_utils_1.PerformanceEvent.timedExecAsync(this.subLogger, { eventName: "InstantiateRuntime" }, async () => runtimeFactory.instantiateRuntime(context, existing));
|
|
1501
|
+
this._lifecycleEvents.emit("runtimeInstantiated");
|
|
1502
|
+
this._loadedCodeDetails = codeDetails;
|
|
1503
|
+
this.emit("contextChanged", codeDetails);
|
|
1431
1504
|
}
|
|
1432
1505
|
/**
|
|
1433
1506
|
* Set the connected state of the ContainerContext
|
|
@@ -1437,17 +1510,16 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1437
1510
|
*/
|
|
1438
1511
|
setContextConnectedState(state, readonly) {
|
|
1439
1512
|
var _a;
|
|
1440
|
-
if (((_a = this.
|
|
1513
|
+
if (((_a = this._runtime) === null || _a === void 0 ? void 0 : _a.disposed) === false) {
|
|
1441
1514
|
/**
|
|
1442
1515
|
* We want to lie to the ContainerRuntime when we are in readonly mode to prevent issues with pending
|
|
1443
1516
|
* ops getting through to the DeltaManager.
|
|
1444
1517
|
* The ContainerRuntime's "connected" state simply means it is ok to send ops
|
|
1445
1518
|
* See https://dev.azure.com/fluidframework/internal/_workitems/edit/1246
|
|
1446
1519
|
*/
|
|
1447
|
-
this.
|
|
1520
|
+
this.runtime.setConnectionState(state && !readonly, this.clientId);
|
|
1448
1521
|
}
|
|
1449
1522
|
}
|
|
1450
1523
|
}
|
|
1451
1524
|
exports.Container = Container;
|
|
1452
|
-
Container.version = "^0.1.0";
|
|
1453
1525
|
//# sourceMappingURL=container.js.map
|