@fluidframework/driver-base 2.0.0-internal.3.3.1 → 2.0.0-internal.3.4.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.
@@ -146,6 +146,7 @@ export declare class DocumentDeltaConnection extends EventEmitterWithErrorHandli
146
146
  protected disconnectCore(): void;
147
147
  protected initialize(connectMessage: IConnect, timeout: number): Promise<void>;
148
148
  private addPropsToError;
149
+ private getConnectionDetailsProps;
149
150
  protected earlyOpHandler: (documentId: string, msgs: ISequencedDocumentMessage[]) => void;
150
151
  protected earlySignalHandler: (msg: ISignalMessage) => void;
151
152
  private removeEarlyOpHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"documentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,eAAe,EACf,wBAAwB,EACxB,8BAA8B,EAC9B,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACN,cAAc,EACd,oBAAoB,EACpB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,yBAAyB,EACzB,aAAa,EACb,cAAc,EACd,YAAY,EAEZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAMN,6BAA6B,EAE7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI/C;;GAEG;AACH,qBAAa,uBACZ,SAAQ,6BAA6B,CAAC,8BAA8B,CACpE,YAAW,wBAAwB,EAAE,WAAW;IAuF/C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAC1B,UAAU,EAAE,MAAM;IAEzB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IAC5C,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;IAzFjC,MAAM,CAAC,QAAQ,CAAC,eAAe,WAAoC;IAInE,MAAM,CAAC,QAAQ,CAAC,qBAAqB,WAA2B;IAEhE;;;;;;OAMG;IACI,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAGpD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,yBAAyB,EAAE,CAAM;IACpE,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,cAAc,EAAE,CAAM;IAExD;;;OAGG;IACH,OAAO,CAAC,sBAAsB,CAAkB;IAEhD,OAAO,CAAC,uBAAuB,CAA4C;IAE3E,OAAO,CAAC,QAAQ,CAAyB;IAGzC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAoD;IAExF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoD;IAErF,SAAS,KAAK,UAAU,IAAI,OAAO,CAElC;IAED,IAAW,QAAQ,YAiBlB;IAED;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,OAAO,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAEvC;;OAEG;IACH,SAAS,KAAK,MAAM,IAAI,gBAAgB,CAEvC;IAED,IAAW,OAAO,IAAI,UAAU,CAK/B;IAED;;;;;OAKG;IACH,SAAS,aACW,MAAM,EAAE,MAAM,EAC1B,UAAU,EAAE,MAAM,EACzB,MAAM,EAAE,gBAAgB,EACP,2BAA2B,GAAE,OAAe,EAC1C,YAAY,CAAC,oBAAQ;IA4CzC;;;;OAIG;IACH,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED;;;;OAIG;IACH,IAAW,IAAI,IAAI,cAAc,CAEhC;IAED;;;;OAIG;IACH,IAAW,MAAM,IAAI,YAAY,CAEhC;IAED;;;;OAIG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED;;;;OAIG;IACH,IAAW,cAAc,IAAI,MAAM,CAElC;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAW,oBAAoB,IAAI,oBAAoB,CAEtD;IAED,OAAO,CAAC,cAAc;IAetB;;;;OAIG;IACH,IAAW,eAAe,IAAI,yBAAyB,EAAE,CAmBxD;IAED;;;;OAIG;IACH,IAAW,cAAc,IAAI,cAAc,EAAE,CAa5C;IAED;;;;OAIG;IACH,IAAW,cAAc,IAAI,aAAa,EAAE,CAG3C;IAED,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE;IASnE,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAI/D;;;;OAIG;IACI,MAAM,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,IAAI;IAKjD;;;;OAIG;IACI,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAKpD;;OAEG;IACH,OAAO,CAAC,WAAW;IAmBnB,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,eAAe;IAIhD;;;;OAIG;IACI,OAAO;IAkBd,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,eAAe;IAmCzC;;;OAGG;IACH,SAAS,CAAC,cAAc;cAIR,UAAU,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IAqMpE,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,yBAAyB;IASjC,SAAS,CAAC,cAAc,eAAgB,MAAM,QAAQ,yBAAyB,EAAE,UAE/E;IAEF,SAAS,CAAC,kBAAkB,QAAS,cAAc,UAEjD;IAEF,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,qBAAqB;IAc7B,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;IAM9E,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,yBAAyB;IAWjC;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,QAAQ,UAAO,GAAG,eAAe;CA8B3F"}
@@ -260,19 +260,12 @@ class DocumentDeltaConnection extends telemetry_utils_1.EventEmitterWithErrorHan
260
260
  * Disconnect from the websocket and close the websocket too.
261
261
  */
262
262
  closeSocket(error) {
263
- var _a;
264
263
  if (this._disposed) {
265
264
  // This would be rare situation due to complexity around socket emitting events.
266
265
  this.logger.sendTelemetryEvent({
267
266
  eventName: "SocketCloseOnDisposedConnection",
268
267
  driverVersion: packageVersion_1.pkgVersion,
269
- details: JSON.stringify({
270
- disposed: this._disposed,
271
- socketConnected: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected,
272
- trackedListenerCount: this.trackedListeners.size,
273
- clientId: this.clientId,
274
- connectionId: this.connectionId,
275
- }),
268
+ details: JSON.stringify(Object.assign(Object.assign({}, this.getConnectionDetailsProps()), { trackedListenerCount: this.trackedListeners.size })),
276
269
  }, error);
277
270
  return;
278
271
  }
@@ -287,16 +280,10 @@ class DocumentDeltaConnection extends telemetry_utils_1.EventEmitterWithErrorHan
287
280
  * multiplexing here, so we need to close the socket here.
288
281
  */
289
282
  dispose() {
290
- var _a;
291
283
  this.logger.sendTelemetryEvent({
292
284
  eventName: "ClientClosingDeltaConnection",
293
285
  driverVersion: packageVersion_1.pkgVersion,
294
- details: JSON.stringify({
295
- disposed: this._disposed,
296
- socketConnected: this.socket.connected,
297
- clientId: (_a = this._details) === null || _a === void 0 ? void 0 : _a.clientId,
298
- connectionId: this.connectionId,
299
- }),
286
+ details: JSON.stringify(Object.assign({}, this.getConnectionDetailsProps())),
300
287
  });
301
288
  this.disconnect((0, driver_utils_1.createGenericNetworkError)(
302
289
  // pre-0.58 error message: clientClosingConnection
@@ -315,25 +302,19 @@ class DocumentDeltaConnection extends telemetry_utils_1.EventEmitterWithErrorHan
315
302
  // OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended
316
303
  // to prevent normal messages from being emitted.
317
304
  this._disposed = true;
318
- // Let user of connection object know about disconnect. This has to happen in between setting _disposed and
319
- // removing all listeners!
305
+ // Remove all listeners listening on the socket. These are listeners on socket and not on this connection
306
+ // object. Anyway since we have disposed this connection object, nobody should listen to event on socket
307
+ // anymore.
308
+ this.removeTrackedListeners();
309
+ // Clear the connection/socket before letting the deltaManager/connection manager know about the disconnect.
310
+ this.disconnectCore();
311
+ // Let user of connection object know about disconnect.
320
312
  this.emit("disconnect", err);
321
313
  this.logger.sendTelemetryEvent({
322
314
  eventName: "AfterDisconnectEvent",
323
315
  driverVersion: packageVersion_1.pkgVersion,
324
- details: JSON.stringify({
325
- disposed: this._disposed,
326
- clientId: this.clientId,
327
- socketConnected: this.socket.connected,
328
- disconnectListenerCount: this.listenerCount("disconnect"),
329
- connectionId: this.connectionId,
330
- }),
316
+ details: JSON.stringify(Object.assign(Object.assign({}, this.getConnectionDetailsProps()), { disconnectListenerCount: this.listenerCount("disconnect") })),
331
317
  });
332
- // user of DeltaConnection should have processed "disconnect" event and removed all listeners. Not clear
333
- // if we want to enforce that, as some users (like LocalDocumentService) do not unregister any handlers
334
- // assert(this.listenerCount("disconnect") === 0, "'disconnect` events should be processed synchronously");
335
- this.removeTrackedListeners();
336
- this.disconnectCore();
337
318
  }
338
319
  /**
339
320
  * Disconnect from the websocket.
@@ -491,19 +472,22 @@ class DocumentDeltaConnection extends telemetry_utils_1.EventEmitterWithErrorHan
491
472
  (0, common_utils_1.assert)(!this.disposed, 0x246 /* "checking consistency of socket & _disposed flags" */);
492
473
  }
493
474
  addPropsToError(errorToBeNormalized) {
494
- var _a, _b;
495
475
  const normalizedError = (0, telemetry_utils_1.normalizeError)(errorToBeNormalized, {
496
476
  props: {
497
- details: JSON.stringify({
498
- disposed: this._disposed,
499
- socketConnected: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected,
500
- clientId: (_b = this._details) === null || _b === void 0 ? void 0 : _b.clientId,
501
- conenctionId: this.connectionId,
502
- }),
477
+ details: JSON.stringify(Object.assign({}, this.getConnectionDetailsProps())),
503
478
  },
504
479
  });
505
480
  return normalizedError;
506
481
  }
482
+ getConnectionDetailsProps() {
483
+ var _a, _b;
484
+ return {
485
+ disposed: this._disposed,
486
+ socketConnected: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected,
487
+ clientId: (_b = this._details) === null || _b === void 0 ? void 0 : _b.clientId,
488
+ connectionId: this.connectionId,
489
+ };
490
+ }
507
491
  removeEarlyOpHandler() {
508
492
  this.socket.removeListener("op", this.earlyOpHandler);
509
493
  this.earlyOpHandlerAttached = false;
@@ -561,7 +545,10 @@ class DocumentDeltaConnection extends telemetry_utils_1.EventEmitterWithErrorHan
561
545
  else {
562
546
  message = (0, telemetry_utils_1.extractLogSafeErrorProperties)(error, true).message;
563
547
  }
564
- const errorObj = (0, driver_utils_1.createGenericNetworkError)(`socket.io (${handler}): ${message}`, { canRetry }, { driverVersion: packageVersion_1.pkgVersion });
548
+ const errorObj = (0, driver_utils_1.createGenericNetworkError)(`socket.io (${handler}): ${message}`, { canRetry }, {
549
+ driverVersion: packageVersion_1.pkgVersion,
550
+ details: JSON.stringify(Object.assign({}, this.getConnectionDetailsProps())),
551
+ });
565
552
  return errorObj;
566
553
  }
567
554
  }
@@ -1 +1 @@
1
- {"version":3,"file":"documentDeltaConnection.js","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n\tIAnyDriverError,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } from \"@fluidframework/driver-utils\";\nimport {\n\tConnectionMode,\n\tIClientConfiguration,\n\tIConnect,\n\tIConnected,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tITokenClaims,\n\tScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n\tChildLogger,\n\textractLogSafeErrorProperties,\n\tgetCircularReplacer,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n\tEventEmitterWithErrorHandling,\n\tnormalizeError,\n} from \"@fluidframework/telemetry-utils\";\nimport type { Socket } from \"socket.io-client\";\n// For now, this package is versioned and released in unison with the specific drivers\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n/**\n * Represents a connection to a stream of delta updates\n */\nexport class DocumentDeltaConnection\n\textends EventEmitterWithErrorHandling<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\tstatic readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n\t// WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n\t// Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n\tstatic readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n\t/**\n\t * Last known sequence number to ordering service at the time of connection\n\t * It may lap actual last sequence number (quite a bit, if container is very active).\n\t * But it's best information for client to figure out how far it is behind, at least\n\t * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n\t * that is likely to be more up-to-date.\n\t */\n\tpublic checkpointSequenceNumber: number | undefined;\n\n\t// Listen for ops sent before we receive a response to connect_document\n\tprotected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n\tprotected readonly queuedSignals: ISignalMessage[] = [];\n\n\t/**\n\t * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n\t * to later be retrieved via initialMessages.\n\t */\n\tprivate earlyOpHandlerAttached: boolean = false;\n\n\tprivate socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n\tprivate _details: IConnected | undefined;\n\n\t// Listeners only needed while the connection is in progress\n\tprivate readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n\t// Listeners used throughout the lifetime of the DocumentDeltaConnection\n\tprivate readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n\tprotected get hasDetails(): boolean {\n\t\treturn !!this._details;\n\t}\n\n\tpublic get disposed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(\n\t\t\t\tthis._disposed || this.socket.connected,\n\t\t\t\t0x244 /* \"Socket is closed, but connection is not!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t\treturn this._disposed;\n\t}\n\n\t/**\n\t * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n\t * After disconnection, we flip this to prevent any stale messages from being emitted.\n\t */\n\tprotected _disposed: boolean = false;\n\tprivate readonly mc: MonitoringContext;\n\n\t/**\n\t * @deprecated Implementors should manage their own logger or monitoring context\n\t */\n\tprotected get logger(): ITelemetryLogger {\n\t\treturn this.mc.logger;\n\t}\n\n\tpublic get details(): IConnected {\n\t\tif (!this._details) {\n\t\t\tthrow new Error(\"Internal error: calling method before _details is initialized!\");\n\t\t}\n\t\treturn this._details;\n\t}\n\n\t/**\n\t * @param socket - websocket to be used\n\t * @param documentId - ID of the document\n\t * @param logger - for reporting telemetry events\n\t * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n\t */\n\tprotected constructor(\n\t\tprotected readonly socket: Socket,\n\t\tpublic documentId: string,\n\t\tlogger: ITelemetryLogger,\n\t\tprivate readonly enableLongPollingDowngrades: boolean = false,\n\t\tprotected readonly connectionId?: string,\n\t) {\n\t\tsuper((name, error) => {\n\t\t\tlogger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"DeltaConnection:EventException\",\n\t\t\t\t\tname,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(logger, \"DeltaConnection\"));\n\n\t\tthis.on(\"newListener\", (event, listener) => {\n\t\t\tassert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n\t\t\t// Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n\t\t\tif (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n\t\t\t\tassert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n\t\t\t\tthrow new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n\t\t\t}\n\n\t\t\t// Whenever listener is added, we should subscribe on same event on socket, so these two things\n\t\t\t// should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n\t\t\t// and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n\t\t\t// Better flow might be to always unconditionally register all handlers on successful connection,\n\t\t\t// though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n\t\t\tassert(\n\t\t\t\t(this.listeners(event).length !== 0) === this.trackedListeners.has(event),\n\t\t\t\t0x20b /* \"mismatch\" */,\n\t\t\t);\n\t\t\tif (!this.trackedListeners.has(event)) {\n\t\t\t\tthis.addTrackedListener(event, (...args: any[]) => {\n\t\t\t\t\tthis.emit(event, ...args);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Get the ID of the client who is sending the message\n\t *\n\t * @returns the client ID\n\t */\n\tpublic get clientId(): string {\n\t\treturn this.details.clientId;\n\t}\n\n\t/**\n\t * Get the mode of the client\n\t *\n\t * @returns the client mode\n\t */\n\tpublic get mode(): ConnectionMode {\n\t\treturn this.details.mode;\n\t}\n\n\t/**\n\t * Get the claims of the client who is sending the message\n\t *\n\t * @returns client claims\n\t */\n\tpublic get claims(): ITokenClaims {\n\t\treturn this.details.claims;\n\t}\n\n\t/**\n\t * Get whether or not this is an existing document\n\t *\n\t * @returns true if the document exists\n\t */\n\tpublic get existing(): boolean {\n\t\treturn this.details.existing;\n\t}\n\n\t/**\n\t * Get the maximum size of a message before chunking is required\n\t *\n\t * @returns the maximum size of a message before chunking is required\n\t */\n\tpublic get maxMessageSize(): number {\n\t\treturn this.details.serviceConfiguration.maxMessageSize;\n\t}\n\n\t/**\n\t * Semver of protocol being used with the service\n\t */\n\tpublic get version(): string {\n\t\treturn this.details.version;\n\t}\n\n\t/**\n\t * Configuration details provided by the service\n\t */\n\tpublic get serviceConfiguration(): IClientConfiguration {\n\t\treturn this.details.serviceConfiguration;\n\t}\n\n\tprivate checkNotClosed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(!this.disposed, 0x20c /* \"connection disposed\" */);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t}\n\n\t/**\n\t * Get messages sent during the connection\n\t *\n\t * @returns messages sent during the connection\n\t */\n\tpublic get initialMessages(): ISequencedDocumentMessage[] {\n\t\tthis.checkNotClosed();\n\n\t\t// If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n\t\t// latest ops. This could possibly indicate that initialMessages was called twice.\n\t\tassert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n\t\t// We will lose ops and perf will tank as we need to go to storage to become current!\n\t\tassert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n\t\tthis.removeEarlyOpHandler();\n\n\t\tif (this.queuedMessages.length > 0) {\n\t\t\t// Some messages were queued.\n\t\t\t// add them to the list of initialMessages to be processed\n\t\t\tthis.details.initialMessages.push(...this.queuedMessages);\n\t\t\tthis.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tthis.queuedMessages.length = 0;\n\t\t}\n\t\treturn this.details.initialMessages;\n\t}\n\n\t/**\n\t * Get signals sent during the connection\n\t *\n\t * @returns signals sent during the connection\n\t */\n\tpublic get initialSignals(): ISignalMessage[] {\n\t\tthis.checkNotClosed();\n\t\tassert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n\t\tthis.removeEarlySignalHandler();\n\n\t\tif (this.queuedSignals.length > 0) {\n\t\t\t// Some signals were queued.\n\t\t\t// add them to the list of initialSignals to be processed\n\t\t\tthis.details.initialSignals.push(...this.queuedSignals);\n\t\t\tthis.queuedSignals.length = 0;\n\t\t}\n\t\treturn this.details.initialSignals;\n\t}\n\n\t/**\n\t * Get initial client list\n\t *\n\t * @returns initial client list sent during the connection\n\t */\n\tpublic get initialClients(): ISignalClient[] {\n\t\tthis.checkNotClosed();\n\t\treturn this.details.initialClients;\n\t}\n\n\tprotected emitMessages(type: string, messages: IDocumentMessage[][]) {\n\t\t// Although the implementation here disconnects the socket and does not reuse it, other subclasses\n\t\t// (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n\t\t// on the still-live socket.\n\t\tif (!this.disposed) {\n\t\t\tthis.socket.emit(type, this.clientId, messages);\n\t\t}\n\t}\n\n\tprotected submitCore(type: string, messages: IDocumentMessage[]) {\n\t\tthis.emitMessages(type, [messages]);\n\t}\n\n\t/**\n\t * Submits a new delta operation to the server\n\t *\n\t * @param message - delta operation to submit\n\t */\n\tpublic submit(messages: IDocumentMessage[]): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitOp\", messages);\n\t}\n\n\t/**\n\t * Submits a new signal to the server\n\t *\n\t * @param message - signal to submit\n\t */\n\tpublic submitSignal(message: IDocumentMessage): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitSignal\", [message]);\n\t}\n\n\t/**\n\t * Disconnect from the websocket and close the websocket too.\n\t */\n\tprivate closeSocket(error: IAnyDriverError) {\n\t\tif (this._disposed) {\n\t\t\t// This would be rare situation due to complexity around socket emitting events.\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"SocketCloseOnDisposedConnection\",\n\t\t\t\t\tdriverVersion,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tdisposed: this._disposed,\n\t\t\t\t\t\tsocketConnected: this.socket?.connected,\n\t\t\t\t\t\ttrackedListenerCount: this.trackedListeners.size,\n\t\t\t\t\t\tclientId: this.clientId,\n\t\t\t\t\t\tconnectionId: this.connectionId,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.closeSocketCore(error);\n\t}\n\n\tprotected closeSocketCore(error: IAnyDriverError) {\n\t\tthis.disconnect(error);\n\t}\n\n\t/**\n\t * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection and close the socket.\n\t * However the OdspDocumentDeltaConnection differ in dispose as in there we don't close the socket. There is no\n\t * multiplexing here, so we need to close the socket here.\n\t */\n\tpublic dispose() {\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"ClientClosingDeltaConnection\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\tdisposed: this._disposed,\n\t\t\t\tsocketConnected: this.socket.connected,\n\t\t\t\tclientId: this._details?.clientId,\n\t\t\t\tconnectionId: this.connectionId,\n\t\t\t}),\n\t\t});\n\t\tthis.disconnect(\n\t\t\tcreateGenericNetworkError(\n\t\t\t\t// pre-0.58 error message: clientClosingConnection\n\t\t\t\t\"Client closing delta connection\",\n\t\t\t\t{ canRetry: true },\n\t\t\t\t{ driverVersion },\n\t\t\t),\n\t\t);\n\t}\n\n\tprotected disconnect(err: IAnyDriverError) {\n\t\t// Can't check this.disposed here, as we get here on socket closure,\n\t\t// so _disposed & socket.connected might be not in sync while processing\n\t\t// \"dispose\" event.\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n\t\t// DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n\t\t// important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n\t\t// OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n\t\t// to prevent normal messages from being emitted.\n\t\tthis._disposed = true;\n\n\t\t// Let user of connection object know about disconnect. This has to happen in between setting _disposed and\n\t\t// removing all listeners!\n\t\tthis.emit(\"disconnect\", err);\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"AfterDisconnectEvent\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\tdisposed: this._disposed,\n\t\t\t\tclientId: this.clientId,\n\t\t\t\tsocketConnected: this.socket.connected,\n\t\t\t\tdisconnectListenerCount: this.listenerCount(\"disconnect\"),\n\t\t\t\tconnectionId: this.connectionId,\n\t\t\t}),\n\t\t});\n\t\t// user of DeltaConnection should have processed \"disconnect\" event and removed all listeners. Not clear\n\t\t// if we want to enforce that, as some users (like LocalDocumentService) do not unregister any handlers\n\t\t// assert(this.listenerCount(\"disconnect\") === 0, \"'disconnect` events should be processed synchronously\");\n\n\t\tthis.removeTrackedListeners();\n\t\tthis.disconnectCore();\n\t}\n\n\t/**\n\t * Disconnect from the websocket.\n\t * @param reason - reason for disconnect\n\t */\n\tprotected disconnectCore() {\n\t\tthis.socket.disconnect();\n\t}\n\n\tprotected async initialize(connectMessage: IConnect, timeout: number) {\n\t\tthis.socket.on(\"op\", this.earlyOpHandler);\n\t\tthis.socket.on(\"signal\", this.earlySignalHandler);\n\t\tthis.earlyOpHandlerAttached = true;\n\n\t\t// Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.\n\t\tlet internalSocketConnectionFailureCount: number = 0;\n\t\tconst isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();\n\t\tconst getMaxInternalSocketReconnectionAttempts = (): number =>\n\t\t\tisInternalSocketReconnectionEnabled() ? this.socket.io.reconnectionAttempts() : 0;\n\t\tconst getMaxAllowedInternalSocketConnectionFailures = (): number =>\n\t\t\tgetMaxInternalSocketReconnectionAttempts() + 1;\n\n\t\tthis._details = await new Promise<IConnected>((resolve, reject) => {\n\t\t\tconst failAndCloseSocket = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.closeSocket(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"CloseSocketError\" }, normalizedError);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tconst failConnection = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.disconnect(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t\t{ eventName: \"FailConnectionError\" },\n\t\t\t\t\t\tnormalizedError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\t// Immediately set the connection timeout.\n\t\t\t// Give extra 2 seconds for handshake on top of socket connection timeout.\n\t\t\tthis.socketConnectionTimeout = setTimeout(() => {\n\t\t\t\tfailConnection(this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n\t\t\t}, timeout + 2000);\n\n\t\t\t// Listen for connection issues\n\t\t\tthis.addConnectionListener(\"connect_error\", (error) => {\n\t\t\t\tinternalSocketConnectionFailureCount++;\n\t\t\t\tlet isWebSocketTransportError = false;\n\t\t\t\ttry {\n\t\t\t\t\tconst description = error?.description;\n\t\t\t\t\tconst context = error?.context;\n\n\t\t\t\t\tif (context && typeof context === \"object\") {\n\t\t\t\t\t\tconst statusText = context.statusText?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.context\n\t\t\t\t\t\tif (statusText === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (description && typeof description === \"object\") {\n\t\t\t\t\t\tconst errorCode = description.error?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.description\n\t\t\t\t\t\tif (errorCode === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (error.type === \"TransportError\") {\n\t\t\t\t\t\t\tisWebSocketTransportError = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// That's a WebSocket. Clear it as we can't log it.\n\t\t\t\t\t\tdescription.target = undefined;\n\t\t\t\t\t}\n\t\t\t\t} catch (_e) {}\n\n\t\t\t\t// Handle socket transport downgrading when not offline.\n\t\t\t\tif (\n\t\t\t\t\tisWebSocketTransportError &&\n\t\t\t\t\tthis.enableLongPollingDowngrades &&\n\t\t\t\t\tthis.socket.io.opts.transports?.[0] !== \"polling\"\n\t\t\t\t) {\n\t\t\t\t\t// Downgrade transports to polling upgrade mechanism.\n\t\t\t\t\tthis.socket.io.opts.transports = [\"polling\", \"websocket\"];\n\t\t\t\t\t// Don't alter reconnection behavior if already enabled.\n\t\t\t\t\tif (!isInternalSocketReconnectionEnabled()) {\n\t\t\t\t\t\t// Allow single reconnection attempt using polling upgrade mechanism.\n\t\t\t\t\t\tthis.socket.io.reconnection(true);\n\t\t\t\t\t\tthis.socket.io.reconnectionAttempts(1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Allow built-in socket.io reconnection handling.\n\t\t\t\tif (\n\t\t\t\t\tisInternalSocketReconnectionEnabled() &&\n\t\t\t\t\tinternalSocketConnectionFailureCount <\n\t\t\t\t\t\tgetMaxAllowedInternalSocketConnectionFailures()\n\t\t\t\t) {\n\t\t\t\t\t// Reconnection is enabled and maximum reconnect attempts have not been reached.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_error\", error));\n\t\t\t});\n\n\t\t\t// Listen for timeouts\n\t\t\tthis.addConnectionListener(\"connect_timeout\", () => {\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_timeout\"));\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst requestedMode = connectMessage.mode;\n\t\t\t\tconst actualMode = response.mode;\n\t\t\t\tconst writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n\t\t\t\tif (writingPermitted) {\n\t\t\t\t\t// The only time we expect a mismatch in requested/actual is if we lack write permissions\n\t\t\t\t\t// In this case we will get \"read\", even if we requested \"write\"\n\t\t\t\t\tif (actualMode !== requestedMode) {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in a different mode than was requested\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (actualMode === \"write\") {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in write mode without write permissions\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n\t\t\t\tthis.removeConnectionListeners();\n\t\t\t\tresolve(response);\n\t\t\t});\n\n\t\t\t// Socket can be disconnected while waiting for Fluid protocol messages\n\t\t\t// (connect_document_error / connect_document_success), as well as before DeltaManager\n\t\t\t// had a chance to register its handlers.\n\t\t\tthis.addTrackedListener(\"disconnect\", (reason) => {\n\t\t\t\tconst err = this.createErrorObject(\"disconnect\", reason);\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addTrackedListener(\"error\", (error) => {\n\t\t\t\t// This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n\t\t\t\tconst err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n\t\t\t\t// Disconnect socket - required if happened before initial handshake\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_error\", (error) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// This is not an socket.io error - it's Fluid protocol error.\n\t\t\t\t// In this case fail connection and indicate that we were unable to create connection\n\t\t\t\tfailConnection(this.createErrorObject(\"connect_document_error\", error));\n\t\t\t});\n\n\t\t\tthis.socket.emit(\"connect_document\", connectMessage);\n\t\t});\n\n\t\tassert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n\t}\n\n\tprivate addPropsToError(errorToBeNormalized: unknown) {\n\t\tconst normalizedError = normalizeError(errorToBeNormalized, {\n\t\t\tprops: {\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\tdisposed: this._disposed,\n\t\t\t\t\tsocketConnected: this.socket?.connected,\n\t\t\t\t\tclientId: this._details?.clientId,\n\t\t\t\t\tconenctionId: this.connectionId,\n\t\t\t\t}),\n\t\t\t},\n\t\t});\n\t\treturn normalizedError;\n\t}\n\n\tprotected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n\t\tthis.queuedMessages.push(...msgs);\n\t};\n\n\tprotected earlySignalHandler = (msg: ISignalMessage) => {\n\t\tthis.queuedSignals.push(msg);\n\t};\n\n\tprivate removeEarlyOpHandler() {\n\t\tthis.socket.removeListener(\"op\", this.earlyOpHandler);\n\t\tthis.earlyOpHandlerAttached = false;\n\t}\n\n\tprivate removeEarlySignalHandler() {\n\t\tthis.socket.removeListener(\"signal\", this.earlySignalHandler);\n\t}\n\n\tprivate addConnectionListener(event: string, listener: (...args: any[]) => void) {\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n\t\t\t0x247 /* \"Use addTrackedListener instead\" */,\n\t\t);\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsToForward.includes(event),\n\t\t\t0x248 /* \"should not subscribe to forwarded events\" */,\n\t\t);\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n\t\tthis.connectionListeners.set(event, listener);\n\t}\n\n\tprotected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n\t\tthis.trackedListeners.set(event, listener);\n\t}\n\n\tprivate removeTrackedListeners() {\n\t\tfor (const [event, listener] of this.trackedListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\t// removeTrackedListeners removes all listeners, including connection listeners\n\t\tthis.removeConnectionListeners();\n\n\t\tthis.removeEarlyOpHandler();\n\t\tthis.removeEarlySignalHandler();\n\n\t\tthis.trackedListeners.clear();\n\t}\n\n\tprivate removeConnectionListeners() {\n\t\tif (this.socketConnectionTimeout !== undefined) {\n\t\t\tclearTimeout(this.socketConnectionTimeout);\n\t\t}\n\n\t\tfor (const [event, listener] of this.connectionListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\tthis.connectionListeners.clear();\n\t}\n\n\t/**\n\t * Error raising for socket.io issues\n\t */\n\tprotected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n\t\t// Note: we suspect the incoming error object is either:\n\t\t// - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n\t\t// - an Error object thrown by socket.io engine. Be careful with not recording PII!\n\t\tlet message: string;\n\t\tif (error?.type === \"TransportError\") {\n\t\t\t// JSON.stringify drops Error.message\n\t\t\tconst messagePrefix = error?.message !== undefined ? `${error.message}: ` : \"\";\n\n\t\t\t// Websocket errors reported by engine.io-client.\n\t\t\t// They are Error objects with description containing WS error and description = \"TransportError\"\n\t\t\t// Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n\t\t\tmessage = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n\t\t} else {\n\t\t\tmessage = extractLogSafeErrorProperties(error, true).message;\n\t\t}\n\n\t\tconst errorObj = createGenericNetworkError(\n\t\t\t`socket.io (${handler}): ${message}`,\n\t\t\t{ canRetry },\n\t\t\t{ driverVersion },\n\t\t);\n\n\t\treturn errorObj;\n\t}\n}\n"]}
1
+ {"version":3,"file":"documentDeltaConnection.js","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n\tIAnyDriverError,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } from \"@fluidframework/driver-utils\";\nimport {\n\tConnectionMode,\n\tIClientConfiguration,\n\tIConnect,\n\tIConnected,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tITokenClaims,\n\tScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n\tChildLogger,\n\textractLogSafeErrorProperties,\n\tgetCircularReplacer,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n\tEventEmitterWithErrorHandling,\n\tnormalizeError,\n} from \"@fluidframework/telemetry-utils\";\nimport type { Socket } from \"socket.io-client\";\n// For now, this package is versioned and released in unison with the specific drivers\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n/**\n * Represents a connection to a stream of delta updates\n */\nexport class DocumentDeltaConnection\n\textends EventEmitterWithErrorHandling<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\tstatic readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n\t// WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n\t// Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n\tstatic readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n\t/**\n\t * Last known sequence number to ordering service at the time of connection\n\t * It may lap actual last sequence number (quite a bit, if container is very active).\n\t * But it's best information for client to figure out how far it is behind, at least\n\t * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n\t * that is likely to be more up-to-date.\n\t */\n\tpublic checkpointSequenceNumber: number | undefined;\n\n\t// Listen for ops sent before we receive a response to connect_document\n\tprotected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n\tprotected readonly queuedSignals: ISignalMessage[] = [];\n\n\t/**\n\t * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n\t * to later be retrieved via initialMessages.\n\t */\n\tprivate earlyOpHandlerAttached: boolean = false;\n\n\tprivate socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n\tprivate _details: IConnected | undefined;\n\n\t// Listeners only needed while the connection is in progress\n\tprivate readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n\t// Listeners used throughout the lifetime of the DocumentDeltaConnection\n\tprivate readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n\tprotected get hasDetails(): boolean {\n\t\treturn !!this._details;\n\t}\n\n\tpublic get disposed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(\n\t\t\t\tthis._disposed || this.socket.connected,\n\t\t\t\t0x244 /* \"Socket is closed, but connection is not!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t\treturn this._disposed;\n\t}\n\n\t/**\n\t * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n\t * After disconnection, we flip this to prevent any stale messages from being emitted.\n\t */\n\tprotected _disposed: boolean = false;\n\tprivate readonly mc: MonitoringContext;\n\n\t/**\n\t * @deprecated Implementors should manage their own logger or monitoring context\n\t */\n\tprotected get logger(): ITelemetryLogger {\n\t\treturn this.mc.logger;\n\t}\n\n\tpublic get details(): IConnected {\n\t\tif (!this._details) {\n\t\t\tthrow new Error(\"Internal error: calling method before _details is initialized!\");\n\t\t}\n\t\treturn this._details;\n\t}\n\n\t/**\n\t * @param socket - websocket to be used\n\t * @param documentId - ID of the document\n\t * @param logger - for reporting telemetry events\n\t * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n\t */\n\tprotected constructor(\n\t\tprotected readonly socket: Socket,\n\t\tpublic documentId: string,\n\t\tlogger: ITelemetryLogger,\n\t\tprivate readonly enableLongPollingDowngrades: boolean = false,\n\t\tprotected readonly connectionId?: string,\n\t) {\n\t\tsuper((name, error) => {\n\t\t\tlogger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"DeltaConnection:EventException\",\n\t\t\t\t\tname,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(logger, \"DeltaConnection\"));\n\n\t\tthis.on(\"newListener\", (event, listener) => {\n\t\t\tassert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n\t\t\t// Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n\t\t\tif (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n\t\t\t\tassert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n\t\t\t\tthrow new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n\t\t\t}\n\n\t\t\t// Whenever listener is added, we should subscribe on same event on socket, so these two things\n\t\t\t// should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n\t\t\t// and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n\t\t\t// Better flow might be to always unconditionally register all handlers on successful connection,\n\t\t\t// though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n\t\t\tassert(\n\t\t\t\t(this.listeners(event).length !== 0) === this.trackedListeners.has(event),\n\t\t\t\t0x20b /* \"mismatch\" */,\n\t\t\t);\n\t\t\tif (!this.trackedListeners.has(event)) {\n\t\t\t\tthis.addTrackedListener(event, (...args: any[]) => {\n\t\t\t\t\tthis.emit(event, ...args);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Get the ID of the client who is sending the message\n\t *\n\t * @returns the client ID\n\t */\n\tpublic get clientId(): string {\n\t\treturn this.details.clientId;\n\t}\n\n\t/**\n\t * Get the mode of the client\n\t *\n\t * @returns the client mode\n\t */\n\tpublic get mode(): ConnectionMode {\n\t\treturn this.details.mode;\n\t}\n\n\t/**\n\t * Get the claims of the client who is sending the message\n\t *\n\t * @returns client claims\n\t */\n\tpublic get claims(): ITokenClaims {\n\t\treturn this.details.claims;\n\t}\n\n\t/**\n\t * Get whether or not this is an existing document\n\t *\n\t * @returns true if the document exists\n\t */\n\tpublic get existing(): boolean {\n\t\treturn this.details.existing;\n\t}\n\n\t/**\n\t * Get the maximum size of a message before chunking is required\n\t *\n\t * @returns the maximum size of a message before chunking is required\n\t */\n\tpublic get maxMessageSize(): number {\n\t\treturn this.details.serviceConfiguration.maxMessageSize;\n\t}\n\n\t/**\n\t * Semver of protocol being used with the service\n\t */\n\tpublic get version(): string {\n\t\treturn this.details.version;\n\t}\n\n\t/**\n\t * Configuration details provided by the service\n\t */\n\tpublic get serviceConfiguration(): IClientConfiguration {\n\t\treturn this.details.serviceConfiguration;\n\t}\n\n\tprivate checkNotClosed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(!this.disposed, 0x20c /* \"connection disposed\" */);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t}\n\n\t/**\n\t * Get messages sent during the connection\n\t *\n\t * @returns messages sent during the connection\n\t */\n\tpublic get initialMessages(): ISequencedDocumentMessage[] {\n\t\tthis.checkNotClosed();\n\n\t\t// If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n\t\t// latest ops. This could possibly indicate that initialMessages was called twice.\n\t\tassert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n\t\t// We will lose ops and perf will tank as we need to go to storage to become current!\n\t\tassert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n\t\tthis.removeEarlyOpHandler();\n\n\t\tif (this.queuedMessages.length > 0) {\n\t\t\t// Some messages were queued.\n\t\t\t// add them to the list of initialMessages to be processed\n\t\t\tthis.details.initialMessages.push(...this.queuedMessages);\n\t\t\tthis.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tthis.queuedMessages.length = 0;\n\t\t}\n\t\treturn this.details.initialMessages;\n\t}\n\n\t/**\n\t * Get signals sent during the connection\n\t *\n\t * @returns signals sent during the connection\n\t */\n\tpublic get initialSignals(): ISignalMessage[] {\n\t\tthis.checkNotClosed();\n\t\tassert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n\t\tthis.removeEarlySignalHandler();\n\n\t\tif (this.queuedSignals.length > 0) {\n\t\t\t// Some signals were queued.\n\t\t\t// add them to the list of initialSignals to be processed\n\t\t\tthis.details.initialSignals.push(...this.queuedSignals);\n\t\t\tthis.queuedSignals.length = 0;\n\t\t}\n\t\treturn this.details.initialSignals;\n\t}\n\n\t/**\n\t * Get initial client list\n\t *\n\t * @returns initial client list sent during the connection\n\t */\n\tpublic get initialClients(): ISignalClient[] {\n\t\tthis.checkNotClosed();\n\t\treturn this.details.initialClients;\n\t}\n\n\tprotected emitMessages(type: string, messages: IDocumentMessage[][]) {\n\t\t// Although the implementation here disconnects the socket and does not reuse it, other subclasses\n\t\t// (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n\t\t// on the still-live socket.\n\t\tif (!this.disposed) {\n\t\t\tthis.socket.emit(type, this.clientId, messages);\n\t\t}\n\t}\n\n\tprotected submitCore(type: string, messages: IDocumentMessage[]) {\n\t\tthis.emitMessages(type, [messages]);\n\t}\n\n\t/**\n\t * Submits a new delta operation to the server\n\t *\n\t * @param message - delta operation to submit\n\t */\n\tpublic submit(messages: IDocumentMessage[]): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitOp\", messages);\n\t}\n\n\t/**\n\t * Submits a new signal to the server\n\t *\n\t * @param message - signal to submit\n\t */\n\tpublic submitSignal(message: IDocumentMessage): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitSignal\", [message]);\n\t}\n\n\t/**\n\t * Disconnect from the websocket and close the websocket too.\n\t */\n\tprivate closeSocket(error: IAnyDriverError) {\n\t\tif (this._disposed) {\n\t\t\t// This would be rare situation due to complexity around socket emitting events.\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"SocketCloseOnDisposedConnection\",\n\t\t\t\t\tdriverVersion,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\t\t\ttrackedListenerCount: this.trackedListeners.size,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.closeSocketCore(error);\n\t}\n\n\tprotected closeSocketCore(error: IAnyDriverError) {\n\t\tthis.disconnect(error);\n\t}\n\n\t/**\n\t * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection and close the socket.\n\t * However the OdspDocumentDeltaConnection differ in dispose as in there we don't close the socket. There is no\n\t * multiplexing here, so we need to close the socket here.\n\t */\n\tpublic dispose() {\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"ClientClosingDeltaConnection\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t}),\n\t\t});\n\t\tthis.disconnect(\n\t\t\tcreateGenericNetworkError(\n\t\t\t\t// pre-0.58 error message: clientClosingConnection\n\t\t\t\t\"Client closing delta connection\",\n\t\t\t\t{ canRetry: true },\n\t\t\t\t{ driverVersion },\n\t\t\t),\n\t\t);\n\t}\n\n\tprotected disconnect(err: IAnyDriverError) {\n\t\t// Can't check this.disposed here, as we get here on socket closure,\n\t\t// so _disposed & socket.connected might be not in sync while processing\n\t\t// \"dispose\" event.\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n\t\t// DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n\t\t// important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n\t\t// OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n\t\t// to prevent normal messages from being emitted.\n\t\tthis._disposed = true;\n\n\t\t// Remove all listeners listening on the socket. These are listeners on socket and not on this connection\n\t\t// object. Anyway since we have disposed this connection object, nobody should listen to event on socket\n\t\t// anymore.\n\t\tthis.removeTrackedListeners();\n\n\t\t// Clear the connection/socket before letting the deltaManager/connection manager know about the disconnect.\n\t\tthis.disconnectCore();\n\n\t\t// Let user of connection object know about disconnect.\n\t\tthis.emit(\"disconnect\", err);\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"AfterDisconnectEvent\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\tdisconnectListenerCount: this.listenerCount(\"disconnect\"),\n\t\t\t}),\n\t\t});\n\t}\n\n\t/**\n\t * Disconnect from the websocket.\n\t * @param reason - reason for disconnect\n\t */\n\tprotected disconnectCore() {\n\t\tthis.socket.disconnect();\n\t}\n\n\tprotected async initialize(connectMessage: IConnect, timeout: number) {\n\t\tthis.socket.on(\"op\", this.earlyOpHandler);\n\t\tthis.socket.on(\"signal\", this.earlySignalHandler);\n\t\tthis.earlyOpHandlerAttached = true;\n\n\t\t// Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.\n\t\tlet internalSocketConnectionFailureCount: number = 0;\n\t\tconst isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();\n\t\tconst getMaxInternalSocketReconnectionAttempts = (): number =>\n\t\t\tisInternalSocketReconnectionEnabled() ? this.socket.io.reconnectionAttempts() : 0;\n\t\tconst getMaxAllowedInternalSocketConnectionFailures = (): number =>\n\t\t\tgetMaxInternalSocketReconnectionAttempts() + 1;\n\n\t\tthis._details = await new Promise<IConnected>((resolve, reject) => {\n\t\t\tconst failAndCloseSocket = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.closeSocket(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"CloseSocketError\" }, normalizedError);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tconst failConnection = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.disconnect(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t\t{ eventName: \"FailConnectionError\" },\n\t\t\t\t\t\tnormalizedError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\t// Immediately set the connection timeout.\n\t\t\t// Give extra 2 seconds for handshake on top of socket connection timeout.\n\t\t\tthis.socketConnectionTimeout = setTimeout(() => {\n\t\t\t\tfailConnection(this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n\t\t\t}, timeout + 2000);\n\n\t\t\t// Listen for connection issues\n\t\t\tthis.addConnectionListener(\"connect_error\", (error) => {\n\t\t\t\tinternalSocketConnectionFailureCount++;\n\t\t\t\tlet isWebSocketTransportError = false;\n\t\t\t\ttry {\n\t\t\t\t\tconst description = error?.description;\n\t\t\t\t\tconst context = error?.context;\n\n\t\t\t\t\tif (context && typeof context === \"object\") {\n\t\t\t\t\t\tconst statusText = context.statusText?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.context\n\t\t\t\t\t\tif (statusText === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (description && typeof description === \"object\") {\n\t\t\t\t\t\tconst errorCode = description.error?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.description\n\t\t\t\t\t\tif (errorCode === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (error.type === \"TransportError\") {\n\t\t\t\t\t\t\tisWebSocketTransportError = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// That's a WebSocket. Clear it as we can't log it.\n\t\t\t\t\t\tdescription.target = undefined;\n\t\t\t\t\t}\n\t\t\t\t} catch (_e) {}\n\n\t\t\t\t// Handle socket transport downgrading when not offline.\n\t\t\t\tif (\n\t\t\t\t\tisWebSocketTransportError &&\n\t\t\t\t\tthis.enableLongPollingDowngrades &&\n\t\t\t\t\tthis.socket.io.opts.transports?.[0] !== \"polling\"\n\t\t\t\t) {\n\t\t\t\t\t// Downgrade transports to polling upgrade mechanism.\n\t\t\t\t\tthis.socket.io.opts.transports = [\"polling\", \"websocket\"];\n\t\t\t\t\t// Don't alter reconnection behavior if already enabled.\n\t\t\t\t\tif (!isInternalSocketReconnectionEnabled()) {\n\t\t\t\t\t\t// Allow single reconnection attempt using polling upgrade mechanism.\n\t\t\t\t\t\tthis.socket.io.reconnection(true);\n\t\t\t\t\t\tthis.socket.io.reconnectionAttempts(1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Allow built-in socket.io reconnection handling.\n\t\t\t\tif (\n\t\t\t\t\tisInternalSocketReconnectionEnabled() &&\n\t\t\t\t\tinternalSocketConnectionFailureCount <\n\t\t\t\t\t\tgetMaxAllowedInternalSocketConnectionFailures()\n\t\t\t\t) {\n\t\t\t\t\t// Reconnection is enabled and maximum reconnect attempts have not been reached.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_error\", error));\n\t\t\t});\n\n\t\t\t// Listen for timeouts\n\t\t\tthis.addConnectionListener(\"connect_timeout\", () => {\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_timeout\"));\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst requestedMode = connectMessage.mode;\n\t\t\t\tconst actualMode = response.mode;\n\t\t\t\tconst writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n\t\t\t\tif (writingPermitted) {\n\t\t\t\t\t// The only time we expect a mismatch in requested/actual is if we lack write permissions\n\t\t\t\t\t// In this case we will get \"read\", even if we requested \"write\"\n\t\t\t\t\tif (actualMode !== requestedMode) {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in a different mode than was requested\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (actualMode === \"write\") {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in write mode without write permissions\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n\t\t\t\tthis.removeConnectionListeners();\n\t\t\t\tresolve(response);\n\t\t\t});\n\n\t\t\t// Socket can be disconnected while waiting for Fluid protocol messages\n\t\t\t// (connect_document_error / connect_document_success), as well as before DeltaManager\n\t\t\t// had a chance to register its handlers.\n\t\t\tthis.addTrackedListener(\"disconnect\", (reason) => {\n\t\t\t\tconst err = this.createErrorObject(\"disconnect\", reason);\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addTrackedListener(\"error\", (error) => {\n\t\t\t\t// This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n\t\t\t\tconst err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n\t\t\t\t// Disconnect socket - required if happened before initial handshake\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_error\", (error) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// This is not an socket.io error - it's Fluid protocol error.\n\t\t\t\t// In this case fail connection and indicate that we were unable to create connection\n\t\t\t\tfailConnection(this.createErrorObject(\"connect_document_error\", error));\n\t\t\t});\n\n\t\t\tthis.socket.emit(\"connect_document\", connectMessage);\n\t\t});\n\n\t\tassert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n\t}\n\n\tprivate addPropsToError(errorToBeNormalized: unknown) {\n\t\tconst normalizedError = normalizeError(errorToBeNormalized, {\n\t\t\tprops: {\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\t}),\n\t\t\t},\n\t\t});\n\t\treturn normalizedError;\n\t}\n\n\tprivate getConnectionDetailsProps() {\n\t\treturn {\n\t\t\tdisposed: this._disposed,\n\t\t\tsocketConnected: this.socket?.connected,\n\t\t\tclientId: this._details?.clientId,\n\t\t\tconnectionId: this.connectionId,\n\t\t};\n\t}\n\n\tprotected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n\t\tthis.queuedMessages.push(...msgs);\n\t};\n\n\tprotected earlySignalHandler = (msg: ISignalMessage) => {\n\t\tthis.queuedSignals.push(msg);\n\t};\n\n\tprivate removeEarlyOpHandler() {\n\t\tthis.socket.removeListener(\"op\", this.earlyOpHandler);\n\t\tthis.earlyOpHandlerAttached = false;\n\t}\n\n\tprivate removeEarlySignalHandler() {\n\t\tthis.socket.removeListener(\"signal\", this.earlySignalHandler);\n\t}\n\n\tprivate addConnectionListener(event: string, listener: (...args: any[]) => void) {\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n\t\t\t0x247 /* \"Use addTrackedListener instead\" */,\n\t\t);\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsToForward.includes(event),\n\t\t\t0x248 /* \"should not subscribe to forwarded events\" */,\n\t\t);\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n\t\tthis.connectionListeners.set(event, listener);\n\t}\n\n\tprotected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n\t\tthis.trackedListeners.set(event, listener);\n\t}\n\n\tprivate removeTrackedListeners() {\n\t\tfor (const [event, listener] of this.trackedListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\t// removeTrackedListeners removes all listeners, including connection listeners\n\t\tthis.removeConnectionListeners();\n\n\t\tthis.removeEarlyOpHandler();\n\t\tthis.removeEarlySignalHandler();\n\n\t\tthis.trackedListeners.clear();\n\t}\n\n\tprivate removeConnectionListeners() {\n\t\tif (this.socketConnectionTimeout !== undefined) {\n\t\t\tclearTimeout(this.socketConnectionTimeout);\n\t\t}\n\n\t\tfor (const [event, listener] of this.connectionListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\tthis.connectionListeners.clear();\n\t}\n\n\t/**\n\t * Error raising for socket.io issues\n\t */\n\tprotected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n\t\t// Note: we suspect the incoming error object is either:\n\t\t// - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n\t\t// - an Error object thrown by socket.io engine. Be careful with not recording PII!\n\t\tlet message: string;\n\t\tif (error?.type === \"TransportError\") {\n\t\t\t// JSON.stringify drops Error.message\n\t\t\tconst messagePrefix = error?.message !== undefined ? `${error.message}: ` : \"\";\n\n\t\t\t// Websocket errors reported by engine.io-client.\n\t\t\t// They are Error objects with description containing WS error and description = \"TransportError\"\n\t\t\t// Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n\t\t\tmessage = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n\t\t} else {\n\t\t\tmessage = extractLogSafeErrorProperties(error, true).message;\n\t\t}\n\n\t\tconst errorObj = createGenericNetworkError(\n\t\t\t`socket.io (${handler}): ${message}`,\n\t\t\t{ canRetry },\n\t\t\t{\n\t\t\t\tdriverVersion,\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\treturn errorObj;\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/driver-base";
8
- export declare const pkgVersion = "2.0.0-internal.3.3.1";
8
+ export declare const pkgVersion = "2.0.0-internal.3.4.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/driver-base";
11
- exports.pkgVersion = "2.0.0-internal.3.3.1";
11
+ exports.pkgVersion = "2.0.0-internal.3.4.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,6BAA6B,CAAC;AACxC,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/driver-base\";\nexport const pkgVersion = \"2.0.0-internal.3.3.1\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,6BAA6B,CAAC;AACxC,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/driver-base\";\nexport const pkgVersion = \"2.0.0-internal.3.4.0\";\n"]}
@@ -146,6 +146,7 @@ export declare class DocumentDeltaConnection extends EventEmitterWithErrorHandli
146
146
  protected disconnectCore(): void;
147
147
  protected initialize(connectMessage: IConnect, timeout: number): Promise<void>;
148
148
  private addPropsToError;
149
+ private getConnectionDetailsProps;
149
150
  protected earlyOpHandler: (documentId: string, msgs: ISequencedDocumentMessage[]) => void;
150
151
  protected earlySignalHandler: (msg: ISignalMessage) => void;
151
152
  private removeEarlyOpHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"documentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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"}
@@ -257,19 +257,12 @@ export class DocumentDeltaConnection extends EventEmitterWithErrorHandling {
257
257
  * Disconnect from the websocket and close the websocket too.
258
258
  */
259
259
  closeSocket(error) {
260
- var _a;
261
260
  if (this._disposed) {
262
261
  // This would be rare situation due to complexity around socket emitting events.
263
262
  this.logger.sendTelemetryEvent({
264
263
  eventName: "SocketCloseOnDisposedConnection",
265
264
  driverVersion,
266
- details: JSON.stringify({
267
- disposed: this._disposed,
268
- socketConnected: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected,
269
- trackedListenerCount: this.trackedListeners.size,
270
- clientId: this.clientId,
271
- connectionId: this.connectionId,
272
- }),
265
+ details: JSON.stringify(Object.assign(Object.assign({}, this.getConnectionDetailsProps()), { trackedListenerCount: this.trackedListeners.size })),
273
266
  }, error);
274
267
  return;
275
268
  }
@@ -284,16 +277,10 @@ export class DocumentDeltaConnection extends EventEmitterWithErrorHandling {
284
277
  * multiplexing here, so we need to close the socket here.
285
278
  */
286
279
  dispose() {
287
- var _a;
288
280
  this.logger.sendTelemetryEvent({
289
281
  eventName: "ClientClosingDeltaConnection",
290
282
  driverVersion,
291
- details: JSON.stringify({
292
- disposed: this._disposed,
293
- socketConnected: this.socket.connected,
294
- clientId: (_a = this._details) === null || _a === void 0 ? void 0 : _a.clientId,
295
- connectionId: this.connectionId,
296
- }),
283
+ details: JSON.stringify(Object.assign({}, this.getConnectionDetailsProps())),
297
284
  });
298
285
  this.disconnect(createGenericNetworkError(
299
286
  // pre-0.58 error message: clientClosingConnection
@@ -312,25 +299,19 @@ export class DocumentDeltaConnection extends EventEmitterWithErrorHandling {
312
299
  // OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended
313
300
  // to prevent normal messages from being emitted.
314
301
  this._disposed = true;
315
- // Let user of connection object know about disconnect. This has to happen in between setting _disposed and
316
- // removing all listeners!
302
+ // Remove all listeners listening on the socket. These are listeners on socket and not on this connection
303
+ // object. Anyway since we have disposed this connection object, nobody should listen to event on socket
304
+ // anymore.
305
+ this.removeTrackedListeners();
306
+ // Clear the connection/socket before letting the deltaManager/connection manager know about the disconnect.
307
+ this.disconnectCore();
308
+ // Let user of connection object know about disconnect.
317
309
  this.emit("disconnect", err);
318
310
  this.logger.sendTelemetryEvent({
319
311
  eventName: "AfterDisconnectEvent",
320
312
  driverVersion,
321
- details: JSON.stringify({
322
- disposed: this._disposed,
323
- clientId: this.clientId,
324
- socketConnected: this.socket.connected,
325
- disconnectListenerCount: this.listenerCount("disconnect"),
326
- connectionId: this.connectionId,
327
- }),
313
+ details: JSON.stringify(Object.assign(Object.assign({}, this.getConnectionDetailsProps()), { disconnectListenerCount: this.listenerCount("disconnect") })),
328
314
  });
329
- // user of DeltaConnection should have processed "disconnect" event and removed all listeners. Not clear
330
- // if we want to enforce that, as some users (like LocalDocumentService) do not unregister any handlers
331
- // assert(this.listenerCount("disconnect") === 0, "'disconnect` events should be processed synchronously");
332
- this.removeTrackedListeners();
333
- this.disconnectCore();
334
315
  }
335
316
  /**
336
317
  * Disconnect from the websocket.
@@ -488,19 +469,22 @@ export class DocumentDeltaConnection extends EventEmitterWithErrorHandling {
488
469
  assert(!this.disposed, 0x246 /* "checking consistency of socket & _disposed flags" */);
489
470
  }
490
471
  addPropsToError(errorToBeNormalized) {
491
- var _a, _b;
492
472
  const normalizedError = normalizeError(errorToBeNormalized, {
493
473
  props: {
494
- details: JSON.stringify({
495
- disposed: this._disposed,
496
- socketConnected: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected,
497
- clientId: (_b = this._details) === null || _b === void 0 ? void 0 : _b.clientId,
498
- conenctionId: this.connectionId,
499
- }),
474
+ details: JSON.stringify(Object.assign({}, this.getConnectionDetailsProps())),
500
475
  },
501
476
  });
502
477
  return normalizedError;
503
478
  }
479
+ getConnectionDetailsProps() {
480
+ var _a, _b;
481
+ return {
482
+ disposed: this._disposed,
483
+ socketConnected: (_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected,
484
+ clientId: (_b = this._details) === null || _b === void 0 ? void 0 : _b.clientId,
485
+ connectionId: this.connectionId,
486
+ };
487
+ }
504
488
  removeEarlyOpHandler() {
505
489
  this.socket.removeListener("op", this.earlyOpHandler);
506
490
  this.earlyOpHandlerAttached = false;
@@ -558,7 +542,10 @@ export class DocumentDeltaConnection extends EventEmitterWithErrorHandling {
558
542
  else {
559
543
  message = extractLogSafeErrorProperties(error, true).message;
560
544
  }
561
- const errorObj = createGenericNetworkError(`socket.io (${handler}): ${message}`, { canRetry }, { driverVersion });
545
+ const errorObj = createGenericNetworkError(`socket.io (${handler}): ${message}`, { canRetry }, {
546
+ driverVersion,
547
+ details: JSON.stringify(Object.assign({}, this.getConnectionDetailsProps())),
548
+ });
562
549
  return errorObj;
563
550
  }
564
551
  }
@@ -1 +1 @@
1
- {"version":3,"file":"documentDeltaConnection.js","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n\tIAnyDriverError,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } from \"@fluidframework/driver-utils\";\nimport {\n\tConnectionMode,\n\tIClientConfiguration,\n\tIConnect,\n\tIConnected,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tITokenClaims,\n\tScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n\tChildLogger,\n\textractLogSafeErrorProperties,\n\tgetCircularReplacer,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n\tEventEmitterWithErrorHandling,\n\tnormalizeError,\n} from \"@fluidframework/telemetry-utils\";\nimport type { Socket } from \"socket.io-client\";\n// For now, this package is versioned and released in unison with the specific drivers\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n/**\n * Represents a connection to a stream of delta updates\n */\nexport class DocumentDeltaConnection\n\textends EventEmitterWithErrorHandling<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\tstatic readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n\t// WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n\t// Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n\tstatic readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n\t/**\n\t * Last known sequence number to ordering service at the time of connection\n\t * It may lap actual last sequence number (quite a bit, if container is very active).\n\t * But it's best information for client to figure out how far it is behind, at least\n\t * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n\t * that is likely to be more up-to-date.\n\t */\n\tpublic checkpointSequenceNumber: number | undefined;\n\n\t// Listen for ops sent before we receive a response to connect_document\n\tprotected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n\tprotected readonly queuedSignals: ISignalMessage[] = [];\n\n\t/**\n\t * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n\t * to later be retrieved via initialMessages.\n\t */\n\tprivate earlyOpHandlerAttached: boolean = false;\n\n\tprivate socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n\tprivate _details: IConnected | undefined;\n\n\t// Listeners only needed while the connection is in progress\n\tprivate readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n\t// Listeners used throughout the lifetime of the DocumentDeltaConnection\n\tprivate readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n\tprotected get hasDetails(): boolean {\n\t\treturn !!this._details;\n\t}\n\n\tpublic get disposed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(\n\t\t\t\tthis._disposed || this.socket.connected,\n\t\t\t\t0x244 /* \"Socket is closed, but connection is not!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t\treturn this._disposed;\n\t}\n\n\t/**\n\t * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n\t * After disconnection, we flip this to prevent any stale messages from being emitted.\n\t */\n\tprotected _disposed: boolean = false;\n\tprivate readonly mc: MonitoringContext;\n\n\t/**\n\t * @deprecated Implementors should manage their own logger or monitoring context\n\t */\n\tprotected get logger(): ITelemetryLogger {\n\t\treturn this.mc.logger;\n\t}\n\n\tpublic get details(): IConnected {\n\t\tif (!this._details) {\n\t\t\tthrow new Error(\"Internal error: calling method before _details is initialized!\");\n\t\t}\n\t\treturn this._details;\n\t}\n\n\t/**\n\t * @param socket - websocket to be used\n\t * @param documentId - ID of the document\n\t * @param logger - for reporting telemetry events\n\t * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n\t */\n\tprotected constructor(\n\t\tprotected readonly socket: Socket,\n\t\tpublic documentId: string,\n\t\tlogger: ITelemetryLogger,\n\t\tprivate readonly enableLongPollingDowngrades: boolean = false,\n\t\tprotected readonly connectionId?: string,\n\t) {\n\t\tsuper((name, error) => {\n\t\t\tlogger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"DeltaConnection:EventException\",\n\t\t\t\t\tname,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(logger, \"DeltaConnection\"));\n\n\t\tthis.on(\"newListener\", (event, listener) => {\n\t\t\tassert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n\t\t\t// Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n\t\t\tif (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n\t\t\t\tassert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n\t\t\t\tthrow new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n\t\t\t}\n\n\t\t\t// Whenever listener is added, we should subscribe on same event on socket, so these two things\n\t\t\t// should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n\t\t\t// and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n\t\t\t// Better flow might be to always unconditionally register all handlers on successful connection,\n\t\t\t// though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n\t\t\tassert(\n\t\t\t\t(this.listeners(event).length !== 0) === this.trackedListeners.has(event),\n\t\t\t\t0x20b /* \"mismatch\" */,\n\t\t\t);\n\t\t\tif (!this.trackedListeners.has(event)) {\n\t\t\t\tthis.addTrackedListener(event, (...args: any[]) => {\n\t\t\t\t\tthis.emit(event, ...args);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Get the ID of the client who is sending the message\n\t *\n\t * @returns the client ID\n\t */\n\tpublic get clientId(): string {\n\t\treturn this.details.clientId;\n\t}\n\n\t/**\n\t * Get the mode of the client\n\t *\n\t * @returns the client mode\n\t */\n\tpublic get mode(): ConnectionMode {\n\t\treturn this.details.mode;\n\t}\n\n\t/**\n\t * Get the claims of the client who is sending the message\n\t *\n\t * @returns client claims\n\t */\n\tpublic get claims(): ITokenClaims {\n\t\treturn this.details.claims;\n\t}\n\n\t/**\n\t * Get whether or not this is an existing document\n\t *\n\t * @returns true if the document exists\n\t */\n\tpublic get existing(): boolean {\n\t\treturn this.details.existing;\n\t}\n\n\t/**\n\t * Get the maximum size of a message before chunking is required\n\t *\n\t * @returns the maximum size of a message before chunking is required\n\t */\n\tpublic get maxMessageSize(): number {\n\t\treturn this.details.serviceConfiguration.maxMessageSize;\n\t}\n\n\t/**\n\t * Semver of protocol being used with the service\n\t */\n\tpublic get version(): string {\n\t\treturn this.details.version;\n\t}\n\n\t/**\n\t * Configuration details provided by the service\n\t */\n\tpublic get serviceConfiguration(): IClientConfiguration {\n\t\treturn this.details.serviceConfiguration;\n\t}\n\n\tprivate checkNotClosed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(!this.disposed, 0x20c /* \"connection disposed\" */);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t}\n\n\t/**\n\t * Get messages sent during the connection\n\t *\n\t * @returns messages sent during the connection\n\t */\n\tpublic get initialMessages(): ISequencedDocumentMessage[] {\n\t\tthis.checkNotClosed();\n\n\t\t// If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n\t\t// latest ops. This could possibly indicate that initialMessages was called twice.\n\t\tassert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n\t\t// We will lose ops and perf will tank as we need to go to storage to become current!\n\t\tassert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n\t\tthis.removeEarlyOpHandler();\n\n\t\tif (this.queuedMessages.length > 0) {\n\t\t\t// Some messages were queued.\n\t\t\t// add them to the list of initialMessages to be processed\n\t\t\tthis.details.initialMessages.push(...this.queuedMessages);\n\t\t\tthis.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tthis.queuedMessages.length = 0;\n\t\t}\n\t\treturn this.details.initialMessages;\n\t}\n\n\t/**\n\t * Get signals sent during the connection\n\t *\n\t * @returns signals sent during the connection\n\t */\n\tpublic get initialSignals(): ISignalMessage[] {\n\t\tthis.checkNotClosed();\n\t\tassert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n\t\tthis.removeEarlySignalHandler();\n\n\t\tif (this.queuedSignals.length > 0) {\n\t\t\t// Some signals were queued.\n\t\t\t// add them to the list of initialSignals to be processed\n\t\t\tthis.details.initialSignals.push(...this.queuedSignals);\n\t\t\tthis.queuedSignals.length = 0;\n\t\t}\n\t\treturn this.details.initialSignals;\n\t}\n\n\t/**\n\t * Get initial client list\n\t *\n\t * @returns initial client list sent during the connection\n\t */\n\tpublic get initialClients(): ISignalClient[] {\n\t\tthis.checkNotClosed();\n\t\treturn this.details.initialClients;\n\t}\n\n\tprotected emitMessages(type: string, messages: IDocumentMessage[][]) {\n\t\t// Although the implementation here disconnects the socket and does not reuse it, other subclasses\n\t\t// (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n\t\t// on the still-live socket.\n\t\tif (!this.disposed) {\n\t\t\tthis.socket.emit(type, this.clientId, messages);\n\t\t}\n\t}\n\n\tprotected submitCore(type: string, messages: IDocumentMessage[]) {\n\t\tthis.emitMessages(type, [messages]);\n\t}\n\n\t/**\n\t * Submits a new delta operation to the server\n\t *\n\t * @param message - delta operation to submit\n\t */\n\tpublic submit(messages: IDocumentMessage[]): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitOp\", messages);\n\t}\n\n\t/**\n\t * Submits a new signal to the server\n\t *\n\t * @param message - signal to submit\n\t */\n\tpublic submitSignal(message: IDocumentMessage): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitSignal\", [message]);\n\t}\n\n\t/**\n\t * Disconnect from the websocket and close the websocket too.\n\t */\n\tprivate closeSocket(error: IAnyDriverError) {\n\t\tif (this._disposed) {\n\t\t\t// This would be rare situation due to complexity around socket emitting events.\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"SocketCloseOnDisposedConnection\",\n\t\t\t\t\tdriverVersion,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tdisposed: this._disposed,\n\t\t\t\t\t\tsocketConnected: this.socket?.connected,\n\t\t\t\t\t\ttrackedListenerCount: this.trackedListeners.size,\n\t\t\t\t\t\tclientId: this.clientId,\n\t\t\t\t\t\tconnectionId: this.connectionId,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.closeSocketCore(error);\n\t}\n\n\tprotected closeSocketCore(error: IAnyDriverError) {\n\t\tthis.disconnect(error);\n\t}\n\n\t/**\n\t * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection and close the socket.\n\t * However the OdspDocumentDeltaConnection differ in dispose as in there we don't close the socket. There is no\n\t * multiplexing here, so we need to close the socket here.\n\t */\n\tpublic dispose() {\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"ClientClosingDeltaConnection\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\tdisposed: this._disposed,\n\t\t\t\tsocketConnected: this.socket.connected,\n\t\t\t\tclientId: this._details?.clientId,\n\t\t\t\tconnectionId: this.connectionId,\n\t\t\t}),\n\t\t});\n\t\tthis.disconnect(\n\t\t\tcreateGenericNetworkError(\n\t\t\t\t// pre-0.58 error message: clientClosingConnection\n\t\t\t\t\"Client closing delta connection\",\n\t\t\t\t{ canRetry: true },\n\t\t\t\t{ driverVersion },\n\t\t\t),\n\t\t);\n\t}\n\n\tprotected disconnect(err: IAnyDriverError) {\n\t\t// Can't check this.disposed here, as we get here on socket closure,\n\t\t// so _disposed & socket.connected might be not in sync while processing\n\t\t// \"dispose\" event.\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n\t\t// DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n\t\t// important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n\t\t// OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n\t\t// to prevent normal messages from being emitted.\n\t\tthis._disposed = true;\n\n\t\t// Let user of connection object know about disconnect. This has to happen in between setting _disposed and\n\t\t// removing all listeners!\n\t\tthis.emit(\"disconnect\", err);\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"AfterDisconnectEvent\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\tdisposed: this._disposed,\n\t\t\t\tclientId: this.clientId,\n\t\t\t\tsocketConnected: this.socket.connected,\n\t\t\t\tdisconnectListenerCount: this.listenerCount(\"disconnect\"),\n\t\t\t\tconnectionId: this.connectionId,\n\t\t\t}),\n\t\t});\n\t\t// user of DeltaConnection should have processed \"disconnect\" event and removed all listeners. Not clear\n\t\t// if we want to enforce that, as some users (like LocalDocumentService) do not unregister any handlers\n\t\t// assert(this.listenerCount(\"disconnect\") === 0, \"'disconnect` events should be processed synchronously\");\n\n\t\tthis.removeTrackedListeners();\n\t\tthis.disconnectCore();\n\t}\n\n\t/**\n\t * Disconnect from the websocket.\n\t * @param reason - reason for disconnect\n\t */\n\tprotected disconnectCore() {\n\t\tthis.socket.disconnect();\n\t}\n\n\tprotected async initialize(connectMessage: IConnect, timeout: number) {\n\t\tthis.socket.on(\"op\", this.earlyOpHandler);\n\t\tthis.socket.on(\"signal\", this.earlySignalHandler);\n\t\tthis.earlyOpHandlerAttached = true;\n\n\t\t// Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.\n\t\tlet internalSocketConnectionFailureCount: number = 0;\n\t\tconst isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();\n\t\tconst getMaxInternalSocketReconnectionAttempts = (): number =>\n\t\t\tisInternalSocketReconnectionEnabled() ? this.socket.io.reconnectionAttempts() : 0;\n\t\tconst getMaxAllowedInternalSocketConnectionFailures = (): number =>\n\t\t\tgetMaxInternalSocketReconnectionAttempts() + 1;\n\n\t\tthis._details = await new Promise<IConnected>((resolve, reject) => {\n\t\t\tconst failAndCloseSocket = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.closeSocket(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"CloseSocketError\" }, normalizedError);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tconst failConnection = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.disconnect(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t\t{ eventName: \"FailConnectionError\" },\n\t\t\t\t\t\tnormalizedError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\t// Immediately set the connection timeout.\n\t\t\t// Give extra 2 seconds for handshake on top of socket connection timeout.\n\t\t\tthis.socketConnectionTimeout = setTimeout(() => {\n\t\t\t\tfailConnection(this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n\t\t\t}, timeout + 2000);\n\n\t\t\t// Listen for connection issues\n\t\t\tthis.addConnectionListener(\"connect_error\", (error) => {\n\t\t\t\tinternalSocketConnectionFailureCount++;\n\t\t\t\tlet isWebSocketTransportError = false;\n\t\t\t\ttry {\n\t\t\t\t\tconst description = error?.description;\n\t\t\t\t\tconst context = error?.context;\n\n\t\t\t\t\tif (context && typeof context === \"object\") {\n\t\t\t\t\t\tconst statusText = context.statusText?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.context\n\t\t\t\t\t\tif (statusText === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (description && typeof description === \"object\") {\n\t\t\t\t\t\tconst errorCode = description.error?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.description\n\t\t\t\t\t\tif (errorCode === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (error.type === \"TransportError\") {\n\t\t\t\t\t\t\tisWebSocketTransportError = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// That's a WebSocket. Clear it as we can't log it.\n\t\t\t\t\t\tdescription.target = undefined;\n\t\t\t\t\t}\n\t\t\t\t} catch (_e) {}\n\n\t\t\t\t// Handle socket transport downgrading when not offline.\n\t\t\t\tif (\n\t\t\t\t\tisWebSocketTransportError &&\n\t\t\t\t\tthis.enableLongPollingDowngrades &&\n\t\t\t\t\tthis.socket.io.opts.transports?.[0] !== \"polling\"\n\t\t\t\t) {\n\t\t\t\t\t// Downgrade transports to polling upgrade mechanism.\n\t\t\t\t\tthis.socket.io.opts.transports = [\"polling\", \"websocket\"];\n\t\t\t\t\t// Don't alter reconnection behavior if already enabled.\n\t\t\t\t\tif (!isInternalSocketReconnectionEnabled()) {\n\t\t\t\t\t\t// Allow single reconnection attempt using polling upgrade mechanism.\n\t\t\t\t\t\tthis.socket.io.reconnection(true);\n\t\t\t\t\t\tthis.socket.io.reconnectionAttempts(1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Allow built-in socket.io reconnection handling.\n\t\t\t\tif (\n\t\t\t\t\tisInternalSocketReconnectionEnabled() &&\n\t\t\t\t\tinternalSocketConnectionFailureCount <\n\t\t\t\t\t\tgetMaxAllowedInternalSocketConnectionFailures()\n\t\t\t\t) {\n\t\t\t\t\t// Reconnection is enabled and maximum reconnect attempts have not been reached.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_error\", error));\n\t\t\t});\n\n\t\t\t// Listen for timeouts\n\t\t\tthis.addConnectionListener(\"connect_timeout\", () => {\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_timeout\"));\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst requestedMode = connectMessage.mode;\n\t\t\t\tconst actualMode = response.mode;\n\t\t\t\tconst writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n\t\t\t\tif (writingPermitted) {\n\t\t\t\t\t// The only time we expect a mismatch in requested/actual is if we lack write permissions\n\t\t\t\t\t// In this case we will get \"read\", even if we requested \"write\"\n\t\t\t\t\tif (actualMode !== requestedMode) {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in a different mode than was requested\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (actualMode === \"write\") {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in write mode without write permissions\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n\t\t\t\tthis.removeConnectionListeners();\n\t\t\t\tresolve(response);\n\t\t\t});\n\n\t\t\t// Socket can be disconnected while waiting for Fluid protocol messages\n\t\t\t// (connect_document_error / connect_document_success), as well as before DeltaManager\n\t\t\t// had a chance to register its handlers.\n\t\t\tthis.addTrackedListener(\"disconnect\", (reason) => {\n\t\t\t\tconst err = this.createErrorObject(\"disconnect\", reason);\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addTrackedListener(\"error\", (error) => {\n\t\t\t\t// This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n\t\t\t\tconst err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n\t\t\t\t// Disconnect socket - required if happened before initial handshake\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_error\", (error) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// This is not an socket.io error - it's Fluid protocol error.\n\t\t\t\t// In this case fail connection and indicate that we were unable to create connection\n\t\t\t\tfailConnection(this.createErrorObject(\"connect_document_error\", error));\n\t\t\t});\n\n\t\t\tthis.socket.emit(\"connect_document\", connectMessage);\n\t\t});\n\n\t\tassert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n\t}\n\n\tprivate addPropsToError(errorToBeNormalized: unknown) {\n\t\tconst normalizedError = normalizeError(errorToBeNormalized, {\n\t\t\tprops: {\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\tdisposed: this._disposed,\n\t\t\t\t\tsocketConnected: this.socket?.connected,\n\t\t\t\t\tclientId: this._details?.clientId,\n\t\t\t\t\tconenctionId: this.connectionId,\n\t\t\t\t}),\n\t\t\t},\n\t\t});\n\t\treturn normalizedError;\n\t}\n\n\tprotected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n\t\tthis.queuedMessages.push(...msgs);\n\t};\n\n\tprotected earlySignalHandler = (msg: ISignalMessage) => {\n\t\tthis.queuedSignals.push(msg);\n\t};\n\n\tprivate removeEarlyOpHandler() {\n\t\tthis.socket.removeListener(\"op\", this.earlyOpHandler);\n\t\tthis.earlyOpHandlerAttached = false;\n\t}\n\n\tprivate removeEarlySignalHandler() {\n\t\tthis.socket.removeListener(\"signal\", this.earlySignalHandler);\n\t}\n\n\tprivate addConnectionListener(event: string, listener: (...args: any[]) => void) {\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n\t\t\t0x247 /* \"Use addTrackedListener instead\" */,\n\t\t);\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsToForward.includes(event),\n\t\t\t0x248 /* \"should not subscribe to forwarded events\" */,\n\t\t);\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n\t\tthis.connectionListeners.set(event, listener);\n\t}\n\n\tprotected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n\t\tthis.trackedListeners.set(event, listener);\n\t}\n\n\tprivate removeTrackedListeners() {\n\t\tfor (const [event, listener] of this.trackedListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\t// removeTrackedListeners removes all listeners, including connection listeners\n\t\tthis.removeConnectionListeners();\n\n\t\tthis.removeEarlyOpHandler();\n\t\tthis.removeEarlySignalHandler();\n\n\t\tthis.trackedListeners.clear();\n\t}\n\n\tprivate removeConnectionListeners() {\n\t\tif (this.socketConnectionTimeout !== undefined) {\n\t\t\tclearTimeout(this.socketConnectionTimeout);\n\t\t}\n\n\t\tfor (const [event, listener] of this.connectionListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\tthis.connectionListeners.clear();\n\t}\n\n\t/**\n\t * Error raising for socket.io issues\n\t */\n\tprotected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n\t\t// Note: we suspect the incoming error object is either:\n\t\t// - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n\t\t// - an Error object thrown by socket.io engine. Be careful with not recording PII!\n\t\tlet message: string;\n\t\tif (error?.type === \"TransportError\") {\n\t\t\t// JSON.stringify drops Error.message\n\t\t\tconst messagePrefix = error?.message !== undefined ? `${error.message}: ` : \"\";\n\n\t\t\t// Websocket errors reported by engine.io-client.\n\t\t\t// They are Error objects with description containing WS error and description = \"TransportError\"\n\t\t\t// Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n\t\t\tmessage = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n\t\t} else {\n\t\t\tmessage = extractLogSafeErrorProperties(error, true).message;\n\t\t}\n\n\t\tconst errorObj = createGenericNetworkError(\n\t\t\t`socket.io (${handler}): ${message}`,\n\t\t\t{ canRetry },\n\t\t\t{ driverVersion },\n\t\t);\n\n\t\treturn errorObj;\n\t}\n}\n"]}
1
+ {"version":3,"file":"documentDeltaConnection.js","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n\tIAnyDriverError,\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } from \"@fluidframework/driver-utils\";\nimport {\n\tConnectionMode,\n\tIClientConfiguration,\n\tIConnect,\n\tIConnected,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tITokenClaims,\n\tScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n\tChildLogger,\n\textractLogSafeErrorProperties,\n\tgetCircularReplacer,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n\tEventEmitterWithErrorHandling,\n\tnormalizeError,\n} from \"@fluidframework/telemetry-utils\";\nimport type { Socket } from \"socket.io-client\";\n// For now, this package is versioned and released in unison with the specific drivers\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n/**\n * Represents a connection to a stream of delta updates\n */\nexport class DocumentDeltaConnection\n\textends EventEmitterWithErrorHandling<IDocumentDeltaConnectionEvents>\n\timplements IDocumentDeltaConnection, IDisposable\n{\n\tstatic readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n\t// WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n\t// Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n\tstatic readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n\t/**\n\t * Last known sequence number to ordering service at the time of connection\n\t * It may lap actual last sequence number (quite a bit, if container is very active).\n\t * But it's best information for client to figure out how far it is behind, at least\n\t * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n\t * that is likely to be more up-to-date.\n\t */\n\tpublic checkpointSequenceNumber: number | undefined;\n\n\t// Listen for ops sent before we receive a response to connect_document\n\tprotected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n\tprotected readonly queuedSignals: ISignalMessage[] = [];\n\n\t/**\n\t * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n\t * to later be retrieved via initialMessages.\n\t */\n\tprivate earlyOpHandlerAttached: boolean = false;\n\n\tprivate socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n\tprivate _details: IConnected | undefined;\n\n\t// Listeners only needed while the connection is in progress\n\tprivate readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n\t// Listeners used throughout the lifetime of the DocumentDeltaConnection\n\tprivate readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n\tprotected get hasDetails(): boolean {\n\t\treturn !!this._details;\n\t}\n\n\tpublic get disposed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(\n\t\t\t\tthis._disposed || this.socket.connected,\n\t\t\t\t0x244 /* \"Socket is closed, but connection is not!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t\treturn this._disposed;\n\t}\n\n\t/**\n\t * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n\t * After disconnection, we flip this to prevent any stale messages from being emitted.\n\t */\n\tprotected _disposed: boolean = false;\n\tprivate readonly mc: MonitoringContext;\n\n\t/**\n\t * @deprecated Implementors should manage their own logger or monitoring context\n\t */\n\tprotected get logger(): ITelemetryLogger {\n\t\treturn this.mc.logger;\n\t}\n\n\tpublic get details(): IConnected {\n\t\tif (!this._details) {\n\t\t\tthrow new Error(\"Internal error: calling method before _details is initialized!\");\n\t\t}\n\t\treturn this._details;\n\t}\n\n\t/**\n\t * @param socket - websocket to be used\n\t * @param documentId - ID of the document\n\t * @param logger - for reporting telemetry events\n\t * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n\t */\n\tprotected constructor(\n\t\tprotected readonly socket: Socket,\n\t\tpublic documentId: string,\n\t\tlogger: ITelemetryLogger,\n\t\tprivate readonly enableLongPollingDowngrades: boolean = false,\n\t\tprotected readonly connectionId?: string,\n\t) {\n\t\tsuper((name, error) => {\n\t\t\tlogger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"DeltaConnection:EventException\",\n\t\t\t\t\tname,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(logger, \"DeltaConnection\"));\n\n\t\tthis.on(\"newListener\", (event, listener) => {\n\t\t\tassert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n\t\t\t// Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n\t\t\tif (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n\t\t\t\tassert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n\t\t\t\tthrow new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n\t\t\t}\n\n\t\t\t// Whenever listener is added, we should subscribe on same event on socket, so these two things\n\t\t\t// should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n\t\t\t// and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n\t\t\t// Better flow might be to always unconditionally register all handlers on successful connection,\n\t\t\t// though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n\t\t\tassert(\n\t\t\t\t(this.listeners(event).length !== 0) === this.trackedListeners.has(event),\n\t\t\t\t0x20b /* \"mismatch\" */,\n\t\t\t);\n\t\t\tif (!this.trackedListeners.has(event)) {\n\t\t\t\tthis.addTrackedListener(event, (...args: any[]) => {\n\t\t\t\t\tthis.emit(event, ...args);\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Get the ID of the client who is sending the message\n\t *\n\t * @returns the client ID\n\t */\n\tpublic get clientId(): string {\n\t\treturn this.details.clientId;\n\t}\n\n\t/**\n\t * Get the mode of the client\n\t *\n\t * @returns the client mode\n\t */\n\tpublic get mode(): ConnectionMode {\n\t\treturn this.details.mode;\n\t}\n\n\t/**\n\t * Get the claims of the client who is sending the message\n\t *\n\t * @returns client claims\n\t */\n\tpublic get claims(): ITokenClaims {\n\t\treturn this.details.claims;\n\t}\n\n\t/**\n\t * Get whether or not this is an existing document\n\t *\n\t * @returns true if the document exists\n\t */\n\tpublic get existing(): boolean {\n\t\treturn this.details.existing;\n\t}\n\n\t/**\n\t * Get the maximum size of a message before chunking is required\n\t *\n\t * @returns the maximum size of a message before chunking is required\n\t */\n\tpublic get maxMessageSize(): number {\n\t\treturn this.details.serviceConfiguration.maxMessageSize;\n\t}\n\n\t/**\n\t * Semver of protocol being used with the service\n\t */\n\tpublic get version(): string {\n\t\treturn this.details.version;\n\t}\n\n\t/**\n\t * Configuration details provided by the service\n\t */\n\tpublic get serviceConfiguration(): IClientConfiguration {\n\t\treturn this.details.serviceConfiguration;\n\t}\n\n\tprivate checkNotClosed() {\n\t\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\t\t// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\ttry {\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tassert(!this.disposed, 0x20c /* \"connection disposed\" */);\n\t\t} catch (error) {\n\t\t\tconst normalizedError = this.addPropsToError(error);\n\t\t\tthrow normalizedError;\n\t\t} finally {\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\t}\n\n\t/**\n\t * Get messages sent during the connection\n\t *\n\t * @returns messages sent during the connection\n\t */\n\tpublic get initialMessages(): ISequencedDocumentMessage[] {\n\t\tthis.checkNotClosed();\n\n\t\t// If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n\t\t// latest ops. This could possibly indicate that initialMessages was called twice.\n\t\tassert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n\t\t// We will lose ops and perf will tank as we need to go to storage to become current!\n\t\tassert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n\t\tthis.removeEarlyOpHandler();\n\n\t\tif (this.queuedMessages.length > 0) {\n\t\t\t// Some messages were queued.\n\t\t\t// add them to the list of initialMessages to be processed\n\t\t\tthis.details.initialMessages.push(...this.queuedMessages);\n\t\t\tthis.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tthis.queuedMessages.length = 0;\n\t\t}\n\t\treturn this.details.initialMessages;\n\t}\n\n\t/**\n\t * Get signals sent during the connection\n\t *\n\t * @returns signals sent during the connection\n\t */\n\tpublic get initialSignals(): ISignalMessage[] {\n\t\tthis.checkNotClosed();\n\t\tassert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n\t\tthis.removeEarlySignalHandler();\n\n\t\tif (this.queuedSignals.length > 0) {\n\t\t\t// Some signals were queued.\n\t\t\t// add them to the list of initialSignals to be processed\n\t\t\tthis.details.initialSignals.push(...this.queuedSignals);\n\t\t\tthis.queuedSignals.length = 0;\n\t\t}\n\t\treturn this.details.initialSignals;\n\t}\n\n\t/**\n\t * Get initial client list\n\t *\n\t * @returns initial client list sent during the connection\n\t */\n\tpublic get initialClients(): ISignalClient[] {\n\t\tthis.checkNotClosed();\n\t\treturn this.details.initialClients;\n\t}\n\n\tprotected emitMessages(type: string, messages: IDocumentMessage[][]) {\n\t\t// Although the implementation here disconnects the socket and does not reuse it, other subclasses\n\t\t// (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n\t\t// on the still-live socket.\n\t\tif (!this.disposed) {\n\t\t\tthis.socket.emit(type, this.clientId, messages);\n\t\t}\n\t}\n\n\tprotected submitCore(type: string, messages: IDocumentMessage[]) {\n\t\tthis.emitMessages(type, [messages]);\n\t}\n\n\t/**\n\t * Submits a new delta operation to the server\n\t *\n\t * @param message - delta operation to submit\n\t */\n\tpublic submit(messages: IDocumentMessage[]): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitOp\", messages);\n\t}\n\n\t/**\n\t * Submits a new signal to the server\n\t *\n\t * @param message - signal to submit\n\t */\n\tpublic submitSignal(message: IDocumentMessage): void {\n\t\tthis.checkNotClosed();\n\t\tthis.submitCore(\"submitSignal\", [message]);\n\t}\n\n\t/**\n\t * Disconnect from the websocket and close the websocket too.\n\t */\n\tprivate closeSocket(error: IAnyDriverError) {\n\t\tif (this._disposed) {\n\t\t\t// This would be rare situation due to complexity around socket emitting events.\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"SocketCloseOnDisposedConnection\",\n\t\t\t\t\tdriverVersion,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\t\t\ttrackedListenerCount: this.trackedListeners.size,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.closeSocketCore(error);\n\t}\n\n\tprotected closeSocketCore(error: IAnyDriverError) {\n\t\tthis.disconnect(error);\n\t}\n\n\t/**\n\t * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection and close the socket.\n\t * However the OdspDocumentDeltaConnection differ in dispose as in there we don't close the socket. There is no\n\t * multiplexing here, so we need to close the socket here.\n\t */\n\tpublic dispose() {\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"ClientClosingDeltaConnection\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t}),\n\t\t});\n\t\tthis.disconnect(\n\t\t\tcreateGenericNetworkError(\n\t\t\t\t// pre-0.58 error message: clientClosingConnection\n\t\t\t\t\"Client closing delta connection\",\n\t\t\t\t{ canRetry: true },\n\t\t\t\t{ driverVersion },\n\t\t\t),\n\t\t);\n\t}\n\n\tprotected disconnect(err: IAnyDriverError) {\n\t\t// Can't check this.disposed here, as we get here on socket closure,\n\t\t// so _disposed & socket.connected might be not in sync while processing\n\t\t// \"dispose\" event.\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n\t\t// DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n\t\t// important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n\t\t// OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n\t\t// to prevent normal messages from being emitted.\n\t\tthis._disposed = true;\n\n\t\t// Remove all listeners listening on the socket. These are listeners on socket and not on this connection\n\t\t// object. Anyway since we have disposed this connection object, nobody should listen to event on socket\n\t\t// anymore.\n\t\tthis.removeTrackedListeners();\n\n\t\t// Clear the connection/socket before letting the deltaManager/connection manager know about the disconnect.\n\t\tthis.disconnectCore();\n\n\t\t// Let user of connection object know about disconnect.\n\t\tthis.emit(\"disconnect\", err);\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"AfterDisconnectEvent\",\n\t\t\tdriverVersion,\n\t\t\tdetails: JSON.stringify({\n\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\tdisconnectListenerCount: this.listenerCount(\"disconnect\"),\n\t\t\t}),\n\t\t});\n\t}\n\n\t/**\n\t * Disconnect from the websocket.\n\t * @param reason - reason for disconnect\n\t */\n\tprotected disconnectCore() {\n\t\tthis.socket.disconnect();\n\t}\n\n\tprotected async initialize(connectMessage: IConnect, timeout: number) {\n\t\tthis.socket.on(\"op\", this.earlyOpHandler);\n\t\tthis.socket.on(\"signal\", this.earlySignalHandler);\n\t\tthis.earlyOpHandlerAttached = true;\n\n\t\t// Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.\n\t\tlet internalSocketConnectionFailureCount: number = 0;\n\t\tconst isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();\n\t\tconst getMaxInternalSocketReconnectionAttempts = (): number =>\n\t\t\tisInternalSocketReconnectionEnabled() ? this.socket.io.reconnectionAttempts() : 0;\n\t\tconst getMaxAllowedInternalSocketConnectionFailures = (): number =>\n\t\t\tgetMaxInternalSocketReconnectionAttempts() + 1;\n\n\t\tthis._details = await new Promise<IConnected>((resolve, reject) => {\n\t\t\tconst failAndCloseSocket = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.closeSocket(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"CloseSocketError\" }, normalizedError);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tconst failConnection = (err: IAnyDriverError) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.disconnect(err);\n\t\t\t\t} catch (failError) {\n\t\t\t\t\tconst normalizedError = this.addPropsToError(failError);\n\t\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t\t{ eventName: \"FailConnectionError\" },\n\t\t\t\t\t\tnormalizedError,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\t// Immediately set the connection timeout.\n\t\t\t// Give extra 2 seconds for handshake on top of socket connection timeout.\n\t\t\tthis.socketConnectionTimeout = setTimeout(() => {\n\t\t\t\tfailConnection(this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n\t\t\t}, timeout + 2000);\n\n\t\t\t// Listen for connection issues\n\t\t\tthis.addConnectionListener(\"connect_error\", (error) => {\n\t\t\t\tinternalSocketConnectionFailureCount++;\n\t\t\t\tlet isWebSocketTransportError = false;\n\t\t\t\ttry {\n\t\t\t\t\tconst description = error?.description;\n\t\t\t\t\tconst context = error?.context;\n\n\t\t\t\t\tif (context && typeof context === \"object\") {\n\t\t\t\t\t\tconst statusText = context.statusText?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.context\n\t\t\t\t\t\tif (statusText === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (description && typeof description === \"object\") {\n\t\t\t\t\t\tconst errorCode = description.error?.code;\n\n\t\t\t\t\t\t// Self-Signed Certificate ErrorCode Found in error.description\n\t\t\t\t\t\tif (errorCode === \"DEPTH_ZERO_SELF_SIGNED_CERT\") {\n\t\t\t\t\t\t\tfailAndCloseSocket(\n\t\t\t\t\t\t\t\tthis.createErrorObject(\"connect_error\", error, false),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (error.type === \"TransportError\") {\n\t\t\t\t\t\t\tisWebSocketTransportError = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// That's a WebSocket. Clear it as we can't log it.\n\t\t\t\t\t\tdescription.target = undefined;\n\t\t\t\t\t}\n\t\t\t\t} catch (_e) {}\n\n\t\t\t\t// Handle socket transport downgrading when not offline.\n\t\t\t\tif (\n\t\t\t\t\tisWebSocketTransportError &&\n\t\t\t\t\tthis.enableLongPollingDowngrades &&\n\t\t\t\t\tthis.socket.io.opts.transports?.[0] !== \"polling\"\n\t\t\t\t) {\n\t\t\t\t\t// Downgrade transports to polling upgrade mechanism.\n\t\t\t\t\tthis.socket.io.opts.transports = [\"polling\", \"websocket\"];\n\t\t\t\t\t// Don't alter reconnection behavior if already enabled.\n\t\t\t\t\tif (!isInternalSocketReconnectionEnabled()) {\n\t\t\t\t\t\t// Allow single reconnection attempt using polling upgrade mechanism.\n\t\t\t\t\t\tthis.socket.io.reconnection(true);\n\t\t\t\t\t\tthis.socket.io.reconnectionAttempts(1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Allow built-in socket.io reconnection handling.\n\t\t\t\tif (\n\t\t\t\t\tisInternalSocketReconnectionEnabled() &&\n\t\t\t\t\tinternalSocketConnectionFailureCount <\n\t\t\t\t\t\tgetMaxAllowedInternalSocketConnectionFailures()\n\t\t\t\t) {\n\t\t\t\t\t// Reconnection is enabled and maximum reconnect attempts have not been reached.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_error\", error));\n\t\t\t});\n\n\t\t\t// Listen for timeouts\n\t\t\tthis.addConnectionListener(\"connect_timeout\", () => {\n\t\t\t\tfailAndCloseSocket(this.createErrorObject(\"connect_timeout\"));\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== undefined &&\n\t\t\t\t\tresponse.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst requestedMode = connectMessage.mode;\n\t\t\t\tconst actualMode = response.mode;\n\t\t\t\tconst writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n\t\t\t\tif (writingPermitted) {\n\t\t\t\t\t// The only time we expect a mismatch in requested/actual is if we lack write permissions\n\t\t\t\t\t// In this case we will get \"read\", even if we requested \"write\"\n\t\t\t\t\tif (actualMode !== requestedMode) {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in a different mode than was requested\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (actualMode === \"write\") {\n\t\t\t\t\t\tfailConnection(\n\t\t\t\t\t\t\tthis.createErrorObject(\n\t\t\t\t\t\t\t\t\"connect_document_success\",\n\t\t\t\t\t\t\t\t\"Connected in write mode without write permissions\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n\t\t\t\tthis.removeConnectionListeners();\n\t\t\t\tresolve(response);\n\t\t\t});\n\n\t\t\t// Socket can be disconnected while waiting for Fluid protocol messages\n\t\t\t// (connect_document_error / connect_document_success), as well as before DeltaManager\n\t\t\t// had a chance to register its handlers.\n\t\t\tthis.addTrackedListener(\"disconnect\", (reason) => {\n\t\t\t\tconst err = this.createErrorObject(\"disconnect\", reason);\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addTrackedListener(\"error\", (error) => {\n\t\t\t\t// This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n\t\t\t\tconst err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n\t\t\t\t// Disconnect socket - required if happened before initial handshake\n\t\t\t\tfailAndCloseSocket(err);\n\t\t\t});\n\n\t\t\tthis.addConnectionListener(\"connect_document_error\", (error) => {\n\t\t\t\t// If we sent a nonce and the server supports nonces, check that the nonces match\n\t\t\t\tif (\n\t\t\t\t\tconnectMessage.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== undefined &&\n\t\t\t\t\terror.nonce !== connectMessage.nonce\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// This is not an socket.io error - it's Fluid protocol error.\n\t\t\t\t// In this case fail connection and indicate that we were unable to create connection\n\t\t\t\tfailConnection(this.createErrorObject(\"connect_document_error\", error));\n\t\t\t});\n\n\t\t\tthis.socket.emit(\"connect_document\", connectMessage);\n\t\t});\n\n\t\tassert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n\t}\n\n\tprivate addPropsToError(errorToBeNormalized: unknown) {\n\t\tconst normalizedError = normalizeError(errorToBeNormalized, {\n\t\t\tprops: {\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\t}),\n\t\t\t},\n\t\t});\n\t\treturn normalizedError;\n\t}\n\n\tprivate getConnectionDetailsProps() {\n\t\treturn {\n\t\t\tdisposed: this._disposed,\n\t\t\tsocketConnected: this.socket?.connected,\n\t\t\tclientId: this._details?.clientId,\n\t\t\tconnectionId: this.connectionId,\n\t\t};\n\t}\n\n\tprotected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n\t\tthis.queuedMessages.push(...msgs);\n\t};\n\n\tprotected earlySignalHandler = (msg: ISignalMessage) => {\n\t\tthis.queuedSignals.push(msg);\n\t};\n\n\tprivate removeEarlyOpHandler() {\n\t\tthis.socket.removeListener(\"op\", this.earlyOpHandler);\n\t\tthis.earlyOpHandlerAttached = false;\n\t}\n\n\tprivate removeEarlySignalHandler() {\n\t\tthis.socket.removeListener(\"signal\", this.earlySignalHandler);\n\t}\n\n\tprivate addConnectionListener(event: string, listener: (...args: any[]) => void) {\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n\t\t\t0x247 /* \"Use addTrackedListener instead\" */,\n\t\t);\n\t\tassert(\n\t\t\t!DocumentDeltaConnection.eventsToForward.includes(event),\n\t\t\t0x248 /* \"should not subscribe to forwarded events\" */,\n\t\t);\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n\t\tthis.connectionListeners.set(event, listener);\n\t}\n\n\tprotected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n\t\tthis.socket.on(event, listener);\n\t\tassert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n\t\tthis.trackedListeners.set(event, listener);\n\t}\n\n\tprivate removeTrackedListeners() {\n\t\tfor (const [event, listener] of this.trackedListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\t// removeTrackedListeners removes all listeners, including connection listeners\n\t\tthis.removeConnectionListeners();\n\n\t\tthis.removeEarlyOpHandler();\n\t\tthis.removeEarlySignalHandler();\n\n\t\tthis.trackedListeners.clear();\n\t}\n\n\tprivate removeConnectionListeners() {\n\t\tif (this.socketConnectionTimeout !== undefined) {\n\t\t\tclearTimeout(this.socketConnectionTimeout);\n\t\t}\n\n\t\tfor (const [event, listener] of this.connectionListeners.entries()) {\n\t\t\tthis.socket.off(event, listener);\n\t\t}\n\t\tthis.connectionListeners.clear();\n\t}\n\n\t/**\n\t * Error raising for socket.io issues\n\t */\n\tprotected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n\t\t// Note: we suspect the incoming error object is either:\n\t\t// - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n\t\t// - an Error object thrown by socket.io engine. Be careful with not recording PII!\n\t\tlet message: string;\n\t\tif (error?.type === \"TransportError\") {\n\t\t\t// JSON.stringify drops Error.message\n\t\t\tconst messagePrefix = error?.message !== undefined ? `${error.message}: ` : \"\";\n\n\t\t\t// Websocket errors reported by engine.io-client.\n\t\t\t// They are Error objects with description containing WS error and description = \"TransportError\"\n\t\t\t// Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n\t\t\tmessage = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n\t\t} else {\n\t\t\tmessage = extractLogSafeErrorProperties(error, true).message;\n\t\t}\n\n\t\tconst errorObj = createGenericNetworkError(\n\t\t\t`socket.io (${handler}): ${message}`,\n\t\t\t{ canRetry },\n\t\t\t{\n\t\t\t\tdriverVersion,\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t...this.getConnectionDetailsProps(),\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\treturn errorObj;\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/driver-base";
8
- export declare const pkgVersion = "2.0.0-internal.3.3.1";
8
+ export declare const pkgVersion = "2.0.0-internal.3.4.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/driver-base";
8
- export const pkgVersion = "2.0.0-internal.3.3.1";
8
+ export const pkgVersion = "2.0.0-internal.3.4.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,6BAA6B,CAAC;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/driver-base\";\nexport const pkgVersion = \"2.0.0-internal.3.3.1\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,6BAA6B,CAAC;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/driver-base\";\nexport const pkgVersion = \"2.0.0-internal.3.4.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/driver-base",
3
- "version": "2.0.0-internal.3.3.1",
3
+ "version": "2.0.0-internal.3.4.0",
4
4
  "description": "Shared driver code for Fluid driver implementations",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -17,25 +17,24 @@
17
17
  "dependencies": {
18
18
  "@fluidframework/common-definitions": "^0.20.1",
19
19
  "@fluidframework/common-utils": "^1.1.1",
20
- "@fluidframework/driver-definitions": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
21
- "@fluidframework/driver-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0",
20
+ "@fluidframework/driver-definitions": "^2.0.0-internal.3.4.0",
21
+ "@fluidframework/driver-utils": "^2.0.0-internal.3.4.0",
22
22
  "@fluidframework/protocol-definitions": "^1.1.0",
23
- "@fluidframework/telemetry-utils": ">=2.0.0-internal.3.3.1 <2.0.0-internal.4.0.0"
23
+ "@fluidframework/telemetry-utils": "^2.0.0-internal.3.4.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@fluid-tools/build-cli": "^0.12.0",
26
+ "@fluid-tools/build-cli": "^0.13.0",
27
27
  "@fluidframework/build-common": "^1.1.0",
28
- "@fluidframework/build-tools": "^0.12.0",
28
+ "@fluidframework/build-tools": "^0.13.0",
29
29
  "@fluidframework/driver-base-previous": "npm:@fluidframework/driver-base@2.0.0-internal.3.2.0",
30
30
  "@fluidframework/eslint-config-fluid": "^2.0.0",
31
- "@microsoft/api-extractor": "^7.22.2",
32
- "@rushstack/eslint-config": "^2.5.1",
33
- "@types/node": "^14.18.36",
34
- "concurrently": "^6.2.0",
31
+ "@microsoft/api-extractor": "^7.34.4",
32
+ "@types/node": "^14.18.38",
33
+ "concurrently": "^7.6.0",
35
34
  "copyfiles": "^2.4.1",
36
35
  "eslint": "~8.6.0",
37
36
  "prettier": "~2.6.2",
38
- "rimraf": "^2.6.2",
37
+ "rimraf": "^4.4.0",
39
38
  "socket.io-client": "^4.4.1",
40
39
  "typescript": "~4.5.5"
41
40
  },
@@ -350,11 +350,8 @@ export class DocumentDeltaConnection
350
350
  eventName: "SocketCloseOnDisposedConnection",
351
351
  driverVersion,
352
352
  details: JSON.stringify({
353
- disposed: this._disposed,
354
- socketConnected: this.socket?.connected,
353
+ ...this.getConnectionDetailsProps(),
355
354
  trackedListenerCount: this.trackedListeners.size,
356
- clientId: this.clientId,
357
- connectionId: this.connectionId,
358
355
  }),
359
356
  },
360
357
  error,
@@ -378,10 +375,7 @@ export class DocumentDeltaConnection
378
375
  eventName: "ClientClosingDeltaConnection",
379
376
  driverVersion,
380
377
  details: JSON.stringify({
381
- disposed: this._disposed,
382
- socketConnected: this.socket.connected,
383
- clientId: this._details?.clientId,
384
- connectionId: this.connectionId,
378
+ ...this.getConnectionDetailsProps(),
385
379
  }),
386
380
  });
387
381
  this.disconnect(
@@ -409,26 +403,24 @@ export class DocumentDeltaConnection
409
403
  // to prevent normal messages from being emitted.
410
404
  this._disposed = true;
411
405
 
412
- // Let user of connection object know about disconnect. This has to happen in between setting _disposed and
413
- // removing all listeners!
406
+ // Remove all listeners listening on the socket. These are listeners on socket and not on this connection
407
+ // object. Anyway since we have disposed this connection object, nobody should listen to event on socket
408
+ // anymore.
409
+ this.removeTrackedListeners();
410
+
411
+ // Clear the connection/socket before letting the deltaManager/connection manager know about the disconnect.
412
+ this.disconnectCore();
413
+
414
+ // Let user of connection object know about disconnect.
414
415
  this.emit("disconnect", err);
415
416
  this.logger.sendTelemetryEvent({
416
417
  eventName: "AfterDisconnectEvent",
417
418
  driverVersion,
418
419
  details: JSON.stringify({
419
- disposed: this._disposed,
420
- clientId: this.clientId,
421
- socketConnected: this.socket.connected,
420
+ ...this.getConnectionDetailsProps(),
422
421
  disconnectListenerCount: this.listenerCount("disconnect"),
423
- connectionId: this.connectionId,
424
422
  }),
425
423
  });
426
- // user of DeltaConnection should have processed "disconnect" event and removed all listeners. Not clear
427
- // if we want to enforce that, as some users (like LocalDocumentService) do not unregister any handlers
428
- // assert(this.listenerCount("disconnect") === 0, "'disconnect` events should be processed synchronously");
429
-
430
- this.removeTrackedListeners();
431
- this.disconnectCore();
432
424
  }
433
425
 
434
426
  /**
@@ -640,16 +632,22 @@ export class DocumentDeltaConnection
640
632
  const normalizedError = normalizeError(errorToBeNormalized, {
641
633
  props: {
642
634
  details: JSON.stringify({
643
- disposed: this._disposed,
644
- socketConnected: this.socket?.connected,
645
- clientId: this._details?.clientId,
646
- conenctionId: this.connectionId,
635
+ ...this.getConnectionDetailsProps(),
647
636
  }),
648
637
  },
649
638
  });
650
639
  return normalizedError;
651
640
  }
652
641
 
642
+ private getConnectionDetailsProps() {
643
+ return {
644
+ disposed: this._disposed,
645
+ socketConnected: this.socket?.connected,
646
+ clientId: this._details?.clientId,
647
+ connectionId: this.connectionId,
648
+ };
649
+ }
650
+
653
651
  protected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {
654
652
  this.queuedMessages.push(...msgs);
655
653
  };
@@ -734,7 +732,12 @@ export class DocumentDeltaConnection
734
732
  const errorObj = createGenericNetworkError(
735
733
  `socket.io (${handler}): ${message}`,
736
734
  { canRetry },
737
- { driverVersion },
735
+ {
736
+ driverVersion,
737
+ details: JSON.stringify({
738
+ ...this.getConnectionDetailsProps(),
739
+ }),
740
+ },
738
741
  );
739
742
 
740
743
  return errorObj;
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/driver-base";
9
- export const pkgVersion = "2.0.0-internal.3.3.1";
9
+ export const pkgVersion = "2.0.0-internal.3.4.0";