@fluidframework/container-loader 2.0.2 → 2.1.0-276326
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/.eslintrc.cjs +2 -5
- package/api-extractor/api-extractor.legacy.json +4 -0
- package/api-report/container-loader.beta.api.md +0 -27
- package/api-report/{container-loader.alpha.api.md → container-loader.legacy.alpha.api.md} +0 -27
- package/api-report/container-loader.public.api.md +0 -27
- package/dist/attachment.d.ts +2 -1
- package/dist/attachment.d.ts.map +1 -1
- package/dist/attachment.js.map +1 -1
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js +4 -4
- package/dist/audience.js.map +1 -1
- package/dist/catchUpMonitor.d.ts +15 -4
- package/dist/catchUpMonitor.d.ts.map +1 -1
- package/dist/catchUpMonitor.js +12 -3
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/connectionManager.d.ts +24 -8
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +36 -23
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +30 -20
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +15 -11
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +7 -2
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +45 -28
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +8 -4
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +3 -1
- 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 +12 -6
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +17 -8
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +4 -2
- package/dist/contracts.js.map +1 -1
- package/dist/debugLogger.js +3 -3
- package/dist/debugLogger.js.map +1 -1
- package/dist/deltaManager.d.ts +13 -9
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +32 -23
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaQueue.d.ts +1 -4
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +2 -2
- package/dist/deltaQueue.js.map +1 -1
- package/dist/disposal.d.ts +1 -1
- package/dist/disposal.d.ts.map +1 -1
- package/dist/disposal.js.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/legacy.d.ts +1 -1
- package/dist/loadPaused.d.ts +2 -2
- package/dist/loadPaused.d.ts.map +1 -1
- package/dist/loadPaused.js +7 -3
- package/dist/loadPaused.js.map +1 -1
- package/dist/loader.d.ts +10 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +11 -1
- package/dist/loader.js.map +1 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +3 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
- package/dist/memoryBlobStorage.d.ts.map +1 -1
- package/dist/memoryBlobStorage.js +4 -2
- package/dist/memoryBlobStorage.js.map +1 -1
- package/dist/noopHeuristic.js +1 -1
- package/dist/noopHeuristic.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/protocol/protocol.d.ts +4 -3
- package/dist/protocol/protocol.d.ts.map +1 -1
- package/dist/protocol/protocol.js +6 -5
- package/dist/protocol/protocol.js.map +1 -1
- package/dist/protocol/quorum.d.ts +11 -8
- package/dist/protocol/quorum.d.ts.map +1 -1
- package/dist/protocol/quorum.js +8 -8
- package/dist/protocol/quorum.js.map +1 -1
- package/dist/protocol.d.ts +2 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +7 -2
- package/dist/protocol.js.map +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts +2 -2
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/protocolTreeDocumentStorageService.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js +4 -1
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/serializedStateManager.d.ts +29 -12
- package/dist/serializedStateManager.d.ts.map +1 -1
- package/dist/serializedStateManager.js +55 -24
- package/dist/serializedStateManager.js.map +1 -1
- package/dist/utils.d.ts +4 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +15 -6
- package/dist/utils.js.map +1 -1
- package/lib/attachment.d.ts +2 -1
- package/lib/attachment.d.ts.map +1 -1
- package/lib/attachment.js.map +1 -1
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js +4 -4
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.d.ts +15 -4
- package/lib/catchUpMonitor.d.ts.map +1 -1
- package/lib/catchUpMonitor.js +12 -3
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/connectionManager.d.ts +24 -8
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +36 -23
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +30 -20
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +14 -12
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +7 -2
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +45 -28
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +8 -4
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +3 -1
- 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 +12 -6
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +17 -8
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js +4 -2
- package/lib/contracts.js.map +1 -1
- package/lib/debugLogger.js +3 -3
- package/lib/debugLogger.js.map +1 -1
- package/lib/deltaManager.d.ts +13 -9
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +32 -23
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaQueue.d.ts +1 -4
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +2 -2
- package/lib/deltaQueue.js.map +1 -1
- package/lib/disposal.d.ts +1 -1
- package/lib/disposal.d.ts.map +1 -1
- package/lib/disposal.js.map +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/loadPaused.d.ts +2 -2
- package/lib/loadPaused.d.ts.map +1 -1
- package/lib/loadPaused.js +8 -4
- package/lib/loadPaused.js.map +1 -1
- package/lib/loader.d.ts +10 -1
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js +11 -1
- package/lib/loader.js.map +1 -1
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -1
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +3 -1
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
- package/lib/memoryBlobStorage.d.ts.map +1 -1
- package/lib/memoryBlobStorage.js +4 -2
- package/lib/memoryBlobStorage.js.map +1 -1
- package/lib/noopHeuristic.js +1 -1
- package/lib/noopHeuristic.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/protocol/protocol.d.ts +4 -3
- package/lib/protocol/protocol.d.ts.map +1 -1
- package/lib/protocol/protocol.js +6 -5
- package/lib/protocol/protocol.js.map +1 -1
- package/lib/protocol/quorum.d.ts +11 -8
- package/lib/protocol/quorum.d.ts.map +1 -1
- package/lib/protocol/quorum.js +8 -8
- package/lib/protocol/quorum.js.map +1 -1
- package/lib/protocol.d.ts +2 -0
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +7 -2
- package/lib/protocol.js.map +1 -1
- package/lib/protocolTreeDocumentStorageService.d.ts +2 -2
- package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/lib/protocolTreeDocumentStorageService.js.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js +4 -1
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/serializedStateManager.d.ts +29 -12
- package/lib/serializedStateManager.d.ts.map +1 -1
- package/lib/serializedStateManager.js +56 -25
- package/lib/serializedStateManager.js.map +1 -1
- package/lib/utils.d.ts +4 -2
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +16 -7
- package/lib/utils.js.map +1 -1
- package/package.json +21 -17
- package/src/attachment.ts +2 -1
- package/src/audience.ts +4 -4
- package/src/catchUpMonitor.ts +23 -8
- package/src/connectionManager.ts +85 -60
- package/src/connectionStateHandler.ts +85 -63
- package/src/container.ts +118 -84
- package/src/containerContext.ts +5 -3
- package/src/containerStorageAdapter.ts +20 -13
- package/src/contracts.ts +21 -9
- package/src/debugLogger.ts +4 -4
- package/src/deltaManager.ts +75 -56
- package/src/deltaQueue.ts +16 -10
- package/src/disposal.ts +3 -3
- package/src/error.ts +2 -1
- package/src/loadPaused.ts +16 -8
- package/src/loader.ts +20 -2
- package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +7 -3
- package/src/memoryBlobStorage.ts +5 -3
- package/src/noopHeuristic.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/protocol/protocol.ts +12 -11
- package/src/protocol/quorum.ts +49 -40
- package/src/protocol.ts +12 -4
- package/src/protocolTreeDocumentStorageService.ts +3 -2
- package/src/retriableDocumentStorageService.ts +6 -3
- package/src/serializedStateManager.ts +95 -39
- package/src/utils.ts +26 -10
package/src/connectionManager.ts
CHANGED
|
@@ -39,6 +39,8 @@ import {
|
|
|
39
39
|
getRetryDelayFromError,
|
|
40
40
|
isRuntimeMessage,
|
|
41
41
|
logNetworkFailure,
|
|
42
|
+
type GenericNetworkError,
|
|
43
|
+
type ThrottlingError,
|
|
42
44
|
} from "@fluidframework/driver-utils/internal";
|
|
43
45
|
import {
|
|
44
46
|
ITelemetryLoggerExt,
|
|
@@ -67,11 +69,13 @@ const DefaultChunkSize = 16 * 1024;
|
|
|
67
69
|
|
|
68
70
|
const fatalConnectErrorProp = { fatalConnectError: true };
|
|
69
71
|
|
|
70
|
-
function getNackReconnectInfo(
|
|
72
|
+
function getNackReconnectInfo(
|
|
73
|
+
nackContent: INackContent,
|
|
74
|
+
): ThrottlingError | GenericNetworkError {
|
|
71
75
|
const message = `Nack (${nackContent.type}): ${nackContent.message}`;
|
|
72
76
|
const canRetry = nackContent.code !== 403;
|
|
73
77
|
const retryAfterMs =
|
|
74
|
-
nackContent.retryAfter
|
|
78
|
+
nackContent.retryAfter === undefined ? undefined : nackContent.retryAfter * 1000;
|
|
75
79
|
return createGenericNetworkError(
|
|
76
80
|
message,
|
|
77
81
|
{ canRetry, retryAfterMs },
|
|
@@ -97,9 +101,10 @@ class NoDeltaStream
|
|
|
97
101
|
implements IDocumentDeltaConnection, IDisposable
|
|
98
102
|
{
|
|
99
103
|
clientId = clientIdNoDeltaStream;
|
|
100
|
-
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
105
|
+
claims = {
|
|
101
106
|
scopes: [ScopeType.DocRead],
|
|
102
|
-
} as
|
|
107
|
+
} as ITokenClaims;
|
|
103
108
|
mode: ConnectionMode = "read";
|
|
104
109
|
existing: boolean = true;
|
|
105
110
|
maxMessageSize: number = 0;
|
|
@@ -137,7 +142,7 @@ class NoDeltaStream
|
|
|
137
142
|
}),
|
|
138
143
|
);
|
|
139
144
|
}
|
|
140
|
-
submitSignal(message:
|
|
145
|
+
submitSignal(message: unknown): void {
|
|
141
146
|
this.emit("nack", this.clientId, {
|
|
142
147
|
operation: message,
|
|
143
148
|
content: { message: "Cannot submit signal with storage-only connection", code: 403 },
|
|
@@ -145,15 +150,15 @@ class NoDeltaStream
|
|
|
145
150
|
}
|
|
146
151
|
|
|
147
152
|
private _disposed = false;
|
|
148
|
-
public get disposed() {
|
|
153
|
+
public get disposed(): boolean {
|
|
149
154
|
return this._disposed;
|
|
150
155
|
}
|
|
151
|
-
public dispose() {
|
|
156
|
+
public dispose(): void {
|
|
152
157
|
this._disposed = true;
|
|
153
158
|
}
|
|
154
159
|
}
|
|
155
160
|
|
|
156
|
-
function isNoDeltaStreamConnection(connection:
|
|
161
|
+
function isNoDeltaStreamConnection(connection: unknown): connection is NoDeltaStream {
|
|
157
162
|
return connection instanceof NoDeltaStream;
|
|
158
163
|
}
|
|
159
164
|
|
|
@@ -161,7 +166,7 @@ const waitForOnline = async (): Promise<void> => {
|
|
|
161
166
|
// Only wait if we have a strong signal that we're offline - otherwise assume we're online.
|
|
162
167
|
if (globalThis.navigator?.onLine === false && globalThis.addEventListener !== undefined) {
|
|
163
168
|
return new Promise<void>((resolve) => {
|
|
164
|
-
const resolveAndRemoveListener = () => {
|
|
169
|
+
const resolveAndRemoveListener = (): void => {
|
|
165
170
|
resolve();
|
|
166
171
|
globalThis.removeEventListener("online", resolveAndRemoveListener);
|
|
167
172
|
};
|
|
@@ -191,7 +196,9 @@ interface IPendingConnection {
|
|
|
191
196
|
* Exposes various controls to influence this process, including manual reconnects, forced read-only mode, etc.
|
|
192
197
|
*/
|
|
193
198
|
export class ConnectionManager implements IConnectionManager {
|
|
194
|
-
/**
|
|
199
|
+
/**
|
|
200
|
+
* Connection mode used when reconnecting on error or disconnect.
|
|
201
|
+
*/
|
|
195
202
|
private readonly defaultReconnectionMode: ConnectionMode;
|
|
196
203
|
|
|
197
204
|
/**
|
|
@@ -202,13 +209,19 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
202
209
|
private pendingConnection: IPendingConnection | undefined;
|
|
203
210
|
private connection: IDocumentDeltaConnection | undefined;
|
|
204
211
|
|
|
205
|
-
/**
|
|
212
|
+
/**
|
|
213
|
+
* Details about connection. undefined if there is no active connection.
|
|
214
|
+
*/
|
|
206
215
|
private _connectionDetails?: IConnectionDetailsInternal;
|
|
207
216
|
|
|
208
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* file ACL - whether user has only read-only access to a file
|
|
219
|
+
*/
|
|
209
220
|
private _readonlyPermissions: boolean | undefined;
|
|
210
221
|
|
|
211
|
-
/**
|
|
222
|
+
/**
|
|
223
|
+
* tracks host requiring read-only mode.
|
|
224
|
+
*/
|
|
212
225
|
private _forceReadonly = false;
|
|
213
226
|
|
|
214
227
|
/**
|
|
@@ -216,15 +229,21 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
216
229
|
*/
|
|
217
230
|
private _reconnectMode: ReconnectMode;
|
|
218
231
|
|
|
219
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* True if there is pending (async) reconnection from "read" to "write"
|
|
234
|
+
*/
|
|
220
235
|
private pendingReconnect = false;
|
|
221
236
|
|
|
222
237
|
private clientSequenceNumber = 0;
|
|
223
238
|
private clientSequenceNumberObserved = 0;
|
|
224
|
-
/**
|
|
239
|
+
/**
|
|
240
|
+
* Counts the number of non-runtime ops sent by the client which may not be acked.
|
|
241
|
+
*/
|
|
225
242
|
private localOpsToIgnore = 0;
|
|
226
243
|
|
|
227
|
-
/**
|
|
244
|
+
/**
|
|
245
|
+
* track clientId used last time when we sent any ops
|
|
246
|
+
*/
|
|
228
247
|
private lastSubmittedClientId: string | undefined;
|
|
229
248
|
|
|
230
249
|
private connectFirstConnection = true;
|
|
@@ -237,7 +256,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
237
256
|
|
|
238
257
|
private readonly _outbound: DeltaQueue<IDocumentMessage[]>;
|
|
239
258
|
|
|
240
|
-
public get connectionVerboseProps() {
|
|
259
|
+
public get connectionVerboseProps(): Record<string, string | number> {
|
|
241
260
|
return this._connectionVerboseProps;
|
|
242
261
|
}
|
|
243
262
|
|
|
@@ -250,16 +269,18 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
250
269
|
return this.connection?.mode ?? "read";
|
|
251
270
|
}
|
|
252
271
|
|
|
253
|
-
public get connected() {
|
|
272
|
+
public get connected(): boolean {
|
|
254
273
|
return this.connection !== undefined;
|
|
255
274
|
}
|
|
256
275
|
|
|
257
|
-
public get clientId() {
|
|
276
|
+
public get clientId(): string | undefined {
|
|
258
277
|
return this.connection?.clientId;
|
|
259
278
|
}
|
|
260
279
|
|
|
261
|
-
/**
|
|
262
|
-
|
|
280
|
+
/**
|
|
281
|
+
* Details about connection. Returns undefined if there is no active connection.
|
|
282
|
+
*/
|
|
283
|
+
public get connectionDetails(): IConnectionDetailsInternal | undefined {
|
|
263
284
|
return this._connectionDetails;
|
|
264
285
|
}
|
|
265
286
|
|
|
@@ -299,13 +320,13 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
299
320
|
* about current or last connection (if there is no connection at the moment)
|
|
300
321
|
*/
|
|
301
322
|
public get connectionProps(): ITelemetryBaseProperties {
|
|
302
|
-
return this.connection
|
|
303
|
-
?
|
|
304
|
-
: {
|
|
323
|
+
return this.connection === undefined
|
|
324
|
+
? {
|
|
305
325
|
...this._connectionProps,
|
|
306
326
|
// Report how many ops this client sent in last disconnected session
|
|
307
327
|
sentOps: this.clientSequenceNumber,
|
|
308
|
-
}
|
|
328
|
+
}
|
|
329
|
+
: this._connectionProps;
|
|
309
330
|
}
|
|
310
331
|
|
|
311
332
|
public shouldJoinWrite(): boolean {
|
|
@@ -368,7 +389,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
368
389
|
claims: connection.claims,
|
|
369
390
|
clientId: connection.clientId,
|
|
370
391
|
checkpointSequenceNumber: connection.checkpointSequenceNumber,
|
|
371
|
-
get initialClients() {
|
|
392
|
+
get initialClients(): ISignalClient[] {
|
|
372
393
|
return connection.initialClients;
|
|
373
394
|
},
|
|
374
395
|
mode: connection.mode,
|
|
@@ -404,7 +425,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
404
425
|
});
|
|
405
426
|
}
|
|
406
427
|
|
|
407
|
-
public dispose(error?: ICriticalContainerError, switchToReadonly: boolean = true) {
|
|
428
|
+
public dispose(error?: ICriticalContainerError, switchToReadonly: boolean = true): void {
|
|
408
429
|
if (this._disposed) {
|
|
409
430
|
return;
|
|
410
431
|
}
|
|
@@ -453,7 +474,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
453
474
|
/**
|
|
454
475
|
* {@inheritDoc Container.forceReadonly}
|
|
455
476
|
*/
|
|
456
|
-
public forceReadonly(readonly: boolean) {
|
|
477
|
+
public forceReadonly(readonly: boolean): void {
|
|
457
478
|
if (readonly !== this._forceReadonly) {
|
|
458
479
|
this.logger.sendTelemetryEvent({
|
|
459
480
|
eventName: "ForceReadOnly",
|
|
@@ -493,16 +514,16 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
493
514
|
newReadonlyValue: boolean,
|
|
494
515
|
oldReadonlyValue: boolean | undefined,
|
|
495
516
|
readonlyConnectionReason?: IConnectionStateChangeReason,
|
|
496
|
-
) {
|
|
517
|
+
): void {
|
|
497
518
|
this._readonlyPermissions = newReadonlyValue;
|
|
498
519
|
if (oldReadonlyValue !== this.readonly) {
|
|
499
520
|
this.props.readonlyChangeHandler(this.readonly, readonlyConnectionReason);
|
|
500
521
|
}
|
|
501
522
|
}
|
|
502
523
|
|
|
503
|
-
public connect(reason: IConnectionStateChangeReason, connectionMode?: ConnectionMode) {
|
|
504
|
-
this.connectCore(reason, connectionMode).catch((
|
|
505
|
-
const normalizedError = normalizeError(
|
|
524
|
+
public connect(reason: IConnectionStateChangeReason, connectionMode?: ConnectionMode): void {
|
|
525
|
+
this.connectCore(reason, connectionMode).catch((error) => {
|
|
526
|
+
const normalizedError = normalizeError(error, { props: fatalConnectErrorProp });
|
|
506
527
|
this.props.closeHandler(normalizedError);
|
|
507
528
|
});
|
|
508
529
|
}
|
|
@@ -563,12 +584,12 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
563
584
|
let delayMs = InitialReconnectDelayInMs;
|
|
564
585
|
let connectRepeatCount = 0;
|
|
565
586
|
const connectStartTime = performance.now();
|
|
566
|
-
let lastError:
|
|
587
|
+
let lastError: unknown;
|
|
567
588
|
|
|
568
589
|
const abortController = new AbortController();
|
|
569
590
|
const abortSignal = abortController.signal;
|
|
570
591
|
this.pendingConnection = {
|
|
571
|
-
abort: () => {
|
|
592
|
+
abort: (): void => {
|
|
572
593
|
abortController.abort();
|
|
573
594
|
},
|
|
574
595
|
connectionMode: requestedMode,
|
|
@@ -610,7 +631,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
610
631
|
undefined,
|
|
611
632
|
LogLevel.verbose,
|
|
612
633
|
);
|
|
613
|
-
} catch (origError:
|
|
634
|
+
} catch (origError: unknown) {
|
|
614
635
|
this.logger.sendTelemetryEvent(
|
|
615
636
|
{
|
|
616
637
|
eventName: "ConnectToDeltaStreamException",
|
|
@@ -738,7 +759,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
738
759
|
private triggerConnect(
|
|
739
760
|
reason: IConnectionStateChangeReason,
|
|
740
761
|
connectionMode: ConnectionMode,
|
|
741
|
-
) {
|
|
762
|
+
): void {
|
|
742
763
|
// reconnect() includes async awaits, and that causes potential race conditions
|
|
743
764
|
// where we might already have a connection. If it were to happen, it's possible that we will connect
|
|
744
765
|
// with different mode to `connectionMode`. Glancing through the caller chains, it looks like code should be
|
|
@@ -802,7 +823,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
802
823
|
/**
|
|
803
824
|
* Cancel in-progress connection attempt.
|
|
804
825
|
*/
|
|
805
|
-
private cancelConnection(reason: IConnectionStateChangeReason) {
|
|
826
|
+
private cancelConnection(reason: IConnectionStateChangeReason): void {
|
|
806
827
|
assert(
|
|
807
828
|
this.pendingConnection !== undefined,
|
|
808
829
|
0x345 /* this.pendingConnection is undefined when trying to cancel */,
|
|
@@ -828,7 +849,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
828
849
|
connection: IDocumentDeltaConnection,
|
|
829
850
|
requestedMode: ConnectionMode,
|
|
830
851
|
reason: IConnectionStateChangeReason,
|
|
831
|
-
) {
|
|
852
|
+
): void {
|
|
832
853
|
// Old connection should have been cleaned up before establishing a new one
|
|
833
854
|
assert(
|
|
834
855
|
this.connection === undefined,
|
|
@@ -915,7 +936,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
915
936
|
this._connectionProps.connectionMode = connection.mode;
|
|
916
937
|
|
|
917
938
|
let last = -1;
|
|
918
|
-
if (initialMessages.length
|
|
939
|
+
if (initialMessages.length > 0) {
|
|
919
940
|
this._connectionVerboseProps.connectionInitialOpsFrom =
|
|
920
941
|
initialMessages[0].sequenceNumber;
|
|
921
942
|
last = initialMessages[initialMessages.length - 1].sequenceNumber;
|
|
@@ -943,6 +964,8 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
943
964
|
// This allows us to have single way to process signals, and makes it simpler to initialize
|
|
944
965
|
// protocol in Container.
|
|
945
966
|
const clearSignal: ISignalMessage = {
|
|
967
|
+
// API uses null
|
|
968
|
+
// eslint-disable-next-line unicorn/no-null
|
|
946
969
|
clientId: null, // system message
|
|
947
970
|
content: JSON.stringify({
|
|
948
971
|
type: SignalType.Clear,
|
|
@@ -954,6 +977,8 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
954
977
|
|
|
955
978
|
const clientJoinSignals: ISignalMessage[] = (connection.initialClients ?? []).map(
|
|
956
979
|
(priorClient) => ({
|
|
980
|
+
// API uses null
|
|
981
|
+
// eslint-disable-next-line unicorn/no-null
|
|
957
982
|
clientId: null, // system signal
|
|
958
983
|
content: JSON.stringify({
|
|
959
984
|
type: SignalType.ClientJoin,
|
|
@@ -962,7 +987,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
962
987
|
}),
|
|
963
988
|
);
|
|
964
989
|
if (clientJoinSignals.length > 0) {
|
|
965
|
-
signalsToProcess = signalsToProcess
|
|
990
|
+
signalsToProcess = [...signalsToProcess, ...clientJoinSignals];
|
|
966
991
|
}
|
|
967
992
|
|
|
968
993
|
// Unfortunately, there is no defined order between initialSignals (including join & leave signals)
|
|
@@ -970,7 +995,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
970
995
|
// for "self" and connection.initialClients does not contain "self", so we have to process them after
|
|
971
996
|
// "clear" signal above.
|
|
972
997
|
if (connection.initialSignals !== undefined && connection.initialSignals.length > 0) {
|
|
973
|
-
signalsToProcess = signalsToProcess
|
|
998
|
+
signalsToProcess = [...signalsToProcess, ...connection.initialSignals];
|
|
974
999
|
}
|
|
975
1000
|
|
|
976
1001
|
this.props.signalHandler(signalsToProcess);
|
|
@@ -983,7 +1008,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
983
1008
|
* @param error - Error reconnect information including whether or not to reconnect
|
|
984
1009
|
* @returns A promise that resolves when the connection is reestablished or we stop trying
|
|
985
1010
|
*/
|
|
986
|
-
private reconnectOnError(requestedMode: ConnectionMode, error: IAnyDriverError) {
|
|
1011
|
+
private reconnectOnError(requestedMode: ConnectionMode, error: IAnyDriverError): void {
|
|
987
1012
|
this.reconnect(requestedMode, { text: error.message, error }).catch(
|
|
988
1013
|
this.props.closeHandler,
|
|
989
1014
|
);
|
|
@@ -999,7 +1024,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
999
1024
|
private async reconnect(
|
|
1000
1025
|
requestedMode: ConnectionMode,
|
|
1001
1026
|
reason: IConnectionStateChangeReason<IAnyDriverError>,
|
|
1002
|
-
) {
|
|
1027
|
+
): Promise<void> {
|
|
1003
1028
|
// We quite often get protocol errors before / after observing nack/disconnect
|
|
1004
1029
|
// we do not want to run through same sequence twice.
|
|
1005
1030
|
// If we're already disconnected/disconnecting it's not appropriate to call this again.
|
|
@@ -1049,9 +1074,9 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1049
1074
|
this.triggerConnect(
|
|
1050
1075
|
{
|
|
1051
1076
|
text:
|
|
1052
|
-
reason.error
|
|
1053
|
-
?
|
|
1054
|
-
:
|
|
1077
|
+
reason.error === undefined
|
|
1078
|
+
? `Reconnecting due to: ${reason.text}`
|
|
1079
|
+
: "Reconnecting due to Error",
|
|
1055
1080
|
error: reason.error,
|
|
1056
1081
|
},
|
|
1057
1082
|
requestedMode,
|
|
@@ -1087,10 +1112,10 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1087
1112
|
this.clientSequenceNumberObserved = 0;
|
|
1088
1113
|
}
|
|
1089
1114
|
|
|
1090
|
-
if (
|
|
1091
|
-
this.localOpsToIgnore++;
|
|
1092
|
-
} else {
|
|
1115
|
+
if (isRuntimeMessage(message)) {
|
|
1093
1116
|
this.localOpsToIgnore = 0;
|
|
1117
|
+
} else {
|
|
1118
|
+
this.localOpsToIgnore++;
|
|
1094
1119
|
}
|
|
1095
1120
|
|
|
1096
1121
|
return {
|
|
@@ -1099,15 +1124,15 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1099
1124
|
};
|
|
1100
1125
|
}
|
|
1101
1126
|
|
|
1102
|
-
public submitSignal(content: string, targetClientId?: string) {
|
|
1103
|
-
if (this.connection
|
|
1104
|
-
this.connection.submitSignal(content, targetClientId);
|
|
1105
|
-
} else {
|
|
1127
|
+
public submitSignal(content: string, targetClientId?: string): void {
|
|
1128
|
+
if (this.connection === undefined) {
|
|
1106
1129
|
this.logger.sendErrorEvent({ eventName: "submitSignalDisconnected" });
|
|
1130
|
+
} else {
|
|
1131
|
+
this.connection.submitSignal(content, targetClientId);
|
|
1107
1132
|
}
|
|
1108
1133
|
}
|
|
1109
1134
|
|
|
1110
|
-
public sendMessages(messages: IDocumentMessage[]) {
|
|
1135
|
+
public sendMessages(messages: IDocumentMessage[]): void {
|
|
1111
1136
|
assert(this.connected, 0x2b4 /* "not connected on sending ops!" */);
|
|
1112
1137
|
// If connection is "read" or implicit "read" (got leave op for "write" connection),
|
|
1113
1138
|
// then op can't make it through - we will get a nack if op is sent.
|
|
@@ -1138,7 +1163,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1138
1163
|
this._outbound.push(messages);
|
|
1139
1164
|
}
|
|
1140
1165
|
|
|
1141
|
-
public beforeProcessingIncomingOp(message: ISequencedDocumentMessage) {
|
|
1166
|
+
public beforeProcessingIncomingOp(message: ISequencedDocumentMessage): void {
|
|
1142
1167
|
// if we have connection, and message is local, then we better treat is as local!
|
|
1143
1168
|
assert(
|
|
1144
1169
|
this.clientId !== message.clientId || this.lastSubmittedClientId === message.clientId,
|
|
@@ -1189,18 +1214,18 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1189
1214
|
private readonly opHandler = (
|
|
1190
1215
|
documentId: string,
|
|
1191
1216
|
messagesArg: ISequencedDocumentMessage[],
|
|
1192
|
-
) => {
|
|
1217
|
+
): void => {
|
|
1193
1218
|
const messages = Array.isArray(messagesArg) ? messagesArg : [messagesArg];
|
|
1194
1219
|
this.props.incomingOpHandler(messages, "opHandler");
|
|
1195
1220
|
};
|
|
1196
1221
|
|
|
1197
|
-
private readonly signalHandler = (signalsArg: ISignalMessage | ISignalMessage[]) => {
|
|
1222
|
+
private readonly signalHandler = (signalsArg: ISignalMessage | ISignalMessage[]): void => {
|
|
1198
1223
|
const signals = Array.isArray(signalsArg) ? signalsArg : [signalsArg];
|
|
1199
1224
|
this.props.signalHandler(signals);
|
|
1200
1225
|
};
|
|
1201
1226
|
|
|
1202
1227
|
// Always connect in write mode after getting nacked.
|
|
1203
|
-
private readonly nackHandler = (documentId: string, messages: INack[]) => {
|
|
1228
|
+
private readonly nackHandler = (documentId: string, messages: INack[]): void => {
|
|
1204
1229
|
const message = messages[0];
|
|
1205
1230
|
if (this._readonlyPermissions === true) {
|
|
1206
1231
|
this.props.closeHandler(
|
|
@@ -1221,13 +1246,13 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1221
1246
|
};
|
|
1222
1247
|
|
|
1223
1248
|
// Connection mode is always read on disconnect/error unless the system mode was write.
|
|
1224
|
-
private readonly disconnectHandlerInternal = (disconnectReason: IAnyDriverError) => {
|
|
1249
|
+
private readonly disconnectHandlerInternal = (disconnectReason: IAnyDriverError): void => {
|
|
1225
1250
|
// Note: we might get multiple disconnect calls on same socket, as early disconnect notification
|
|
1226
1251
|
// ("server_disconnect", ODSP-specific) is mapped to "disconnect"
|
|
1227
1252
|
this.reconnectOnError(this.defaultReconnectionMode, disconnectReason);
|
|
1228
1253
|
};
|
|
1229
1254
|
|
|
1230
|
-
private readonly errorHandler = (error: IAnyDriverError) => {
|
|
1255
|
+
private readonly errorHandler = (error: IAnyDriverError): void => {
|
|
1231
1256
|
this.reconnectOnError(this.defaultReconnectionMode, error);
|
|
1232
1257
|
};
|
|
1233
1258
|
}
|