@fluidframework/container-loader 2.20.0 → 2.21.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 +4 -0
- package/dist/connectionManager.js +7 -7
- package/dist/connectionManager.js.map +1 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +18 -14
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +6 -1
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +7 -0
- package/dist/containerContext.js.map +1 -1
- package/dist/debugLogger.js +1 -1
- package/dist/debugLogger.js.map +1 -1
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +2 -2
- package/dist/deltaQueue.js.map +1 -1
- package/dist/layerCompatState.d.ts +19 -0
- package/dist/layerCompatState.d.ts.map +1 -0
- package/dist/layerCompatState.js +64 -0
- package/dist/layerCompatState.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/quorum.d.ts +0 -10
- package/dist/protocol/quorum.d.ts.map +1 -1
- package/dist/protocol/quorum.js +0 -14
- package/dist/protocol/quorum.js.map +1 -1
- package/lib/connectionManager.js +8 -8
- package/lib/connectionManager.js.map +1 -1
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +19 -15
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +6 -1
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +7 -0
- package/lib/containerContext.js.map +1 -1
- package/lib/debugLogger.js +2 -2
- package/lib/debugLogger.js.map +1 -1
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +3 -3
- package/lib/deltaQueue.js.map +1 -1
- package/lib/layerCompatState.d.ts +19 -0
- package/lib/layerCompatState.d.ts.map +1 -0
- package/lib/layerCompatState.js +60 -0
- package/lib/layerCompatState.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/quorum.d.ts +0 -10
- package/lib/protocol/quorum.d.ts.map +1 -1
- package/lib/protocol/quorum.js +0 -14
- package/lib/protocol/quorum.js.map +1 -1
- package/package.json +14 -14
- package/src/connectionManager.ts +8 -8
- package/src/container.ts +28 -15
- package/src/containerContext.ts +14 -1
- package/src/debugLogger.ts +2 -2
- package/src/deltaQueue.ts +3 -3
- package/src/layerCompatState.ts +75 -0
- package/src/packageVersion.ts +1 -1
- package/src/protocol/quorum.ts +0 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-loader",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "Fluid container loader",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -119,13 +119,13 @@
|
|
|
119
119
|
"temp-directory": "nyc/.nyc_output"
|
|
120
120
|
},
|
|
121
121
|
"dependencies": {
|
|
122
|
-
"@fluid-internal/client-utils": "~2.
|
|
123
|
-
"@fluidframework/container-definitions": "~2.
|
|
124
|
-
"@fluidframework/core-interfaces": "~2.
|
|
125
|
-
"@fluidframework/core-utils": "~2.
|
|
126
|
-
"@fluidframework/driver-definitions": "~2.
|
|
127
|
-
"@fluidframework/driver-utils": "~2.
|
|
128
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
122
|
+
"@fluid-internal/client-utils": "~2.21.0",
|
|
123
|
+
"@fluidframework/container-definitions": "~2.21.0",
|
|
124
|
+
"@fluidframework/core-interfaces": "~2.21.0",
|
|
125
|
+
"@fluidframework/core-utils": "~2.21.0",
|
|
126
|
+
"@fluidframework/driver-definitions": "~2.21.0",
|
|
127
|
+
"@fluidframework/driver-utils": "~2.21.0",
|
|
128
|
+
"@fluidframework/telemetry-utils": "~2.21.0",
|
|
129
129
|
"@types/events_pkg": "npm:@types/events@^3.0.0",
|
|
130
130
|
"@ungap/structured-clone": "^1.2.0",
|
|
131
131
|
"debug": "^4.3.4",
|
|
@@ -136,14 +136,14 @@
|
|
|
136
136
|
"devDependencies": {
|
|
137
137
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
138
138
|
"@biomejs/biome": "~1.9.3",
|
|
139
|
-
"@fluid-internal/client-utils": "~2.
|
|
140
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
141
|
-
"@fluid-private/test-loader-utils": "~2.
|
|
139
|
+
"@fluid-internal/client-utils": "~2.21.0",
|
|
140
|
+
"@fluid-internal/mocha-test-setup": "~2.21.0",
|
|
141
|
+
"@fluid-private/test-loader-utils": "~2.21.0",
|
|
142
142
|
"@fluid-tools/build-cli": "^0.51.0",
|
|
143
143
|
"@fluidframework/build-common": "^2.0.3",
|
|
144
144
|
"@fluidframework/build-tools": "^0.51.0",
|
|
145
|
-
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.
|
|
146
|
-
"@fluidframework/eslint-config-fluid": "^5.
|
|
145
|
+
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.20.0",
|
|
146
|
+
"@fluidframework/eslint-config-fluid": "^5.7.3",
|
|
147
147
|
"@microsoft/api-extractor": "7.47.8",
|
|
148
148
|
"@types/debug": "^4.1.5",
|
|
149
149
|
"@types/double-ended-queue": "^2.1.0",
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
"ci:build:api-reports:current": "api-extractor run --config api-extractor/api-extractor.current.json",
|
|
200
200
|
"ci:build:api-reports:legacy": "api-extractor run --config api-extractor/api-extractor.legacy.json",
|
|
201
201
|
"ci:build:docs": "api-extractor run",
|
|
202
|
-
"clean": "rimraf --glob dist lib
|
|
202
|
+
"clean": "rimraf --glob dist lib {alpha,beta,internal,legacy}.d.ts \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
|
|
203
203
|
"eslint": "eslint --format stylish src",
|
|
204
204
|
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
205
205
|
"format": "npm run format:biome",
|
package/src/connectionManager.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { TypedEventEmitter,
|
|
6
|
+
import { TypedEventEmitter, performanceNow } from "@fluid-internal/client-utils";
|
|
7
7
|
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
8
8
|
import { IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
|
|
9
9
|
import {
|
|
@@ -583,7 +583,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
583
583
|
|
|
584
584
|
let delayMs = InitialReconnectDelayInMs;
|
|
585
585
|
let connectRepeatCount = 0;
|
|
586
|
-
const connectStartTime =
|
|
586
|
+
const connectStartTime = performanceNow();
|
|
587
587
|
let lastError: unknown;
|
|
588
588
|
|
|
589
589
|
const abortController = new AbortController();
|
|
@@ -604,7 +604,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
604
604
|
this.logger.sendTelemetryEvent({
|
|
605
605
|
eventName: "ConnectionAttemptCancelled",
|
|
606
606
|
attempts: connectRepeatCount,
|
|
607
|
-
duration: formatTick(
|
|
607
|
+
duration: formatTick(performanceNow() - connectStartTime),
|
|
608
608
|
connectionEstablished: false,
|
|
609
609
|
});
|
|
610
610
|
return;
|
|
@@ -675,7 +675,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
675
675
|
attempts: connectRepeatCount,
|
|
676
676
|
delay: delayMs, // milliseconds
|
|
677
677
|
eventName: "DeltaConnectionFailureToConnect",
|
|
678
|
-
duration: formatTick(
|
|
678
|
+
duration: formatTick(performanceNow() - connectStartTime),
|
|
679
679
|
},
|
|
680
680
|
origError,
|
|
681
681
|
);
|
|
@@ -688,7 +688,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
688
688
|
return;
|
|
689
689
|
}
|
|
690
690
|
|
|
691
|
-
const waitStartTime =
|
|
691
|
+
const waitStartTime = performanceNow();
|
|
692
692
|
const retryDelayFromError = getRetryDelayFromError(origError);
|
|
693
693
|
// If the error told us to wait or browser signals us that we are offline, then calculate the time we
|
|
694
694
|
// want to wait for before retrying. then we wait for that time. If the error didn't tell us to wait,
|
|
@@ -714,7 +714,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
714
714
|
await waitForOnline();
|
|
715
715
|
this.logger.sendPerformanceEvent({
|
|
716
716
|
eventName: "WaitBetweenConnectionAttempts",
|
|
717
|
-
duration:
|
|
717
|
+
duration: performanceNow() - waitStartTime,
|
|
718
718
|
details: JSON.stringify({
|
|
719
719
|
retryDelayFromError,
|
|
720
720
|
delayMs,
|
|
@@ -730,7 +730,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
730
730
|
{
|
|
731
731
|
eventName: "MultipleDeltaConnectionFailures",
|
|
732
732
|
attempts: connectRepeatCount,
|
|
733
|
-
duration: formatTick(
|
|
733
|
+
duration: formatTick(performanceNow() - connectStartTime),
|
|
734
734
|
},
|
|
735
735
|
lastError,
|
|
736
736
|
);
|
|
@@ -742,7 +742,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
742
742
|
this.logger.sendTelemetryEvent({
|
|
743
743
|
eventName: "ConnectionAttemptCancelled",
|
|
744
744
|
attempts: connectRepeatCount,
|
|
745
|
-
duration: formatTick(
|
|
745
|
+
duration: formatTick(performanceNow() - connectStartTime),
|
|
746
746
|
connectionEstablished: true,
|
|
747
747
|
});
|
|
748
748
|
return;
|
package/src/container.ts
CHANGED
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
/* eslint-disable unicorn/consistent-function-scoping */
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
TypedEventEmitter,
|
|
10
|
+
performanceNow,
|
|
11
|
+
type ILayerCompatDetails,
|
|
12
|
+
} from "@fluid-internal/client-utils";
|
|
9
13
|
import {
|
|
10
14
|
AttachState,
|
|
11
15
|
IAudience,
|
|
@@ -123,6 +127,7 @@ import {
|
|
|
123
127
|
getPackageName,
|
|
124
128
|
} from "./contracts.js";
|
|
125
129
|
import { DeltaManager, IConnectionArgs } from "./deltaManager.js";
|
|
130
|
+
import { validateRuntimeCompatibility } from "./layerCompatState.js";
|
|
126
131
|
// eslint-disable-next-line import/no-deprecated
|
|
127
132
|
import { IDetachedBlobStorage, ILoaderOptions, RelativeLoader } from "./loader.js";
|
|
128
133
|
import {
|
|
@@ -617,7 +622,7 @@ export class Container
|
|
|
617
622
|
private readonly clientsWhoShouldHaveLeft = new Set<string>();
|
|
618
623
|
private _containerMetadata: Readonly<Record<string, string>> = {};
|
|
619
624
|
|
|
620
|
-
private setAutoReconnectTime =
|
|
625
|
+
private setAutoReconnectTime = performanceNow();
|
|
621
626
|
|
|
622
627
|
private noopHeuristic: NoopHeuristic | undefined;
|
|
623
628
|
|
|
@@ -803,7 +808,7 @@ export class Container
|
|
|
803
808
|
protocolHandlerBuilder,
|
|
804
809
|
} = createProps;
|
|
805
810
|
|
|
806
|
-
this.connectionTransitionTimes[ConnectionState.Disconnected] =
|
|
811
|
+
this.connectionTransitionTimes[ConnectionState.Disconnected] = performanceNow();
|
|
807
812
|
const pendingLocalState = loadProps?.pendingLocalState;
|
|
808
813
|
|
|
809
814
|
this._canReconnect = canReconnect ?? true;
|
|
@@ -891,7 +896,7 @@ export class Container
|
|
|
891
896
|
: this.deltaManager?.lastMessage?.clientId,
|
|
892
897
|
dmLastMsgClientSeq: () => this.deltaManager?.lastMessage?.clientSequenceNumber,
|
|
893
898
|
connectionStateDuration: () =>
|
|
894
|
-
|
|
899
|
+
performanceNow() - this.connectionTransitionTimes[this.connectionState],
|
|
895
900
|
},
|
|
896
901
|
},
|
|
897
902
|
});
|
|
@@ -935,7 +940,7 @@ export class Container
|
|
|
935
940
|
mode,
|
|
936
941
|
category: this._lifecycleState === "loading" ? "generic" : category,
|
|
937
942
|
duration:
|
|
938
|
-
|
|
943
|
+
performanceNow() - this.connectionTransitionTimes[ConnectionState.CatchingUp],
|
|
939
944
|
...(details === undefined ? {} : { details: JSON.stringify(details) }),
|
|
940
945
|
});
|
|
941
946
|
|
|
@@ -1031,10 +1036,10 @@ export class Container
|
|
|
1031
1036
|
document.addEventListener !== null;
|
|
1032
1037
|
// keep track of last time page was visible for telemetry (on interactive clients only)
|
|
1033
1038
|
if (isDomAvailable && interactive) {
|
|
1034
|
-
this.lastVisible = document.hidden ?
|
|
1039
|
+
this.lastVisible = document.hidden ? performanceNow() : undefined;
|
|
1035
1040
|
this.visibilityEventHandler = (): void => {
|
|
1036
1041
|
if (document.hidden) {
|
|
1037
|
-
this.lastVisible =
|
|
1042
|
+
this.lastVisible = performanceNow();
|
|
1038
1043
|
} else {
|
|
1039
1044
|
// settimeout so this will hopefully fire after disconnect event if being hidden caused it
|
|
1040
1045
|
setTimeout(() => {
|
|
@@ -1411,7 +1416,7 @@ export class Container
|
|
|
1411
1416
|
return;
|
|
1412
1417
|
}
|
|
1413
1418
|
|
|
1414
|
-
const now =
|
|
1419
|
+
const now = performanceNow();
|
|
1415
1420
|
const duration = now - this.setAutoReconnectTime;
|
|
1416
1421
|
this.setAutoReconnectTime = now;
|
|
1417
1422
|
|
|
@@ -1629,7 +1634,7 @@ export class Container
|
|
|
1629
1634
|
dmLastProcessedSeqNumber: number;
|
|
1630
1635
|
dmLastKnownSeqNumber: number;
|
|
1631
1636
|
}> {
|
|
1632
|
-
const timings: Record<string, number> = { phase1:
|
|
1637
|
+
const timings: Record<string, number> = { phase1: performanceNow() };
|
|
1633
1638
|
this.service = await this.createDocumentService(async () =>
|
|
1634
1639
|
this.serviceFactory.createDocumentService(
|
|
1635
1640
|
resolvedUrl,
|
|
@@ -1662,7 +1667,7 @@ export class Container
|
|
|
1662
1667
|
state: AttachState.Attached,
|
|
1663
1668
|
};
|
|
1664
1669
|
|
|
1665
|
-
timings.phase2 =
|
|
1670
|
+
timings.phase2 = performanceNow();
|
|
1666
1671
|
|
|
1667
1672
|
// Fetch specified snapshot.
|
|
1668
1673
|
const { baseSnapshot, version } =
|
|
@@ -1722,7 +1727,7 @@ export class Container
|
|
|
1722
1727
|
this.protocolHandler.audience.setCurrentClientId(pendingLocalState?.clientId);
|
|
1723
1728
|
}
|
|
1724
1729
|
|
|
1725
|
-
timings.phase3 =
|
|
1730
|
+
timings.phase3 = performanceNow();
|
|
1726
1731
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
1727
1732
|
await this.instantiateRuntime(
|
|
1728
1733
|
codeDetails,
|
|
@@ -1785,7 +1790,7 @@ export class Container
|
|
|
1785
1790
|
throw new Error("Container was closed while load()");
|
|
1786
1791
|
}
|
|
1787
1792
|
|
|
1788
|
-
timings.end =
|
|
1793
|
+
timings.end = performanceNow();
|
|
1789
1794
|
this.subLogger.sendTelemetryEvent(
|
|
1790
1795
|
{
|
|
1791
1796
|
eventName: "LoadStagesTimings",
|
|
@@ -2152,7 +2157,7 @@ export class Container
|
|
|
2152
2157
|
reason?: IConnectionStateChangeReason,
|
|
2153
2158
|
): void {
|
|
2154
2159
|
// Log actual event
|
|
2155
|
-
const time =
|
|
2160
|
+
const time = performanceNow();
|
|
2156
2161
|
this.connectionTransitionTimes[value] = time;
|
|
2157
2162
|
const duration = time - this.connectionTransitionTimes[oldState];
|
|
2158
2163
|
|
|
@@ -2191,7 +2196,7 @@ export class Container
|
|
|
2191
2196
|
opsBehind,
|
|
2192
2197
|
online: OnlineStatus[isOnline()],
|
|
2193
2198
|
lastVisible:
|
|
2194
|
-
this.lastVisible === undefined ? undefined :
|
|
2199
|
+
this.lastVisible === undefined ? undefined : performanceNow() - this.lastVisible,
|
|
2195
2200
|
checkpointSequenceNumber,
|
|
2196
2201
|
quorumSize: this._protocolHandler?.quorum.getMembers().size,
|
|
2197
2202
|
audienceSize: this._protocolHandler?.audience.getMembers().size,
|
|
@@ -2461,11 +2466,19 @@ export class Container
|
|
|
2461
2466
|
snapshot,
|
|
2462
2467
|
);
|
|
2463
2468
|
|
|
2464
|
-
|
|
2469
|
+
const runtime = await PerformanceEvent.timedExecAsync(
|
|
2465
2470
|
this.subLogger,
|
|
2466
2471
|
{ eventName: "InstantiateRuntime" },
|
|
2467
2472
|
async () => runtimeFactory.instantiateRuntime(context, existing),
|
|
2468
2473
|
);
|
|
2474
|
+
|
|
2475
|
+
const maybeRuntimeCompatDetails = runtime as FluidObject<ILayerCompatDetails>;
|
|
2476
|
+
validateRuntimeCompatibility(maybeRuntimeCompatDetails.ILayerCompatDetails, (error) =>
|
|
2477
|
+
this.dispose(error),
|
|
2478
|
+
);
|
|
2479
|
+
|
|
2480
|
+
this._runtime = runtime;
|
|
2481
|
+
|
|
2469
2482
|
this._lifecycleEvents.emit("runtimeInstantiated");
|
|
2470
2483
|
|
|
2471
2484
|
this._loadedCodeDetails = codeDetails;
|
package/src/containerContext.ts
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import type {
|
|
7
|
+
ILayerCompatDetails,
|
|
8
|
+
IProvideLayerCompatDetails,
|
|
9
|
+
} from "@fluid-internal/client-utils";
|
|
6
10
|
import {
|
|
7
11
|
AttachState,
|
|
8
12
|
IAudience,
|
|
@@ -30,10 +34,15 @@ import {
|
|
|
30
34
|
} from "@fluidframework/driver-definitions/internal";
|
|
31
35
|
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
|
|
32
36
|
|
|
37
|
+
import { LoaderCompatDetails } from "./layerCompatState.js";
|
|
38
|
+
|
|
33
39
|
/**
|
|
34
40
|
* {@inheritDoc @fluidframework/container-definitions#IContainerContext}
|
|
35
41
|
*/
|
|
36
|
-
export class ContainerContext implements IContainerContext {
|
|
42
|
+
export class ContainerContext implements IContainerContext, IProvideLayerCompatDetails {
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated - This has been replaced by ILayerCompatDetails.
|
|
45
|
+
*/
|
|
37
46
|
public readonly supportedFeatures: ReadonlyMap<string, unknown> = new Map([
|
|
38
47
|
/**
|
|
39
48
|
* This version of the loader accepts `referenceSequenceNumber`, provided by the container runtime,
|
|
@@ -62,6 +71,10 @@ export class ContainerContext implements IContainerContext {
|
|
|
62
71
|
return this._getConnected();
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
public get ILayerCompatDetails(): ILayerCompatDetails {
|
|
75
|
+
return LoaderCompatDetails;
|
|
76
|
+
}
|
|
77
|
+
|
|
65
78
|
constructor(
|
|
66
79
|
public readonly options: ILoaderOptions,
|
|
67
80
|
public readonly scope: FluidObject,
|
package/src/debugLogger.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { performanceNow } from "@fluid-internal/client-utils";
|
|
7
7
|
import {
|
|
8
8
|
ITelemetryBaseEvent,
|
|
9
9
|
ITelemetryBaseLogger,
|
|
@@ -88,7 +88,7 @@ export class DebugLogger implements ITelemetryBaseLogger {
|
|
|
88
88
|
newEvent.eventName = undefined;
|
|
89
89
|
|
|
90
90
|
let tick = "";
|
|
91
|
-
tick = `tick=${formatTick(
|
|
91
|
+
tick = `tick=${formatTick(performanceNow())}`;
|
|
92
92
|
|
|
93
93
|
// Extract stack to put it last, but also to avoid escaping '\n' in it by JSON.stringify below
|
|
94
94
|
const stack = newEvent.stack ?? "";
|
package/src/deltaQueue.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { TypedEventEmitter,
|
|
6
|
+
import { TypedEventEmitter, performanceNow } from "@fluid-internal/client-utils";
|
|
7
7
|
import {
|
|
8
8
|
IDeltaQueue,
|
|
9
9
|
IDeltaQueueEvents,
|
|
@@ -153,7 +153,7 @@ export class DeltaQueue<T>
|
|
|
153
153
|
count: number;
|
|
154
154
|
duration: number;
|
|
155
155
|
} {
|
|
156
|
-
const start =
|
|
156
|
+
const start = performanceNow();
|
|
157
157
|
let count = 0;
|
|
158
158
|
|
|
159
159
|
// For grouping to work we must process all local messages immediately and in the single turn.
|
|
@@ -169,7 +169,7 @@ export class DeltaQueue<T>
|
|
|
169
169
|
this.emit("op", next);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
const duration =
|
|
172
|
+
const duration = performanceNow() - start;
|
|
173
173
|
if (this.q.length === 0) {
|
|
174
174
|
this.emit("idle", count, duration);
|
|
175
175
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
checkLayerCompatibility,
|
|
8
|
+
type ILayerCompatDetails,
|
|
9
|
+
type ILayerCompatSupportRequirements,
|
|
10
|
+
} from "@fluid-internal/client-utils";
|
|
11
|
+
import type { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
12
|
+
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
13
|
+
|
|
14
|
+
import { pkgVersion } from "./packageVersion.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Loader's compatibility details that is exposed to the Runtime layer.
|
|
18
|
+
*/
|
|
19
|
+
export const LoaderCompatDetails: ILayerCompatDetails = {
|
|
20
|
+
/**
|
|
21
|
+
* The package version of the Loader layer.
|
|
22
|
+
*/
|
|
23
|
+
pkgVersion,
|
|
24
|
+
/**
|
|
25
|
+
* The current generation of the Loader layer.
|
|
26
|
+
*/
|
|
27
|
+
generation: 1,
|
|
28
|
+
/**
|
|
29
|
+
* The features supported by the Loader layer across the Loader / Runtime boundary.
|
|
30
|
+
*/
|
|
31
|
+
supportedFeatures: new Set<string>(),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The requirements that the Runtime layer must meet to be compatible with this Loader.
|
|
36
|
+
*/
|
|
37
|
+
export const RuntimeSupportRequirements: ILayerCompatSupportRequirements = {
|
|
38
|
+
/**
|
|
39
|
+
* Minimum generation that Runtime must be at to be compatible with Loader. Note that 0 is used here for
|
|
40
|
+
* Runtime layers before the introduction of the layer compatibility enforcement.
|
|
41
|
+
*/
|
|
42
|
+
minSupportedGeneration: 0,
|
|
43
|
+
/**
|
|
44
|
+
* The features that the Runtime must support to be compatible with Loader.
|
|
45
|
+
*/
|
|
46
|
+
requiredFeatures: [],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validates that the Runtime layer is compatible with the Loader.
|
|
51
|
+
*/
|
|
52
|
+
export function validateRuntimeCompatibility(
|
|
53
|
+
maybeRuntimeCompatDetails: ILayerCompatDetails | undefined,
|
|
54
|
+
disposeFn: (error?: ICriticalContainerError) => void,
|
|
55
|
+
): void {
|
|
56
|
+
const layerCheckResult = checkLayerCompatibility(
|
|
57
|
+
RuntimeSupportRequirements,
|
|
58
|
+
maybeRuntimeCompatDetails,
|
|
59
|
+
);
|
|
60
|
+
if (!layerCheckResult.isCompatible) {
|
|
61
|
+
const error = new UsageError("Loader is not compatible with Runtime", {
|
|
62
|
+
errorDetails: JSON.stringify({
|
|
63
|
+
loaderVersion: LoaderCompatDetails.pkgVersion,
|
|
64
|
+
runtimeVersion: maybeRuntimeCompatDetails?.pkgVersion,
|
|
65
|
+
loaderGeneration: LoaderCompatDetails.generation,
|
|
66
|
+
runtimeGeneration: maybeRuntimeCompatDetails?.generation,
|
|
67
|
+
minSupportedGeneration: RuntimeSupportRequirements.minSupportedGeneration,
|
|
68
|
+
isGenerationCompatible: layerCheckResult.isGenerationCompatible,
|
|
69
|
+
unsupportedFeatures: layerCheckResult.unsupportedFeatures,
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
disposeFn(error);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
package/src/packageVersion.ts
CHANGED
package/src/protocol/quorum.ts
CHANGED
|
@@ -221,14 +221,6 @@ export class QuorumProposals
|
|
|
221
221
|
return this.values.get(key)?.value;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
/**
|
|
225
|
-
* Returns additional data about the approved consensus value
|
|
226
|
-
* @deprecated Removed in recent protocol-definitions. Use get() instead.
|
|
227
|
-
*/
|
|
228
|
-
public getApprovalData(key: string): ICommittedProposal | undefined {
|
|
229
|
-
return this.values.get(key);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
224
|
/**
|
|
233
225
|
* Proposes a new value. Returns a promise that will either:
|
|
234
226
|
* - Resolve when the proposal is accepted
|
|
@@ -505,14 +497,6 @@ export class Quorum extends TypedEventEmitter<IQuorum["on"]> implements IQuorum
|
|
|
505
497
|
return this.quorumProposals.get(key);
|
|
506
498
|
}
|
|
507
499
|
|
|
508
|
-
/**
|
|
509
|
-
* Returns additional data about the approved consensus value
|
|
510
|
-
* @deprecated Removed in recent protocol-definitions. Use get() instead.
|
|
511
|
-
*/
|
|
512
|
-
public getApprovalData(key: string): ICommittedProposal | undefined {
|
|
513
|
-
return this.quorumProposals.getApprovalData(key);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
500
|
/**
|
|
517
501
|
* Adds a new client to the quorum
|
|
518
502
|
*/
|