@fluidframework/container-loader 2.0.0-internal.5.1.1 → 2.0.0-internal.5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -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 +182 -109
- 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 +186 -113
- 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 +284 -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();
|
|
@@ -304,6 +327,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
304
327
|
static async load(loadProps, createProps) {
|
|
305
328
|
const { version, pendingLocalState, loadMode, resolvedUrl } = loadProps;
|
|
306
329
|
const container = new Container(createProps, loadProps);
|
|
330
|
+
const disableRecordHeapSize = container.mc.config.getBoolean("Fluid.Loader.DisableRecordHeapSize");
|
|
307
331
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "Load" }, async (event) => new Promise((resolve, reject) => {
|
|
308
332
|
const defaultMode = { opsBeforeReturn: "cached" };
|
|
309
333
|
// if we have pendingLocalState, anything we cached is not useful and we shouldn't wait for connection
|
|
@@ -331,7 +355,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
331
355
|
container.close(err);
|
|
332
356
|
onClosed(err);
|
|
333
357
|
});
|
|
334
|
-
}), { start: true, end: true, cancel: "generic" });
|
|
358
|
+
}), { start: true, end: true, cancel: "generic" }, disableRecordHeapSize !== true /* recordHeapSize */);
|
|
335
359
|
}
|
|
336
360
|
/**
|
|
337
361
|
* Create a new container in a detached state.
|
|
@@ -370,14 +394,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
370
394
|
this._lifecycleState === "disposing" ||
|
|
371
395
|
this._lifecycleState === "disposed");
|
|
372
396
|
}
|
|
373
|
-
get
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
get context() {
|
|
377
|
-
if (this._context === undefined) {
|
|
378
|
-
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");
|
|
379
400
|
}
|
|
380
|
-
return this.
|
|
401
|
+
return this._runtime;
|
|
381
402
|
}
|
|
382
403
|
get protocolHandler() {
|
|
383
404
|
if (this._protocolHandler === undefined) {
|
|
@@ -406,15 +427,9 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
406
427
|
*/
|
|
407
428
|
return (_a = this.service) === null || _a === void 0 ? void 0 : _a.resolvedUrl;
|
|
408
429
|
}
|
|
409
|
-
get loadedFromVersion() {
|
|
410
|
-
return this._loadedFromVersion;
|
|
411
|
-
}
|
|
412
430
|
get readOnlyInfo() {
|
|
413
431
|
return this._deltaManager.readOnlyInfo;
|
|
414
432
|
}
|
|
415
|
-
get closeSignal() {
|
|
416
|
-
return this._deltaManager.closeAbortController.signal;
|
|
417
|
-
}
|
|
418
433
|
/**
|
|
419
434
|
* Tracks host requiring read-only mode.
|
|
420
435
|
*/
|
|
@@ -430,13 +445,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
430
445
|
get connected() {
|
|
431
446
|
return this.connectionStateHandler.connectionState === connectionState_1.ConnectionState.Connected;
|
|
432
447
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Service configuration details. If running in offline mode will be undefined otherwise will contain service
|
|
435
|
-
* configuration details returned as part of the initial connection.
|
|
436
|
-
*/
|
|
437
|
-
get serviceConfiguration() {
|
|
438
|
-
return this._deltaManager.serviceConfiguration;
|
|
439
|
-
}
|
|
440
448
|
/**
|
|
441
449
|
* The server provided id of the client.
|
|
442
450
|
* Set once this.connected is true, otherwise undefined
|
|
@@ -444,21 +452,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
444
452
|
get clientId() {
|
|
445
453
|
return this._clientId;
|
|
446
454
|
}
|
|
447
|
-
/**
|
|
448
|
-
* The server provided claims of the client.
|
|
449
|
-
* Set once this.connected is true, otherwise undefined
|
|
450
|
-
*/
|
|
451
|
-
get scopes() {
|
|
452
|
-
return this._deltaManager.connectionManager.scopes;
|
|
453
|
-
}
|
|
454
|
-
get clientDetails() {
|
|
455
|
-
return this._deltaManager.clientDetails;
|
|
456
|
-
}
|
|
457
455
|
get offlineLoadEnabled() {
|
|
458
456
|
var _a, _b;
|
|
459
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;
|
|
460
458
|
// summarizer will not have any pending state we want to save
|
|
461
|
-
return enabled && this.clientDetails.capabilities.interactive;
|
|
459
|
+
return enabled && this.deltaManager.clientDetails.capabilities.interactive;
|
|
462
460
|
}
|
|
463
461
|
/**
|
|
464
462
|
* Get the code details that are currently specified for the container.
|
|
@@ -473,8 +471,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
473
471
|
* loaded.
|
|
474
472
|
*/
|
|
475
473
|
getLoadedCodeDetails() {
|
|
476
|
-
|
|
477
|
-
return (_a = this._context) === null || _a === void 0 ? void 0 : _a.codeDetails;
|
|
474
|
+
return this._loadedCodeDetails;
|
|
478
475
|
}
|
|
479
476
|
/**
|
|
480
477
|
* Retrieves the audience associated with the document
|
|
@@ -495,32 +492,26 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
495
492
|
*/
|
|
496
493
|
async getEntryPoint() {
|
|
497
494
|
var _a, _b;
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
if (this.
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
while (this._context === undefined) {
|
|
505
|
-
await new Promise((resolve, reject) => {
|
|
506
|
-
const contextChangedHandler = () => {
|
|
507
|
-
resolve();
|
|
508
|
-
this.off("disposed", disposedHandler);
|
|
509
|
-
};
|
|
510
|
-
const disposedHandler = (error) => {
|
|
511
|
-
reject(error !== null && error !== void 0 ? error : "The Container is disposed");
|
|
512
|
-
this.off("contextChanged", contextChangedHandler);
|
|
513
|
-
};
|
|
514
|
-
this.once("contextChanged", contextChangedHandler);
|
|
515
|
-
this.once("disposed", disposedHandler);
|
|
516
|
-
});
|
|
517
|
-
// The Promise above should only resolve (vs reject) if the 'contextChanged' event was emitted and that
|
|
518
|
-
// should have set this._context; making sure.
|
|
519
|
-
(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);
|
|
520
500
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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
|
+
});
|
|
524
515
|
}
|
|
525
516
|
/**
|
|
526
517
|
* Retrieves the quorum associated with the document
|
|
@@ -574,6 +565,10 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
574
565
|
}
|
|
575
566
|
finally {
|
|
576
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
|
+
}
|
|
577
572
|
}
|
|
578
573
|
}
|
|
579
574
|
disposeCore(error) {
|
|
@@ -587,7 +582,8 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
587
582
|
// This gives us a chance to know what errors happened on open vs. on fully loaded container.
|
|
588
583
|
this.mc.logger.sendTelemetryEvent({
|
|
589
584
|
eventName: "ContainerDispose",
|
|
590
|
-
|
|
585
|
+
// Only log error if container isn't closed
|
|
586
|
+
category: !this.closed && error !== undefined ? "error" : "generic",
|
|
591
587
|
}, error);
|
|
592
588
|
// ! Progressing from "closed" to "disposing" is not allowed
|
|
593
589
|
if (this._lifecycleState !== "closed") {
|
|
@@ -595,7 +591,8 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
595
591
|
}
|
|
596
592
|
(_a = this._protocolHandler) === null || _a === void 0 ? void 0 : _a.close();
|
|
597
593
|
this.connectionStateHandler.dispose();
|
|
598
|
-
|
|
594
|
+
const maybeError = error !== undefined ? new Error(error.message) : undefined;
|
|
595
|
+
(_b = this._runtime) === null || _b === void 0 ? void 0 : _b.dispose(maybeError);
|
|
599
596
|
this.storageAdapter.dispose();
|
|
600
597
|
// Notify storage about critical errors. They may be due to disconnect between client & server knowledge
|
|
601
598
|
// about file, like file being overwritten in storage, but client having stale local cache.
|
|
@@ -613,6 +610,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
613
610
|
}
|
|
614
611
|
finally {
|
|
615
612
|
this._lifecycleState = "disposed";
|
|
613
|
+
this._lifecycleEvents.emit("disposed");
|
|
616
614
|
}
|
|
617
615
|
}
|
|
618
616
|
closeAndGetPendingLocalState() {
|
|
@@ -627,12 +625,15 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
627
625
|
if (!this.offlineLoadEnabled) {
|
|
628
626
|
throw new container_utils_1.UsageError("Can't get pending local state unless offline load is enabled");
|
|
629
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
|
+
}
|
|
630
631
|
(0, common_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
631
632
|
(0, common_utils_1.assert)(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
632
633
|
(0, common_utils_1.assert)(!!this.baseSnapshot, 0x5d4 /* no base snapshot */);
|
|
633
634
|
(0, common_utils_1.assert)(!!this.baseSnapshotBlobs, 0x5d5 /* no snapshot blobs */);
|
|
634
635
|
const pendingState = {
|
|
635
|
-
pendingRuntimeState: this.
|
|
636
|
+
pendingRuntimeState: this.runtime.getPendingLocalState(),
|
|
636
637
|
baseSnapshot: this.baseSnapshot,
|
|
637
638
|
snapshotBlobs: this.baseSnapshotBlobs,
|
|
638
639
|
savedOps: this.savedOps,
|
|
@@ -648,7 +649,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
648
649
|
}
|
|
649
650
|
serialize() {
|
|
650
651
|
(0, common_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Detached, 0x0d3 /* "Should only be called in detached container" */);
|
|
651
|
-
const appSummary = this.
|
|
652
|
+
const appSummary = this.runtime.createSummary();
|
|
652
653
|
const protocolSummary = this.captureProtocolSummary();
|
|
653
654
|
const combinedSummary = (0, driver_utils_1.combineAppAndProtocolSummary)(appSummary, protocolSummary);
|
|
654
655
|
if (this.detachedBlobStorage && this.detachedBlobStorage.size > 0) {
|
|
@@ -677,7 +678,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
677
678
|
if (!hasAttachmentBlobs) {
|
|
678
679
|
// Get the document state post attach - possibly can just call attach but we need to change the
|
|
679
680
|
// semantics around what the attach means as far as async code goes.
|
|
680
|
-
const appSummary = this.
|
|
681
|
+
const appSummary = this.runtime.createSummary();
|
|
681
682
|
const protocolSummary = this.captureProtocolSummary();
|
|
682
683
|
summary = (0, driver_utils_1.combineAppAndProtocolSummary)(appSummary, protocolSummary);
|
|
683
684
|
// Set the state as attaching as we are starting the process of attaching container.
|
|
@@ -685,6 +686,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
685
686
|
// starting to attach the container to storage.
|
|
686
687
|
// Also, this should only be fired in detached container.
|
|
687
688
|
this._attachState = container_definitions_1.AttachState.Attaching;
|
|
689
|
+
this.runtime.setAttachState(container_definitions_1.AttachState.Attaching);
|
|
688
690
|
this.emit("attaching");
|
|
689
691
|
if (this.offlineLoadEnabled) {
|
|
690
692
|
const snapshot = (0, utils_1.getSnapshotTreeFromSerializedContainer)(summary);
|
|
@@ -699,7 +701,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
699
701
|
(0, common_utils_1.assert)(this.client.details.type !== summarizerClientType &&
|
|
700
702
|
createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
|
|
701
703
|
this.service = await (0, driver_utils_1.runWithRetry)(async () => this.serviceFactory.createContainer(summary, createNewResolvedUrl, this.subLogger, false), "containerAttach", this.mc.logger, {
|
|
702
|
-
cancel: this.
|
|
704
|
+
cancel: this._deltaManager.closeAbortController.signal,
|
|
703
705
|
});
|
|
704
706
|
}
|
|
705
707
|
await this.storageAdapter.connectToService(this.service);
|
|
@@ -721,10 +723,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
721
723
|
}
|
|
722
724
|
}
|
|
723
725
|
// take summary and upload
|
|
724
|
-
const appSummary = this.
|
|
726
|
+
const appSummary = this.runtime.createSummary(redirectTable);
|
|
725
727
|
const protocolSummary = this.captureProtocolSummary();
|
|
726
728
|
summary = (0, driver_utils_1.combineAppAndProtocolSummary)(appSummary, protocolSummary);
|
|
727
729
|
this._attachState = container_definitions_1.AttachState.Attaching;
|
|
730
|
+
this.runtime.setAttachState(container_definitions_1.AttachState.Attaching);
|
|
728
731
|
this.emit("attaching");
|
|
729
732
|
if (this.offlineLoadEnabled) {
|
|
730
733
|
const snapshot = (0, utils_1.getSnapshotTreeFromSerializedContainer)(summary);
|
|
@@ -739,6 +742,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
739
742
|
});
|
|
740
743
|
}
|
|
741
744
|
this._attachState = container_definitions_1.AttachState.Attached;
|
|
745
|
+
this.runtime.setAttachState(container_definitions_1.AttachState.Attached);
|
|
742
746
|
this.emit("attached");
|
|
743
747
|
if (!this.closed) {
|
|
744
748
|
this.resumeInternal({
|
|
@@ -757,7 +761,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
757
761
|
}, { start: true, end: true, cancel: "generic" });
|
|
758
762
|
}
|
|
759
763
|
async request(path) {
|
|
760
|
-
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" });
|
|
761
765
|
}
|
|
762
766
|
setAutoReconnectInternal(mode) {
|
|
763
767
|
const currentMode = this._deltaManager.connectionManager.reconnectMode;
|
|
@@ -823,13 +827,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
823
827
|
// Ensure connection to web socket
|
|
824
828
|
this.connectToDeltaStream(args);
|
|
825
829
|
}
|
|
826
|
-
async getAbsoluteUrl(relativeUrl) {
|
|
827
|
-
var _a;
|
|
828
|
-
if (this.resolvedUrl === undefined) {
|
|
829
|
-
return undefined;
|
|
830
|
-
}
|
|
831
|
-
return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, (0, contracts_1.getPackageName)((_a = this._context) === null || _a === void 0 ? void 0 : _a.codeDetails));
|
|
832
|
-
}
|
|
833
830
|
async proposeCodeDetails(codeDetails) {
|
|
834
831
|
if (!(0, container_definitions_1.isFluidCodeDetails)(codeDetails)) {
|
|
835
832
|
throw new Error("Provided codeDetails are not IFluidCodeDetails");
|
|
@@ -851,7 +848,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
851
848
|
this.deltaManager.inbound.pause(),
|
|
852
849
|
this.deltaManager.inboundSignal.pause(),
|
|
853
850
|
]);
|
|
854
|
-
if ((await this.
|
|
851
|
+
if ((await this.satisfies(codeDetails)) === true) {
|
|
855
852
|
this.deltaManager.inbound.resume();
|
|
856
853
|
this.deltaManager.inboundSignal.resume();
|
|
857
854
|
return;
|
|
@@ -860,6 +857,38 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
860
857
|
const error = new container_utils_1.GenericError("Existing context does not satisfy incoming proposal");
|
|
861
858
|
this.close(error);
|
|
862
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
|
+
}
|
|
863
892
|
async getVersion(version) {
|
|
864
893
|
const versions = await this.storageAdapter.getVersions(version, 1);
|
|
865
894
|
return versions[0];
|
|
@@ -877,7 +906,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
877
906
|
* @param specifiedVersion - Version SHA to load snapshot. If not specified, will fetch the latest snapshot.
|
|
878
907
|
*/
|
|
879
908
|
async load(specifiedVersion, loadMode, resolvedUrl, pendingLocalState) {
|
|
880
|
-
var _a;
|
|
909
|
+
var _a, _b, _c;
|
|
881
910
|
this.service = await this.serviceFactory.createDocumentService(resolvedUrl, this.subLogger, this.client.details.type === summarizerClientType);
|
|
882
911
|
// Ideally we always connect as "read" by default.
|
|
883
912
|
// Currently that works with SPO & r11s, because we get "write" connection when connecting to non-existing file.
|
|
@@ -921,7 +950,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
921
950
|
if (this.offlineLoadEnabled) {
|
|
922
951
|
this.baseSnapshot = snapshot;
|
|
923
952
|
// Save contents of snapshot now, otherwise closeAndGetPendingLocalState() must be async
|
|
924
|
-
this.baseSnapshotBlobs = await (0, containerStorageAdapter_1.getBlobContentsFromTree)(snapshot, this.
|
|
953
|
+
this.baseSnapshotBlobs = await (0, containerStorageAdapter_1.getBlobContentsFromTree)(snapshot, this.storageAdapter);
|
|
925
954
|
}
|
|
926
955
|
}
|
|
927
956
|
const attributes = await this.getDocumentAttributes(this.storageAdapter, snapshot);
|
|
@@ -957,7 +986,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
957
986
|
for (const message of pendingLocalState.savedOps) {
|
|
958
987
|
this.processRemoteMessage(message);
|
|
959
988
|
// allow runtime to apply stashed ops at this op's sequence number
|
|
960
|
-
await this.
|
|
989
|
+
await ((_c = (_b = this.runtime).notifyOpReplay) === null || _c === void 0 ? void 0 : _c.call(_b, message));
|
|
961
990
|
}
|
|
962
991
|
pendingLocalState.savedOps = [];
|
|
963
992
|
// now set clientId to stashed clientId so live ops are correctly processed as local
|
|
@@ -1196,7 +1225,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1196
1225
|
});
|
|
1197
1226
|
deltaManager.on("disconnect", (reason, error) => {
|
|
1198
1227
|
var _a;
|
|
1199
|
-
(_a = this.
|
|
1228
|
+
(_a = this.noopHeuristic) === null || _a === void 0 ? void 0 : _a.notifyDisconnect();
|
|
1200
1229
|
if (!this.closed) {
|
|
1201
1230
|
this.connectionStateHandler.receivedDisconnectEvent(reason, error);
|
|
1202
1231
|
}
|
|
@@ -1253,7 +1282,9 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1253
1282
|
else if (value === connectionState_1.ConnectionState.CatchingUp) {
|
|
1254
1283
|
// This info is of most interesting while Catching Up.
|
|
1255
1284
|
checkpointSequenceNumber = this.deltaManager.lastKnownSeqNumber;
|
|
1256
|
-
|
|
1285
|
+
// Need to check that we have already loaded and fetched the snapshot.
|
|
1286
|
+
if (this.deltaManager.hasCheckpointSequenceNumber &&
|
|
1287
|
+
this._lifecycleState === "loaded") {
|
|
1257
1288
|
opsBehind = checkpointSequenceNumber - this.deltaManager.lastSequenceNumber;
|
|
1258
1289
|
}
|
|
1259
1290
|
}
|
|
@@ -1340,7 +1371,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1340
1371
|
return -1;
|
|
1341
1372
|
}
|
|
1342
1373
|
this.messageCountAfterDisconnection += 1;
|
|
1343
|
-
(_a = this.
|
|
1374
|
+
(_a = this.noopHeuristic) === null || _a === void 0 ? void 0 : _a.notifyMessageSent();
|
|
1344
1375
|
return this._deltaManager.submit(type, contents, batch, metadata, compression, referenceSequenceNumber);
|
|
1345
1376
|
}
|
|
1346
1377
|
processRemoteMessage(message) {
|
|
@@ -1348,24 +1379,51 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1348
1379
|
this.savedOps.push(message);
|
|
1349
1380
|
}
|
|
1350
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
|
+
}
|
|
1351
1399
|
// Allow the protocol handler to process the message
|
|
1352
1400
|
const result = this.protocolHandler.processMessage(message, local);
|
|
1353
1401
|
// Forward messages to the loaded runtime for processing
|
|
1354
|
-
this.
|
|
1402
|
+
this.runtime.process(message, local);
|
|
1355
1403
|
// Inactive (not in quorum or not writers) clients don't take part in the minimum sequence number calculation.
|
|
1356
1404
|
if (this.activeConnection()) {
|
|
1357
|
-
if (this.
|
|
1405
|
+
if (this.noopHeuristic === undefined) {
|
|
1406
|
+
const serviceConfiguration = this.deltaManager.serviceConfiguration;
|
|
1358
1407
|
// Note that config from first connection will be used for this container's lifetime.
|
|
1359
1408
|
// That means that if relay service changes settings, such changes will impact only newly booted
|
|
1360
1409
|
// clients.
|
|
1361
1410
|
// All existing will continue to use settings they got earlier.
|
|
1362
|
-
(0, common_utils_1.assert)(
|
|
1363
|
-
this.
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
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);
|
|
1367
1426
|
}
|
|
1368
|
-
this.collabWindowTracker.scheduleSequenceNumberUpdate(message, result.immediateNoOp === true);
|
|
1369
1427
|
}
|
|
1370
1428
|
this.emit("op", message);
|
|
1371
1429
|
}
|
|
@@ -1374,12 +1432,12 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1374
1432
|
}
|
|
1375
1433
|
processSignal(message) {
|
|
1376
1434
|
// No clientId indicates a system signal message.
|
|
1377
|
-
if (
|
|
1435
|
+
if ((0, protocol_1.protocolHandlerShouldProcessSignal)(message)) {
|
|
1378
1436
|
this.protocolHandler.processSignal(message);
|
|
1379
1437
|
}
|
|
1380
1438
|
else {
|
|
1381
1439
|
const local = this.clientId === message.clientId;
|
|
1382
|
-
this.
|
|
1440
|
+
this.runtime.processSignal(message, local);
|
|
1383
1441
|
}
|
|
1384
1442
|
}
|
|
1385
1443
|
/**
|
|
@@ -1412,21 +1470,37 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1412
1470
|
await this.instantiateContext(existing, codeDetails, snapshot);
|
|
1413
1471
|
}
|
|
1414
1472
|
async instantiateContext(existing, codeDetails, snapshot, pendingLocalState) {
|
|
1415
|
-
var _a;
|
|
1416
|
-
(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" */);
|
|
1417
1475
|
// The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
|
|
1418
1476
|
// are set. Global requests will still go directly to the loader
|
|
1419
1477
|
const maybeLoader = this.scope;
|
|
1420
1478
|
const loader = new loader_1.RelativeLoader(this, maybeLoader.ILoader);
|
|
1421
|
-
|
|
1422
|
-
this.
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
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);
|
|
1427
1491
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
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);
|
|
1430
1504
|
}
|
|
1431
1505
|
/**
|
|
1432
1506
|
* Set the connected state of the ContainerContext
|
|
@@ -1436,17 +1510,16 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1436
1510
|
*/
|
|
1437
1511
|
setContextConnectedState(state, readonly) {
|
|
1438
1512
|
var _a;
|
|
1439
|
-
if (((_a = this.
|
|
1513
|
+
if (((_a = this._runtime) === null || _a === void 0 ? void 0 : _a.disposed) === false) {
|
|
1440
1514
|
/**
|
|
1441
1515
|
* We want to lie to the ContainerRuntime when we are in readonly mode to prevent issues with pending
|
|
1442
1516
|
* ops getting through to the DeltaManager.
|
|
1443
1517
|
* The ContainerRuntime's "connected" state simply means it is ok to send ops
|
|
1444
1518
|
* See https://dev.azure.com/fluidframework/internal/_workitems/edit/1246
|
|
1445
1519
|
*/
|
|
1446
|
-
this.
|
|
1520
|
+
this.runtime.setConnectionState(state && !readonly, this.clientId);
|
|
1447
1521
|
}
|
|
1448
1522
|
}
|
|
1449
1523
|
}
|
|
1450
1524
|
exports.Container = Container;
|
|
1451
|
-
Container.version = "^0.1.0";
|
|
1452
1525
|
//# sourceMappingURL=container.js.map
|