@fluidframework/driver-base 0.59.3003 → 0.59.4000-71128

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.
@@ -34,7 +34,6 @@ export declare class DocumentDeltaConnection extends TypedEventEmitter<IDocument
34
34
  private earlyOpHandlerAttached;
35
35
  private socketConnectionTimeout;
36
36
  private _details;
37
- private reconnectAttempts;
38
37
  private readonly connectionListeners;
39
38
  private readonly trackedListeners;
40
39
  protected get hasDetails(): boolean;
@@ -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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"}
@@ -34,7 +34,6 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
34
34
  * to later be retrieved via initialMessages.
35
35
  */
36
36
  this.earlyOpHandlerAttached = false;
37
- this.reconnectAttempts = 0;
38
37
  // Listeners only needed while the connection is in progress
39
38
  this.connectionListeners = new Map();
40
39
  // Listeners used throughout the lifetime of the DocumentDeltaConnection
@@ -263,6 +262,13 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
263
262
  this.socket.on("op", this.earlyOpHandler);
264
263
  this.socket.on("signal", this.earlySignalHandler);
265
264
  this.earlyOpHandlerAttached = true;
265
+ // Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.
266
+ let internalSocketConnectionFailureCount = 0;
267
+ const isInternalSocketReconnectionEnabled = () => this.socket.io.reconnection();
268
+ const getMaxInternalSocketReconnectionAttempts = () => isInternalSocketReconnectionEnabled()
269
+ ? this.socket.io.reconnectionAttempts()
270
+ : 0;
271
+ const getMaxAllowedInternalSocketConnectionFailures = () => getMaxInternalSocketReconnectionAttempts() + 1;
266
272
  this._details = await new Promise((resolve, reject) => {
267
273
  const fail = (socketProtocolError, err) => {
268
274
  this.disposeCore(socketProtocolError, err);
@@ -271,6 +277,7 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
271
277
  // Listen for connection issues
272
278
  this.addConnectionListener("connect_error", (error) => {
273
279
  var _a;
280
+ internalSocketConnectionFailureCount++;
274
281
  let isWebSocketTransportError = false;
275
282
  try {
276
283
  const description = error === null || error === void 0 ? void 0 : error.description;
@@ -283,30 +290,27 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
283
290
  }
284
291
  }
285
292
  catch (_e) { }
286
- // Handle socket transport downgrading.
293
+ // Handle socket transport downgrading when not offline.
287
294
  if (isWebSocketTransportError &&
288
295
  this.enableLongPollingDowngrades &&
289
296
  ((_a = this.socket.io.opts.transports) === null || _a === void 0 ? void 0 : _a[0]) !== "polling") {
290
297
  // Downgrade transports to polling upgrade mechanism.
291
298
  this.socket.io.opts.transports = ["polling", "websocket"];
292
299
  // Don't alter reconnection behavior if already enabled.
293
- if (!this.socket.io.reconnection()) {
300
+ if (!isInternalSocketReconnectionEnabled()) {
294
301
  // Allow single reconnection attempt using polling upgrade mechanism.
295
302
  this.socket.io.reconnection(true);
296
303
  this.socket.io.reconnectionAttempts(1);
297
304
  }
298
305
  }
299
306
  // Allow built-in socket.io reconnection handling.
300
- if (this.socket.io.reconnection() &&
301
- this.reconnectAttempts < this.socket.io.reconnectionAttempts()) {
307
+ if (isInternalSocketReconnectionEnabled() &&
308
+ internalSocketConnectionFailureCount < getMaxAllowedInternalSocketConnectionFailures()) {
302
309
  // Reconnection is enabled and maximum reconnect attempts have not been reached.
303
310
  return;
304
311
  }
305
312
  fail(true, this.createErrorObject("connect_error", error));
306
313
  });
307
- this.addConnectionListener("reconnect_attempt", () => {
308
- this.reconnectAttempts++;
309
- });
310
314
  // Listen for timeouts
311
315
  this.addConnectionListener("connect_timeout", () => {
312
316
  fail(true, this.createErrorObject("connect_timeout"));
@@ -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, extractLogSafeErrorProperties, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError, IAnyDriverError } from \"@fluidframework/driver-utils\";\nimport {\n ConnectionMode,\n IClientConfiguration,\n IConnect,\n IConnected,\n IDocumentMessage,\n ISequencedDocumentMessage,\n ISignalClient,\n ISignalMessage,\n ITokenClaims,\n ScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n ChildLogger,\n getCircularReplacer,\n loggerToMonitoringContext,\n MonitoringContext,\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 extends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n implements IDocumentDeltaConnection, IDisposable {\n static readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n // WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n // Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n static readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n /**\n * Last known sequence number to ordering service at the time of connection\n * It may lap actual last sequence number (quite a bit, if container is very active).\n * But it's best information for client to figure out how far it is behind, at least\n * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n * that is likely to be more up-to-date.\n */\n public checkpointSequenceNumber: number | undefined;\n\n // Listen for ops sent before we receive a response to connect_document\n protected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n protected readonly queuedSignals: ISignalMessage[] = [];\n /**\n * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n * to later be retrieved via initialMessages.\n */\n private earlyOpHandlerAttached: boolean = false;\n\n private socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n private _details: IConnected | undefined;\n\n private reconnectAttempts: number = 0;\n\n // Listeners only needed while the connection is in progress\n private readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n // Listeners used throughout the lifetime of the DocumentDeltaConnection\n private readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n protected get hasDetails(): boolean {\n return !!this._details;\n }\n\n public get disposed() {\n assert(this._disposed || this.socket.connected, 0x244 /* \"Socket is closed, but connection is not!\" */);\n return this._disposed;\n }\n /**\n * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n * After disconnection, we flip this to prevent any stale messages from being emitted.\n */\n protected _disposed: boolean = false;\n private readonly mc: MonitoringContext;\n /**\n * @deprecated - Implementors should manage their own logger or monitoring context\n */\n protected get logger(): ITelemetryLogger {\n return this.mc.logger;\n }\n\n public get details(): IConnected {\n if (!this._details) {\n throw new Error(\"Internal error: calling method before _details is initialized!\");\n }\n return this._details;\n }\n\n /**\n * @param socket - websocket to be used\n * @param documentId - ID of the document\n * @param logger - for reporting telemetry events\n * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n */\n protected constructor(\n protected readonly socket: Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n private readonly enableLongPollingDowngrades: boolean = false,\n ) {\n super();\n\n this.mc = loggerToMonitoringContext(\n ChildLogger.create(logger, \"DeltaConnection\"));\n\n this.on(\"newListener\", (event, listener) => {\n assert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n // Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n if (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n assert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n return;\n }\n\n if (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n throw new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n }\n\n // Whenever listener is added, we should subscribe on same event on socket, so these two things\n // should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n // and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n // Better flow might be to always unconditionally register all handlers on successful connection,\n // though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n assert((this.listeners(event).length !== 0) === this.trackedListeners.has(event), 0x20b /* \"mismatch\" */);\n if (!this.trackedListeners.has(event)) {\n this.addTrackedListener(\n event,\n (...args: any[]) => {\n this.emit(event, ...args);\n });\n }\n });\n }\n\n /**\n * Get the ID of the client who is sending the message\n *\n * @returns the client ID\n */\n public get clientId(): string {\n return this.details.clientId;\n }\n\n /**\n * Get the mode of the client\n *\n * @returns the client mode\n */\n public get mode(): ConnectionMode {\n return this.details.mode;\n }\n\n /**\n * Get the claims of the client who is sending the message\n *\n * @returns client claims\n */\n public get claims(): ITokenClaims {\n return this.details.claims;\n }\n\n /**\n * Get whether or not this is an existing document\n *\n * @returns true if the document exists\n */\n public get existing(): boolean {\n return this.details.existing;\n }\n\n /**\n * Get the maximum size of a message before chunking is required\n *\n * @returns the maximum size of a message before chunking is required\n */\n public get maxMessageSize(): number {\n return this.details.serviceConfiguration.maxMessageSize;\n }\n\n /**\n * Semver of protocol being used with the service\n */\n public get version(): string {\n return this.details.version;\n }\n\n /**\n * Configuration details provided by the service\n */\n public get serviceConfiguration(): IClientConfiguration {\n return this.details.serviceConfiguration;\n }\n\n private checkNotClosed() {\n assert(!this.disposed, 0x20c /* \"connection disposed\" */);\n }\n\n /**\n * Get messages sent during the connection\n *\n * @returns messages sent during the connection\n */\n public get initialMessages(): ISequencedDocumentMessage[] {\n this.checkNotClosed();\n\n // If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n // latest ops. This could possibly indicate that initialMessages was called twice.\n assert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n // We will lose ops and perf will tank as we need to go to storage to become current!\n assert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n this.removeEarlyOpHandler();\n\n if (this.queuedMessages.length > 0) {\n // Some messages were queued.\n // add them to the list of initialMessages to be processed\n this.details.initialMessages.push(...this.queuedMessages);\n this.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n this.queuedMessages.length = 0;\n }\n return this.details.initialMessages;\n }\n\n /**\n * Get signals sent during the connection\n *\n * @returns signals sent during the connection\n */\n public get initialSignals(): ISignalMessage[] {\n this.checkNotClosed();\n assert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n this.removeEarlySignalHandler();\n\n if (this.queuedSignals.length > 0) {\n // Some signals were queued.\n // add them to the list of initialSignals to be processed\n this.details.initialSignals.push(...this.queuedSignals);\n this.queuedSignals.length = 0;\n }\n return this.details.initialSignals;\n }\n\n /**\n * Get initial client list\n *\n * @returns initial client list sent during the connection\n */\n public get initialClients(): ISignalClient[] {\n this.checkNotClosed();\n return this.details.initialClients;\n }\n\n protected emitMessages(type: string, messages: IDocumentMessage[][]) {\n // Although the implementation here disconnects the socket and does not reuse it, other subclasses\n // (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n // on the still-live socket.\n if (!this.disposed) {\n this.socket.emit(type, this.clientId, messages);\n }\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n this.emitMessages(type, [messages]);\n }\n\n /**\n * Submits a new delta operation to the server\n *\n * @param message - delta operation to submit\n */\n public submit(messages: IDocumentMessage[]): void {\n this.checkNotClosed();\n this.submitCore(\"submitOp\", messages);\n }\n\n /**\n * Submits a new signal to the server\n *\n * @param message - signal to submit\n */\n public submitSignal(message: IDocumentMessage): void {\n this.checkNotClosed();\n this.submitCore(\"submitSignal\", [message]);\n }\n\n /**\n * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection.\n */\n public dispose() {\n this.disposeCore(\n false, // socketProtocolError\n createGenericNetworkError(\n // pre-0.58 error message: clientClosingConnection\n \"Client closing delta connection\", { canRetry: true }, { driverVersion }));\n }\n\n protected disposeCore(socketProtocolError: boolean, err: IAnyDriverError) {\n // Can't check this.disposed here, as we get here on socket closure,\n // so _disposed & socket.connected might be not in sync while processing\n // \"dispose\" event.\n if (this._disposed) {\n return;\n }\n\n // We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n // DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n // important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n // OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n // to prevent normal messages from being emitted.\n this._disposed = true;\n\n this.removeTrackedListeners();\n this.disconnect(socketProtocolError, err);\n }\n\n /**\n * Disconnect from the websocket.\n * @param socketProtocolError - true if error happened on socket / socket.io protocol level\n * (not on Fluid protocol level)\n * @param reason - reason for disconnect\n */\n protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {\n this.socket.disconnect();\n }\n\n protected async initialize(connectMessage: IConnect, timeout: number) {\n this.socket.on(\"op\", this.earlyOpHandler);\n this.socket.on(\"signal\", this.earlySignalHandler);\n this.earlyOpHandlerAttached = true;\n\n this._details = await new Promise<IConnected>((resolve, reject) => {\n const fail = (socketProtocolError: boolean, err: IAnyDriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\n let isWebSocketTransportError = false;\n try {\n const description = error?.description;\n if (description && typeof description === \"object\") {\n if (error.type === \"TransportError\") {\n isWebSocketTransportError = true;\n }\n // That's a WebSocket. Clear it as we can't log it.\n description.target = undefined;\n }\n } catch (_e) {}\n\n // Handle socket transport downgrading.\n if (isWebSocketTransportError &&\n this.enableLongPollingDowngrades &&\n this.socket.io.opts.transports?.[0] !== \"polling\") {\n // Downgrade transports to polling upgrade mechanism.\n this.socket.io.opts.transports = [\"polling\", \"websocket\"];\n // Don't alter reconnection behavior if already enabled.\n if (!this.socket.io.reconnection()) {\n // Allow single reconnection attempt using polling upgrade mechanism.\n this.socket.io.reconnection(true);\n this.socket.io.reconnectionAttempts(1);\n }\n }\n\n // Allow built-in socket.io reconnection handling.\n if (this.socket.io.reconnection() &&\n this.reconnectAttempts < this.socket.io.reconnectionAttempts()) {\n // Reconnection is enabled and maximum reconnect attempts have not been reached.\n return;\n }\n\n fail(true, this.createErrorObject(\"connect_error\", error));\n });\n\n this.addConnectionListener(\"reconnect_attempt\", () => {\n this.reconnectAttempts++;\n });\n\n // Listen for timeouts\n this.addConnectionListener(\"connect_timeout\", () => {\n fail(true, this.createErrorObject(\"connect_timeout\"));\n });\n\n this.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n response.nonce !== undefined &&\n response.nonce !== connectMessage.nonce) {\n return;\n }\n\n const requestedMode = connectMessage.mode;\n const actualMode = response.mode;\n const writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n if (writingPermitted) {\n // The only time we expect a mismatch in requested/actual is if we lack write permissions\n // In this case we will get \"read\", even if we requested \"write\"\n if (actualMode !== requestedMode) {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in a different mode than was requested\",\n false,\n ));\n return;\n }\n } else {\n if (actualMode === \"write\") {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in write mode without write permissions\",\n false,\n ));\n return;\n }\n }\n\n this.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n this.removeConnectionListeners();\n resolve(response);\n });\n\n // Socket can be disconnected while waiting for Fluid protocol messages\n // (connect_document_error / connect_document_success), as well as before DeltaManager\n // had a chance to register its handlers.\n this.addTrackedListener(\"disconnect\", (reason) => {\n const err = this.createErrorObject(\"disconnect\", reason);\n this.emit(\"disconnect\", err);\n fail(true, err);\n });\n\n this.addTrackedListener(\"error\", ((error) => {\n // First, raise an error event, to give clients a chance to observe error contents\n // This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n const err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n this.emit(\"error\", err);\n // Disconnect socket - required if happened before initial handshake\n fail(true, err);\n }));\n\n this.addConnectionListener(\"connect_document_error\", ((error) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n error.nonce !== undefined &&\n error.nonce !== connectMessage.nonce) {\n return;\n }\n\n // This is not an socket.io error - it's Fluid protocol error.\n // In this case fail connection and indicate that we were unable to create connection\n fail(false, this.createErrorObject(\"connect_document_error\", error));\n }));\n\n this.socket.emit(\"connect_document\", connectMessage);\n\n // Give extra 2 seconds for handshake on top of socket connection timeout\n this.socketConnectionTimeout = setTimeout(() => {\n fail(false, this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n }, timeout + 2000);\n });\n\n assert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n }\n\n protected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n this.queuedMessages.push(...msgs);\n };\n\n protected earlySignalHandler = (msg: ISignalMessage) => {\n this.queuedSignals.push(msg);\n };\n\n private removeEarlyOpHandler() {\n this.socket.removeListener(\"op\", this.earlyOpHandler);\n this.earlyOpHandlerAttached = false;\n }\n\n private removeEarlySignalHandler() {\n this.socket.removeListener(\"signal\", this.earlySignalHandler);\n }\n\n private addConnectionListener(event: string, listener: (...args: any[]) => void) {\n assert(!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n 0x247 /* \"Use addTrackedListener instead\" */);\n assert(!DocumentDeltaConnection.eventsToForward.includes(event),\n 0x248 /* \"should not subscribe to forwarded events\" */);\n this.socket.on(event, listener);\n assert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n this.connectionListeners.set(event, listener);\n }\n\n protected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n this.socket.on(event, listener);\n assert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n this.trackedListeners.set(event, listener);\n }\n\n private removeTrackedListeners() {\n for (const [event, listener] of this.trackedListeners.entries()) {\n this.socket.off(event, listener);\n }\n // removeTrackedListeners removes all listeners, including connection listeners\n this.removeConnectionListeners();\n\n this.removeEarlyOpHandler();\n this.removeEarlySignalHandler();\n\n this.trackedListeners.clear();\n }\n\n private removeConnectionListeners() {\n if (this.socketConnectionTimeout !== undefined) {\n clearTimeout(this.socketConnectionTimeout);\n }\n\n for (const [event, listener] of this.connectionListeners.entries()) {\n this.socket.off(event, listener);\n }\n this.connectionListeners.clear();\n }\n\n /**\n * Error raising for socket.io issues\n */\n protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n // Note: we suspect the incoming error object is either:\n // - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n // - an Error object thrown by socket.io engine. Be careful with not recording PII!\n let message: string;\n if (error?.type === \"TransportError\") {\n // JSON.stringify drops Error.message\n const messagePrefix = (error?.message !== undefined)\n ? `${error.message}: `\n : \"\";\n\n // Websocket errors reported by engine.io-client.\n // They are Error objects with description containing WS error and description = \"TransportError\"\n // Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n message = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n } else {\n message = extractLogSafeErrorProperties(error).message;\n }\n\n const errorObj = createGenericNetworkError(\n `socket.io (${handler}): ${message}`,\n { canRetry },\n { driverVersion },\n );\n\n return errorObj;\n }\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, extractLogSafeErrorProperties, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError, IAnyDriverError } from \"@fluidframework/driver-utils\";\nimport {\n ConnectionMode,\n IClientConfiguration,\n IConnect,\n IConnected,\n IDocumentMessage,\n ISequencedDocumentMessage,\n ISignalClient,\n ISignalMessage,\n ITokenClaims,\n ScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n ChildLogger,\n getCircularReplacer,\n loggerToMonitoringContext,\n MonitoringContext,\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 extends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n implements IDocumentDeltaConnection, IDisposable {\n static readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n // WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n // Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n static readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n /**\n * Last known sequence number to ordering service at the time of connection\n * It may lap actual last sequence number (quite a bit, if container is very active).\n * But it's best information for client to figure out how far it is behind, at least\n * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n * that is likely to be more up-to-date.\n */\n public checkpointSequenceNumber: number | undefined;\n\n // Listen for ops sent before we receive a response to connect_document\n protected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n protected readonly queuedSignals: ISignalMessage[] = [];\n /**\n * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n * to later be retrieved via initialMessages.\n */\n private earlyOpHandlerAttached: boolean = false;\n\n private socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n private _details: IConnected | undefined;\n\n // Listeners only needed while the connection is in progress\n private readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n // Listeners used throughout the lifetime of the DocumentDeltaConnection\n private readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n protected get hasDetails(): boolean {\n return !!this._details;\n }\n\n public get disposed() {\n assert(this._disposed || this.socket.connected, 0x244 /* \"Socket is closed, but connection is not!\" */);\n return this._disposed;\n }\n /**\n * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n * After disconnection, we flip this to prevent any stale messages from being emitted.\n */\n protected _disposed: boolean = false;\n private readonly mc: MonitoringContext;\n /**\n * @deprecated - Implementors should manage their own logger or monitoring context\n */\n protected get logger(): ITelemetryLogger {\n return this.mc.logger;\n }\n\n public get details(): IConnected {\n if (!this._details) {\n throw new Error(\"Internal error: calling method before _details is initialized!\");\n }\n return this._details;\n }\n\n /**\n * @param socket - websocket to be used\n * @param documentId - ID of the document\n * @param logger - for reporting telemetry events\n * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n */\n protected constructor(\n protected readonly socket: Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n private readonly enableLongPollingDowngrades: boolean = false,\n ) {\n super();\n\n this.mc = loggerToMonitoringContext(\n ChildLogger.create(logger, \"DeltaConnection\"));\n\n this.on(\"newListener\", (event, listener) => {\n assert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n // Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n if (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n assert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n return;\n }\n\n if (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n throw new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n }\n\n // Whenever listener is added, we should subscribe on same event on socket, so these two things\n // should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n // and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n // Better flow might be to always unconditionally register all handlers on successful connection,\n // though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n assert((this.listeners(event).length !== 0) === this.trackedListeners.has(event), 0x20b /* \"mismatch\" */);\n if (!this.trackedListeners.has(event)) {\n this.addTrackedListener(\n event,\n (...args: any[]) => {\n this.emit(event, ...args);\n });\n }\n });\n }\n\n /**\n * Get the ID of the client who is sending the message\n *\n * @returns the client ID\n */\n public get clientId(): string {\n return this.details.clientId;\n }\n\n /**\n * Get the mode of the client\n *\n * @returns the client mode\n */\n public get mode(): ConnectionMode {\n return this.details.mode;\n }\n\n /**\n * Get the claims of the client who is sending the message\n *\n * @returns client claims\n */\n public get claims(): ITokenClaims {\n return this.details.claims;\n }\n\n /**\n * Get whether or not this is an existing document\n *\n * @returns true if the document exists\n */\n public get existing(): boolean {\n return this.details.existing;\n }\n\n /**\n * Get the maximum size of a message before chunking is required\n *\n * @returns the maximum size of a message before chunking is required\n */\n public get maxMessageSize(): number {\n return this.details.serviceConfiguration.maxMessageSize;\n }\n\n /**\n * Semver of protocol being used with the service\n */\n public get version(): string {\n return this.details.version;\n }\n\n /**\n * Configuration details provided by the service\n */\n public get serviceConfiguration(): IClientConfiguration {\n return this.details.serviceConfiguration;\n }\n\n private checkNotClosed() {\n assert(!this.disposed, 0x20c /* \"connection disposed\" */);\n }\n\n /**\n * Get messages sent during the connection\n *\n * @returns messages sent during the connection\n */\n public get initialMessages(): ISequencedDocumentMessage[] {\n this.checkNotClosed();\n\n // If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n // latest ops. This could possibly indicate that initialMessages was called twice.\n assert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n // We will lose ops and perf will tank as we need to go to storage to become current!\n assert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n this.removeEarlyOpHandler();\n\n if (this.queuedMessages.length > 0) {\n // Some messages were queued.\n // add them to the list of initialMessages to be processed\n this.details.initialMessages.push(...this.queuedMessages);\n this.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n this.queuedMessages.length = 0;\n }\n return this.details.initialMessages;\n }\n\n /**\n * Get signals sent during the connection\n *\n * @returns signals sent during the connection\n */\n public get initialSignals(): ISignalMessage[] {\n this.checkNotClosed();\n assert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n this.removeEarlySignalHandler();\n\n if (this.queuedSignals.length > 0) {\n // Some signals were queued.\n // add them to the list of initialSignals to be processed\n this.details.initialSignals.push(...this.queuedSignals);\n this.queuedSignals.length = 0;\n }\n return this.details.initialSignals;\n }\n\n /**\n * Get initial client list\n *\n * @returns initial client list sent during the connection\n */\n public get initialClients(): ISignalClient[] {\n this.checkNotClosed();\n return this.details.initialClients;\n }\n\n protected emitMessages(type: string, messages: IDocumentMessage[][]) {\n // Although the implementation here disconnects the socket and does not reuse it, other subclasses\n // (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n // on the still-live socket.\n if (!this.disposed) {\n this.socket.emit(type, this.clientId, messages);\n }\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n this.emitMessages(type, [messages]);\n }\n\n /**\n * Submits a new delta operation to the server\n *\n * @param message - delta operation to submit\n */\n public submit(messages: IDocumentMessage[]): void {\n this.checkNotClosed();\n this.submitCore(\"submitOp\", messages);\n }\n\n /**\n * Submits a new signal to the server\n *\n * @param message - signal to submit\n */\n public submitSignal(message: IDocumentMessage): void {\n this.checkNotClosed();\n this.submitCore(\"submitSignal\", [message]);\n }\n\n /**\n * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection.\n */\n public dispose() {\n this.disposeCore(\n false, // socketProtocolError\n createGenericNetworkError(\n // pre-0.58 error message: clientClosingConnection\n \"Client closing delta connection\", { canRetry: true }, { driverVersion }));\n }\n\n protected disposeCore(socketProtocolError: boolean, err: IAnyDriverError) {\n // Can't check this.disposed here, as we get here on socket closure,\n // so _disposed & socket.connected might be not in sync while processing\n // \"dispose\" event.\n if (this._disposed) {\n return;\n }\n\n // We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n // DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n // important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n // OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n // to prevent normal messages from being emitted.\n this._disposed = true;\n\n this.removeTrackedListeners();\n this.disconnect(socketProtocolError, err);\n }\n\n /**\n * Disconnect from the websocket.\n * @param socketProtocolError - true if error happened on socket / socket.io protocol level\n * (not on Fluid protocol level)\n * @param reason - reason for disconnect\n */\n protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {\n this.socket.disconnect();\n }\n\n protected async initialize(connectMessage: IConnect, timeout: number) {\n this.socket.on(\"op\", this.earlyOpHandler);\n this.socket.on(\"signal\", this.earlySignalHandler);\n this.earlyOpHandlerAttached = true;\n\n // Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.\n let internalSocketConnectionFailureCount: number = 0;\n const isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();\n const getMaxInternalSocketReconnectionAttempts = (): number => isInternalSocketReconnectionEnabled()\n ? this.socket.io.reconnectionAttempts()\n : 0;\n const getMaxAllowedInternalSocketConnectionFailures = (): number =>\n getMaxInternalSocketReconnectionAttempts() + 1;\n\n this._details = await new Promise<IConnected>((resolve, reject) => {\n const fail = (socketProtocolError: boolean, err: IAnyDriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\n internalSocketConnectionFailureCount++;\n let isWebSocketTransportError = false;\n try {\n const description = error?.description;\n if (description && typeof description === \"object\") {\n if (error.type === \"TransportError\") {\n isWebSocketTransportError = true;\n }\n // That's a WebSocket. Clear it as we can't log it.\n description.target = undefined;\n }\n } catch (_e) { }\n\n // Handle socket transport downgrading when not offline.\n if (\n isWebSocketTransportError &&\n this.enableLongPollingDowngrades &&\n this.socket.io.opts.transports?.[0] !== \"polling\") {\n // Downgrade transports to polling upgrade mechanism.\n this.socket.io.opts.transports = [\"polling\", \"websocket\"];\n // Don't alter reconnection behavior if already enabled.\n if (!isInternalSocketReconnectionEnabled()) {\n // Allow single reconnection attempt using polling upgrade mechanism.\n this.socket.io.reconnection(true);\n this.socket.io.reconnectionAttempts(1);\n }\n }\n\n // Allow built-in socket.io reconnection handling.\n if (isInternalSocketReconnectionEnabled() &&\n internalSocketConnectionFailureCount < getMaxAllowedInternalSocketConnectionFailures()) {\n // Reconnection is enabled and maximum reconnect attempts have not been reached.\n return;\n }\n\n fail(true, this.createErrorObject(\"connect_error\", error));\n });\n\n // Listen for timeouts\n this.addConnectionListener(\"connect_timeout\", () => {\n fail(true, this.createErrorObject(\"connect_timeout\"));\n });\n\n this.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n response.nonce !== undefined &&\n response.nonce !== connectMessage.nonce) {\n return;\n }\n\n const requestedMode = connectMessage.mode;\n const actualMode = response.mode;\n const writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n if (writingPermitted) {\n // The only time we expect a mismatch in requested/actual is if we lack write permissions\n // In this case we will get \"read\", even if we requested \"write\"\n if (actualMode !== requestedMode) {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in a different mode than was requested\",\n false,\n ));\n return;\n }\n } else {\n if (actualMode === \"write\") {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in write mode without write permissions\",\n false,\n ));\n return;\n }\n }\n\n this.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n this.removeConnectionListeners();\n resolve(response);\n });\n\n // Socket can be disconnected while waiting for Fluid protocol messages\n // (connect_document_error / connect_document_success), as well as before DeltaManager\n // had a chance to register its handlers.\n this.addTrackedListener(\"disconnect\", (reason) => {\n const err = this.createErrorObject(\"disconnect\", reason);\n this.emit(\"disconnect\", err);\n fail(true, err);\n });\n\n this.addTrackedListener(\"error\", ((error) => {\n // First, raise an error event, to give clients a chance to observe error contents\n // This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n const err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n this.emit(\"error\", err);\n // Disconnect socket - required if happened before initial handshake\n fail(true, err);\n }));\n\n this.addConnectionListener(\"connect_document_error\", ((error) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n error.nonce !== undefined &&\n error.nonce !== connectMessage.nonce) {\n return;\n }\n\n // This is not an socket.io error - it's Fluid protocol error.\n // In this case fail connection and indicate that we were unable to create connection\n fail(false, this.createErrorObject(\"connect_document_error\", error));\n }));\n\n this.socket.emit(\"connect_document\", connectMessage);\n\n // Give extra 2 seconds for handshake on top of socket connection timeout\n this.socketConnectionTimeout = setTimeout(() => {\n fail(false, this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n }, timeout + 2000);\n });\n\n assert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n }\n\n protected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n this.queuedMessages.push(...msgs);\n };\n\n protected earlySignalHandler = (msg: ISignalMessage) => {\n this.queuedSignals.push(msg);\n };\n\n private removeEarlyOpHandler() {\n this.socket.removeListener(\"op\", this.earlyOpHandler);\n this.earlyOpHandlerAttached = false;\n }\n\n private removeEarlySignalHandler() {\n this.socket.removeListener(\"signal\", this.earlySignalHandler);\n }\n\n private addConnectionListener(event: string, listener: (...args: any[]) => void) {\n assert(!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n 0x247 /* \"Use addTrackedListener instead\" */);\n assert(!DocumentDeltaConnection.eventsToForward.includes(event),\n 0x248 /* \"should not subscribe to forwarded events\" */);\n this.socket.on(event, listener);\n assert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n this.connectionListeners.set(event, listener);\n }\n\n protected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n this.socket.on(event, listener);\n assert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n this.trackedListeners.set(event, listener);\n }\n\n private removeTrackedListeners() {\n for (const [event, listener] of this.trackedListeners.entries()) {\n this.socket.off(event, listener);\n }\n // removeTrackedListeners removes all listeners, including connection listeners\n this.removeConnectionListeners();\n\n this.removeEarlyOpHandler();\n this.removeEarlySignalHandler();\n\n this.trackedListeners.clear();\n }\n\n private removeConnectionListeners() {\n if (this.socketConnectionTimeout !== undefined) {\n clearTimeout(this.socketConnectionTimeout);\n }\n\n for (const [event, listener] of this.connectionListeners.entries()) {\n this.socket.off(event, listener);\n }\n this.connectionListeners.clear();\n }\n\n /**\n * Error raising for socket.io issues\n */\n protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n // Note: we suspect the incoming error object is either:\n // - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n // - an Error object thrown by socket.io engine. Be careful with not recording PII!\n let message: string;\n if (error?.type === \"TransportError\") {\n // JSON.stringify drops Error.message\n const messagePrefix = (error?.message !== undefined)\n ? `${error.message}: `\n : \"\";\n\n // Websocket errors reported by engine.io-client.\n // They are Error objects with description containing WS error and description = \"TransportError\"\n // Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n message = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n } else {\n message = extractLogSafeErrorProperties(error).message;\n }\n\n const errorObj = createGenericNetworkError(\n `socket.io (${handler}): ${message}`,\n { canRetry },\n { driverVersion },\n );\n\n return errorObj;\n }\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 = "0.59.3003";
8
+ export declare const pkgVersion = "0.59.4000-71128";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,cAAc,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,oBAAoB,CAAC"}
@@ -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 = "0.59.3003";
11
+ exports.pkgVersion = "0.59.4000-71128";
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,WAAW,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 = \"0.59.3003\";\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,iBAAiB,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 = \"0.59.4000-71128\";\n"]}
@@ -34,7 +34,6 @@ export declare class DocumentDeltaConnection extends TypedEventEmitter<IDocument
34
34
  private earlyOpHandlerAttached;
35
35
  private socketConnectionTimeout;
36
36
  private _details;
37
- private reconnectAttempts;
38
37
  private readonly connectionListeners;
39
38
  private readonly trackedListeners;
40
39
  protected get hasDetails(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"documentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAyC,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACxG,OAAO,EACH,wBAAwB,EACxB,8BAA8B,EACjC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAA6B,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EACH,cAAc,EACd,oBAAoB,EACpB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,yBAAyB,EACzB,aAAa,EACb,cAAc,EACd,YAAY,EAEf,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAOnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI/C;;GAEG;AACH,qBAAa,uBACT,SAAQ,iBAAiB,CAAC,8BAA8B,CACxD,YAAW,wBAAwB,EAAE,WAAW;IAuE5C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAC1B,UAAU,EAAE,MAAM;IAEzB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IAzEhD,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;IACxD;;;OAGG;IACH,OAAO,CAAC,sBAAsB,CAAkB;IAEhD,OAAO,CAAC,uBAAuB,CAA4C;IAE3E,OAAO,CAAC,QAAQ,CAAyB;IAEzC,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAoD;IAExF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoD;IAErF,SAAS,KAAK,UAAU,IAAI,OAAO,CAElC;IAED,IAAW,QAAQ,YAGlB;IACD;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,OAAO,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IACvC;;OAEG;IACH,SAAS,KAAK,MAAM,IAAI,gBAAgB,CAEvC;IAED,IAAW,OAAO,IAAI,UAAU,CAK/B;IAED;;;;;OAKG;IACH,SAAS,aACc,MAAM,EAAE,MAAM,EAC1B,UAAU,EAAE,MAAM,EACzB,MAAM,EAAE,gBAAgB,EACP,2BAA2B,GAAE,OAAe;IAoCjE;;;;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;IAItB;;;;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;IACI,OAAO;IAQd,SAAS,CAAC,WAAW,CAAC,mBAAmB,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe;IAmBxE;;;;;OAKG;IACH,SAAS,CAAC,UAAU,CAAC,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe;cAI1D,UAAU,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IA4IpE,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;IAU7B,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;CA2B9F"}
1
+ {"version":3,"file":"documentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,6 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
31
31
  * to later be retrieved via initialMessages.
32
32
  */
33
33
  this.earlyOpHandlerAttached = false;
34
- this.reconnectAttempts = 0;
35
34
  // Listeners only needed while the connection is in progress
36
35
  this.connectionListeners = new Map();
37
36
  // Listeners used throughout the lifetime of the DocumentDeltaConnection
@@ -260,6 +259,13 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
260
259
  this.socket.on("op", this.earlyOpHandler);
261
260
  this.socket.on("signal", this.earlySignalHandler);
262
261
  this.earlyOpHandlerAttached = true;
262
+ // Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.
263
+ let internalSocketConnectionFailureCount = 0;
264
+ const isInternalSocketReconnectionEnabled = () => this.socket.io.reconnection();
265
+ const getMaxInternalSocketReconnectionAttempts = () => isInternalSocketReconnectionEnabled()
266
+ ? this.socket.io.reconnectionAttempts()
267
+ : 0;
268
+ const getMaxAllowedInternalSocketConnectionFailures = () => getMaxInternalSocketReconnectionAttempts() + 1;
263
269
  this._details = await new Promise((resolve, reject) => {
264
270
  const fail = (socketProtocolError, err) => {
265
271
  this.disposeCore(socketProtocolError, err);
@@ -268,6 +274,7 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
268
274
  // Listen for connection issues
269
275
  this.addConnectionListener("connect_error", (error) => {
270
276
  var _a;
277
+ internalSocketConnectionFailureCount++;
271
278
  let isWebSocketTransportError = false;
272
279
  try {
273
280
  const description = error === null || error === void 0 ? void 0 : error.description;
@@ -280,30 +287,27 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
280
287
  }
281
288
  }
282
289
  catch (_e) { }
283
- // Handle socket transport downgrading.
290
+ // Handle socket transport downgrading when not offline.
284
291
  if (isWebSocketTransportError &&
285
292
  this.enableLongPollingDowngrades &&
286
293
  ((_a = this.socket.io.opts.transports) === null || _a === void 0 ? void 0 : _a[0]) !== "polling") {
287
294
  // Downgrade transports to polling upgrade mechanism.
288
295
  this.socket.io.opts.transports = ["polling", "websocket"];
289
296
  // Don't alter reconnection behavior if already enabled.
290
- if (!this.socket.io.reconnection()) {
297
+ if (!isInternalSocketReconnectionEnabled()) {
291
298
  // Allow single reconnection attempt using polling upgrade mechanism.
292
299
  this.socket.io.reconnection(true);
293
300
  this.socket.io.reconnectionAttempts(1);
294
301
  }
295
302
  }
296
303
  // Allow built-in socket.io reconnection handling.
297
- if (this.socket.io.reconnection() &&
298
- this.reconnectAttempts < this.socket.io.reconnectionAttempts()) {
304
+ if (isInternalSocketReconnectionEnabled() &&
305
+ internalSocketConnectionFailureCount < getMaxAllowedInternalSocketConnectionFailures()) {
299
306
  // Reconnection is enabled and maximum reconnect attempts have not been reached.
300
307
  return;
301
308
  }
302
309
  fail(true, this.createErrorObject("connect_error", error));
303
310
  });
304
- this.addConnectionListener("reconnect_attempt", () => {
305
- this.reconnectAttempts++;
306
- });
307
311
  // Listen for timeouts
308
312
  this.addConnectionListener("connect_timeout", () => {
309
313
  fail(true, this.createErrorObject("connect_timeout"));
@@ -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, extractLogSafeErrorProperties, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError, IAnyDriverError } from \"@fluidframework/driver-utils\";\nimport {\n ConnectionMode,\n IClientConfiguration,\n IConnect,\n IConnected,\n IDocumentMessage,\n ISequencedDocumentMessage,\n ISignalClient,\n ISignalMessage,\n ITokenClaims,\n ScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n ChildLogger,\n getCircularReplacer,\n loggerToMonitoringContext,\n MonitoringContext,\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 extends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n implements IDocumentDeltaConnection, IDisposable {\n static readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n // WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n // Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n static readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n /**\n * Last known sequence number to ordering service at the time of connection\n * It may lap actual last sequence number (quite a bit, if container is very active).\n * But it's best information for client to figure out how far it is behind, at least\n * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n * that is likely to be more up-to-date.\n */\n public checkpointSequenceNumber: number | undefined;\n\n // Listen for ops sent before we receive a response to connect_document\n protected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n protected readonly queuedSignals: ISignalMessage[] = [];\n /**\n * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n * to later be retrieved via initialMessages.\n */\n private earlyOpHandlerAttached: boolean = false;\n\n private socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n private _details: IConnected | undefined;\n\n private reconnectAttempts: number = 0;\n\n // Listeners only needed while the connection is in progress\n private readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n // Listeners used throughout the lifetime of the DocumentDeltaConnection\n private readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n protected get hasDetails(): boolean {\n return !!this._details;\n }\n\n public get disposed() {\n assert(this._disposed || this.socket.connected, 0x244 /* \"Socket is closed, but connection is not!\" */);\n return this._disposed;\n }\n /**\n * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n * After disconnection, we flip this to prevent any stale messages from being emitted.\n */\n protected _disposed: boolean = false;\n private readonly mc: MonitoringContext;\n /**\n * @deprecated - Implementors should manage their own logger or monitoring context\n */\n protected get logger(): ITelemetryLogger {\n return this.mc.logger;\n }\n\n public get details(): IConnected {\n if (!this._details) {\n throw new Error(\"Internal error: calling method before _details is initialized!\");\n }\n return this._details;\n }\n\n /**\n * @param socket - websocket to be used\n * @param documentId - ID of the document\n * @param logger - for reporting telemetry events\n * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n */\n protected constructor(\n protected readonly socket: Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n private readonly enableLongPollingDowngrades: boolean = false,\n ) {\n super();\n\n this.mc = loggerToMonitoringContext(\n ChildLogger.create(logger, \"DeltaConnection\"));\n\n this.on(\"newListener\", (event, listener) => {\n assert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n // Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n if (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n assert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n return;\n }\n\n if (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n throw new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n }\n\n // Whenever listener is added, we should subscribe on same event on socket, so these two things\n // should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n // and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n // Better flow might be to always unconditionally register all handlers on successful connection,\n // though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n assert((this.listeners(event).length !== 0) === this.trackedListeners.has(event), 0x20b /* \"mismatch\" */);\n if (!this.trackedListeners.has(event)) {\n this.addTrackedListener(\n event,\n (...args: any[]) => {\n this.emit(event, ...args);\n });\n }\n });\n }\n\n /**\n * Get the ID of the client who is sending the message\n *\n * @returns the client ID\n */\n public get clientId(): string {\n return this.details.clientId;\n }\n\n /**\n * Get the mode of the client\n *\n * @returns the client mode\n */\n public get mode(): ConnectionMode {\n return this.details.mode;\n }\n\n /**\n * Get the claims of the client who is sending the message\n *\n * @returns client claims\n */\n public get claims(): ITokenClaims {\n return this.details.claims;\n }\n\n /**\n * Get whether or not this is an existing document\n *\n * @returns true if the document exists\n */\n public get existing(): boolean {\n return this.details.existing;\n }\n\n /**\n * Get the maximum size of a message before chunking is required\n *\n * @returns the maximum size of a message before chunking is required\n */\n public get maxMessageSize(): number {\n return this.details.serviceConfiguration.maxMessageSize;\n }\n\n /**\n * Semver of protocol being used with the service\n */\n public get version(): string {\n return this.details.version;\n }\n\n /**\n * Configuration details provided by the service\n */\n public get serviceConfiguration(): IClientConfiguration {\n return this.details.serviceConfiguration;\n }\n\n private checkNotClosed() {\n assert(!this.disposed, 0x20c /* \"connection disposed\" */);\n }\n\n /**\n * Get messages sent during the connection\n *\n * @returns messages sent during the connection\n */\n public get initialMessages(): ISequencedDocumentMessage[] {\n this.checkNotClosed();\n\n // If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n // latest ops. This could possibly indicate that initialMessages was called twice.\n assert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n // We will lose ops and perf will tank as we need to go to storage to become current!\n assert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n this.removeEarlyOpHandler();\n\n if (this.queuedMessages.length > 0) {\n // Some messages were queued.\n // add them to the list of initialMessages to be processed\n this.details.initialMessages.push(...this.queuedMessages);\n this.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n this.queuedMessages.length = 0;\n }\n return this.details.initialMessages;\n }\n\n /**\n * Get signals sent during the connection\n *\n * @returns signals sent during the connection\n */\n public get initialSignals(): ISignalMessage[] {\n this.checkNotClosed();\n assert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n this.removeEarlySignalHandler();\n\n if (this.queuedSignals.length > 0) {\n // Some signals were queued.\n // add them to the list of initialSignals to be processed\n this.details.initialSignals.push(...this.queuedSignals);\n this.queuedSignals.length = 0;\n }\n return this.details.initialSignals;\n }\n\n /**\n * Get initial client list\n *\n * @returns initial client list sent during the connection\n */\n public get initialClients(): ISignalClient[] {\n this.checkNotClosed();\n return this.details.initialClients;\n }\n\n protected emitMessages(type: string, messages: IDocumentMessage[][]) {\n // Although the implementation here disconnects the socket and does not reuse it, other subclasses\n // (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n // on the still-live socket.\n if (!this.disposed) {\n this.socket.emit(type, this.clientId, messages);\n }\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n this.emitMessages(type, [messages]);\n }\n\n /**\n * Submits a new delta operation to the server\n *\n * @param message - delta operation to submit\n */\n public submit(messages: IDocumentMessage[]): void {\n this.checkNotClosed();\n this.submitCore(\"submitOp\", messages);\n }\n\n /**\n * Submits a new signal to the server\n *\n * @param message - signal to submit\n */\n public submitSignal(message: IDocumentMessage): void {\n this.checkNotClosed();\n this.submitCore(\"submitSignal\", [message]);\n }\n\n /**\n * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection.\n */\n public dispose() {\n this.disposeCore(\n false, // socketProtocolError\n createGenericNetworkError(\n // pre-0.58 error message: clientClosingConnection\n \"Client closing delta connection\", { canRetry: true }, { driverVersion }));\n }\n\n protected disposeCore(socketProtocolError: boolean, err: IAnyDriverError) {\n // Can't check this.disposed here, as we get here on socket closure,\n // so _disposed & socket.connected might be not in sync while processing\n // \"dispose\" event.\n if (this._disposed) {\n return;\n }\n\n // We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n // DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n // important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n // OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n // to prevent normal messages from being emitted.\n this._disposed = true;\n\n this.removeTrackedListeners();\n this.disconnect(socketProtocolError, err);\n }\n\n /**\n * Disconnect from the websocket.\n * @param socketProtocolError - true if error happened on socket / socket.io protocol level\n * (not on Fluid protocol level)\n * @param reason - reason for disconnect\n */\n protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {\n this.socket.disconnect();\n }\n\n protected async initialize(connectMessage: IConnect, timeout: number) {\n this.socket.on(\"op\", this.earlyOpHandler);\n this.socket.on(\"signal\", this.earlySignalHandler);\n this.earlyOpHandlerAttached = true;\n\n this._details = await new Promise<IConnected>((resolve, reject) => {\n const fail = (socketProtocolError: boolean, err: IAnyDriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\n let isWebSocketTransportError = false;\n try {\n const description = error?.description;\n if (description && typeof description === \"object\") {\n if (error.type === \"TransportError\") {\n isWebSocketTransportError = true;\n }\n // That's a WebSocket. Clear it as we can't log it.\n description.target = undefined;\n }\n } catch (_e) {}\n\n // Handle socket transport downgrading.\n if (isWebSocketTransportError &&\n this.enableLongPollingDowngrades &&\n this.socket.io.opts.transports?.[0] !== \"polling\") {\n // Downgrade transports to polling upgrade mechanism.\n this.socket.io.opts.transports = [\"polling\", \"websocket\"];\n // Don't alter reconnection behavior if already enabled.\n if (!this.socket.io.reconnection()) {\n // Allow single reconnection attempt using polling upgrade mechanism.\n this.socket.io.reconnection(true);\n this.socket.io.reconnectionAttempts(1);\n }\n }\n\n // Allow built-in socket.io reconnection handling.\n if (this.socket.io.reconnection() &&\n this.reconnectAttempts < this.socket.io.reconnectionAttempts()) {\n // Reconnection is enabled and maximum reconnect attempts have not been reached.\n return;\n }\n\n fail(true, this.createErrorObject(\"connect_error\", error));\n });\n\n this.addConnectionListener(\"reconnect_attempt\", () => {\n this.reconnectAttempts++;\n });\n\n // Listen for timeouts\n this.addConnectionListener(\"connect_timeout\", () => {\n fail(true, this.createErrorObject(\"connect_timeout\"));\n });\n\n this.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n response.nonce !== undefined &&\n response.nonce !== connectMessage.nonce) {\n return;\n }\n\n const requestedMode = connectMessage.mode;\n const actualMode = response.mode;\n const writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n if (writingPermitted) {\n // The only time we expect a mismatch in requested/actual is if we lack write permissions\n // In this case we will get \"read\", even if we requested \"write\"\n if (actualMode !== requestedMode) {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in a different mode than was requested\",\n false,\n ));\n return;\n }\n } else {\n if (actualMode === \"write\") {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in write mode without write permissions\",\n false,\n ));\n return;\n }\n }\n\n this.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n this.removeConnectionListeners();\n resolve(response);\n });\n\n // Socket can be disconnected while waiting for Fluid protocol messages\n // (connect_document_error / connect_document_success), as well as before DeltaManager\n // had a chance to register its handlers.\n this.addTrackedListener(\"disconnect\", (reason) => {\n const err = this.createErrorObject(\"disconnect\", reason);\n this.emit(\"disconnect\", err);\n fail(true, err);\n });\n\n this.addTrackedListener(\"error\", ((error) => {\n // First, raise an error event, to give clients a chance to observe error contents\n // This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n const err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n this.emit(\"error\", err);\n // Disconnect socket - required if happened before initial handshake\n fail(true, err);\n }));\n\n this.addConnectionListener(\"connect_document_error\", ((error) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n error.nonce !== undefined &&\n error.nonce !== connectMessage.nonce) {\n return;\n }\n\n // This is not an socket.io error - it's Fluid protocol error.\n // In this case fail connection and indicate that we were unable to create connection\n fail(false, this.createErrorObject(\"connect_document_error\", error));\n }));\n\n this.socket.emit(\"connect_document\", connectMessage);\n\n // Give extra 2 seconds for handshake on top of socket connection timeout\n this.socketConnectionTimeout = setTimeout(() => {\n fail(false, this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n }, timeout + 2000);\n });\n\n assert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n }\n\n protected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n this.queuedMessages.push(...msgs);\n };\n\n protected earlySignalHandler = (msg: ISignalMessage) => {\n this.queuedSignals.push(msg);\n };\n\n private removeEarlyOpHandler() {\n this.socket.removeListener(\"op\", this.earlyOpHandler);\n this.earlyOpHandlerAttached = false;\n }\n\n private removeEarlySignalHandler() {\n this.socket.removeListener(\"signal\", this.earlySignalHandler);\n }\n\n private addConnectionListener(event: string, listener: (...args: any[]) => void) {\n assert(!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n 0x247 /* \"Use addTrackedListener instead\" */);\n assert(!DocumentDeltaConnection.eventsToForward.includes(event),\n 0x248 /* \"should not subscribe to forwarded events\" */);\n this.socket.on(event, listener);\n assert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n this.connectionListeners.set(event, listener);\n }\n\n protected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n this.socket.on(event, listener);\n assert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n this.trackedListeners.set(event, listener);\n }\n\n private removeTrackedListeners() {\n for (const [event, listener] of this.trackedListeners.entries()) {\n this.socket.off(event, listener);\n }\n // removeTrackedListeners removes all listeners, including connection listeners\n this.removeConnectionListeners();\n\n this.removeEarlyOpHandler();\n this.removeEarlySignalHandler();\n\n this.trackedListeners.clear();\n }\n\n private removeConnectionListeners() {\n if (this.socketConnectionTimeout !== undefined) {\n clearTimeout(this.socketConnectionTimeout);\n }\n\n for (const [event, listener] of this.connectionListeners.entries()) {\n this.socket.off(event, listener);\n }\n this.connectionListeners.clear();\n }\n\n /**\n * Error raising for socket.io issues\n */\n protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n // Note: we suspect the incoming error object is either:\n // - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n // - an Error object thrown by socket.io engine. Be careful with not recording PII!\n let message: string;\n if (error?.type === \"TransportError\") {\n // JSON.stringify drops Error.message\n const messagePrefix = (error?.message !== undefined)\n ? `${error.message}: `\n : \"\";\n\n // Websocket errors reported by engine.io-client.\n // They are Error objects with description containing WS error and description = \"TransportError\"\n // Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n message = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n } else {\n message = extractLogSafeErrorProperties(error).message;\n }\n\n const errorObj = createGenericNetworkError(\n `socket.io (${handler}): ${message}`,\n { canRetry },\n { driverVersion },\n );\n\n return errorObj;\n }\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, extractLogSafeErrorProperties, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError, IAnyDriverError } from \"@fluidframework/driver-utils\";\nimport {\n ConnectionMode,\n IClientConfiguration,\n IConnect,\n IConnected,\n IDocumentMessage,\n ISequencedDocumentMessage,\n ISignalClient,\n ISignalMessage,\n ITokenClaims,\n ScopeType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n ChildLogger,\n getCircularReplacer,\n loggerToMonitoringContext,\n MonitoringContext,\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 extends TypedEventEmitter<IDocumentDeltaConnectionEvents>\n implements IDocumentDeltaConnection, IDisposable {\n static readonly eventsToForward = [\"nack\", \"op\", \"signal\", \"pong\"];\n\n // WARNING: These are critical events that we can't miss, so registration for them has to be in place at all times!\n // Including before handshake is over, and after that (but before DeltaManager had a chance to put its own handlers)\n static readonly eventsAlwaysForwarded = [\"disconnect\", \"error\"];\n\n /**\n * Last known sequence number to ordering service at the time of connection\n * It may lap actual last sequence number (quite a bit, if container is very active).\n * But it's best information for client to figure out how far it is behind, at least\n * for \"read\" connections. \"write\" connections may use own \"join\" op to similar information,\n * that is likely to be more up-to-date.\n */\n public checkpointSequenceNumber: number | undefined;\n\n // Listen for ops sent before we receive a response to connect_document\n protected readonly queuedMessages: ISequencedDocumentMessage[] = [];\n protected readonly queuedSignals: ISignalMessage[] = [];\n /**\n * A flag to indicate whether we have our handler attached. If it's attached, we're queueing incoming ops\n * to later be retrieved via initialMessages.\n */\n private earlyOpHandlerAttached: boolean = false;\n\n private socketConnectionTimeout: ReturnType<typeof setTimeout> | undefined;\n\n private _details: IConnected | undefined;\n\n // Listeners only needed while the connection is in progress\n private readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();\n // Listeners used throughout the lifetime of the DocumentDeltaConnection\n private readonly trackedListeners: Map<string, (...args: any[]) => void> = new Map();\n\n protected get hasDetails(): boolean {\n return !!this._details;\n }\n\n public get disposed() {\n assert(this._disposed || this.socket.connected, 0x244 /* \"Socket is closed, but connection is not!\" */);\n return this._disposed;\n }\n /**\n * Flag to indicate whether the DocumentDeltaConnection is expected to still be capable of sending messages.\n * After disconnection, we flip this to prevent any stale messages from being emitted.\n */\n protected _disposed: boolean = false;\n private readonly mc: MonitoringContext;\n /**\n * @deprecated - Implementors should manage their own logger or monitoring context\n */\n protected get logger(): ITelemetryLogger {\n return this.mc.logger;\n }\n\n public get details(): IConnected {\n if (!this._details) {\n throw new Error(\"Internal error: calling method before _details is initialized!\");\n }\n return this._details;\n }\n\n /**\n * @param socket - websocket to be used\n * @param documentId - ID of the document\n * @param logger - for reporting telemetry events\n * @param enableLongPollingDowngrades - allow connection to be downgraded to long-polling on websocket failure\n */\n protected constructor(\n protected readonly socket: Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n private readonly enableLongPollingDowngrades: boolean = false,\n ) {\n super();\n\n this.mc = loggerToMonitoringContext(\n ChildLogger.create(logger, \"DeltaConnection\"));\n\n this.on(\"newListener\", (event, listener) => {\n assert(!this.disposed, 0x20a /* \"register for event on disposed object\" */);\n\n // Some events are already forwarded - see this.addTrackedListener() calls in initialize().\n if (DocumentDeltaConnection.eventsAlwaysForwarded.includes(event)) {\n assert(this.trackedListeners.has(event), 0x245 /* \"tracked listener\" */);\n return;\n }\n\n if (!DocumentDeltaConnection.eventsToForward.includes(event)) {\n throw new Error(`DocumentDeltaConnection: Registering for unknown event: ${event}`);\n }\n\n // Whenever listener is added, we should subscribe on same event on socket, so these two things\n // should be in sync. This currently assumes that nobody unregisters and registers back listeners,\n // and that there are no \"internal\" listeners installed (like \"error\" case we skip above)\n // Better flow might be to always unconditionally register all handlers on successful connection,\n // though some logic (naming assert in initialMessages getter) might need to be adjusted (it becomes noop)\n assert((this.listeners(event).length !== 0) === this.trackedListeners.has(event), 0x20b /* \"mismatch\" */);\n if (!this.trackedListeners.has(event)) {\n this.addTrackedListener(\n event,\n (...args: any[]) => {\n this.emit(event, ...args);\n });\n }\n });\n }\n\n /**\n * Get the ID of the client who is sending the message\n *\n * @returns the client ID\n */\n public get clientId(): string {\n return this.details.clientId;\n }\n\n /**\n * Get the mode of the client\n *\n * @returns the client mode\n */\n public get mode(): ConnectionMode {\n return this.details.mode;\n }\n\n /**\n * Get the claims of the client who is sending the message\n *\n * @returns client claims\n */\n public get claims(): ITokenClaims {\n return this.details.claims;\n }\n\n /**\n * Get whether or not this is an existing document\n *\n * @returns true if the document exists\n */\n public get existing(): boolean {\n return this.details.existing;\n }\n\n /**\n * Get the maximum size of a message before chunking is required\n *\n * @returns the maximum size of a message before chunking is required\n */\n public get maxMessageSize(): number {\n return this.details.serviceConfiguration.maxMessageSize;\n }\n\n /**\n * Semver of protocol being used with the service\n */\n public get version(): string {\n return this.details.version;\n }\n\n /**\n * Configuration details provided by the service\n */\n public get serviceConfiguration(): IClientConfiguration {\n return this.details.serviceConfiguration;\n }\n\n private checkNotClosed() {\n assert(!this.disposed, 0x20c /* \"connection disposed\" */);\n }\n\n /**\n * Get messages sent during the connection\n *\n * @returns messages sent during the connection\n */\n public get initialMessages(): ISequencedDocumentMessage[] {\n this.checkNotClosed();\n\n // If we call this when the earlyOpHandler is not attached, then the queuedMessages may not include the\n // latest ops. This could possibly indicate that initialMessages was called twice.\n assert(this.earlyOpHandlerAttached, 0x08e /* \"Potentially missed initial messages\" */);\n // We will lose ops and perf will tank as we need to go to storage to become current!\n assert(this.listeners(\"op\").length !== 0, 0x08f /* \"No op handler is setup!\" */);\n\n this.removeEarlyOpHandler();\n\n if (this.queuedMessages.length > 0) {\n // Some messages were queued.\n // add them to the list of initialMessages to be processed\n this.details.initialMessages.push(...this.queuedMessages);\n this.details.initialMessages.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n this.queuedMessages.length = 0;\n }\n return this.details.initialMessages;\n }\n\n /**\n * Get signals sent during the connection\n *\n * @returns signals sent during the connection\n */\n public get initialSignals(): ISignalMessage[] {\n this.checkNotClosed();\n assert(this.listeners(\"signal\").length !== 0, 0x090 /* \"No signal handler is setup!\" */);\n\n this.removeEarlySignalHandler();\n\n if (this.queuedSignals.length > 0) {\n // Some signals were queued.\n // add them to the list of initialSignals to be processed\n this.details.initialSignals.push(...this.queuedSignals);\n this.queuedSignals.length = 0;\n }\n return this.details.initialSignals;\n }\n\n /**\n * Get initial client list\n *\n * @returns initial client list sent during the connection\n */\n public get initialClients(): ISignalClient[] {\n this.checkNotClosed();\n return this.details.initialClients;\n }\n\n protected emitMessages(type: string, messages: IDocumentMessage[][]) {\n // Although the implementation here disconnects the socket and does not reuse it, other subclasses\n // (e.g. OdspDocumentDeltaConnection) may reuse the socket. In these cases, we need to avoid emitting\n // on the still-live socket.\n if (!this.disposed) {\n this.socket.emit(type, this.clientId, messages);\n }\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n this.emitMessages(type, [messages]);\n }\n\n /**\n * Submits a new delta operation to the server\n *\n * @param message - delta operation to submit\n */\n public submit(messages: IDocumentMessage[]): void {\n this.checkNotClosed();\n this.submitCore(\"submitOp\", messages);\n }\n\n /**\n * Submits a new signal to the server\n *\n * @param message - signal to submit\n */\n public submitSignal(message: IDocumentMessage): void {\n this.checkNotClosed();\n this.submitCore(\"submitSignal\", [message]);\n }\n\n /**\n * Disconnect from the websocket, and permanently disable this DocumentDeltaConnection.\n */\n public dispose() {\n this.disposeCore(\n false, // socketProtocolError\n createGenericNetworkError(\n // pre-0.58 error message: clientClosingConnection\n \"Client closing delta connection\", { canRetry: true }, { driverVersion }));\n }\n\n protected disposeCore(socketProtocolError: boolean, err: IAnyDriverError) {\n // Can't check this.disposed here, as we get here on socket closure,\n // so _disposed & socket.connected might be not in sync while processing\n // \"dispose\" event.\n if (this._disposed) {\n return;\n }\n\n // We set the disposed flag as a part of the contract for overriding the disconnect method. This is used by\n // DocumentDeltaConnection to determine if emitting messages (ops) on the socket is allowed, which is\n // important since OdspDocumentDeltaConnection reuses the socket rather than truly disconnecting it. Note that\n // OdspDocumentDeltaConnection may still send disconnect_document which is allowed; this is only intended\n // to prevent normal messages from being emitted.\n this._disposed = true;\n\n this.removeTrackedListeners();\n this.disconnect(socketProtocolError, err);\n }\n\n /**\n * Disconnect from the websocket.\n * @param socketProtocolError - true if error happened on socket / socket.io protocol level\n * (not on Fluid protocol level)\n * @param reason - reason for disconnect\n */\n protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {\n this.socket.disconnect();\n }\n\n protected async initialize(connectMessage: IConnect, timeout: number) {\n this.socket.on(\"op\", this.earlyOpHandler);\n this.socket.on(\"signal\", this.earlySignalHandler);\n this.earlyOpHandlerAttached = true;\n\n // Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.\n let internalSocketConnectionFailureCount: number = 0;\n const isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();\n const getMaxInternalSocketReconnectionAttempts = (): number => isInternalSocketReconnectionEnabled()\n ? this.socket.io.reconnectionAttempts()\n : 0;\n const getMaxAllowedInternalSocketConnectionFailures = (): number =>\n getMaxInternalSocketReconnectionAttempts() + 1;\n\n this._details = await new Promise<IConnected>((resolve, reject) => {\n const fail = (socketProtocolError: boolean, err: IAnyDriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\n internalSocketConnectionFailureCount++;\n let isWebSocketTransportError = false;\n try {\n const description = error?.description;\n if (description && typeof description === \"object\") {\n if (error.type === \"TransportError\") {\n isWebSocketTransportError = true;\n }\n // That's a WebSocket. Clear it as we can't log it.\n description.target = undefined;\n }\n } catch (_e) { }\n\n // Handle socket transport downgrading when not offline.\n if (\n isWebSocketTransportError &&\n this.enableLongPollingDowngrades &&\n this.socket.io.opts.transports?.[0] !== \"polling\") {\n // Downgrade transports to polling upgrade mechanism.\n this.socket.io.opts.transports = [\"polling\", \"websocket\"];\n // Don't alter reconnection behavior if already enabled.\n if (!isInternalSocketReconnectionEnabled()) {\n // Allow single reconnection attempt using polling upgrade mechanism.\n this.socket.io.reconnection(true);\n this.socket.io.reconnectionAttempts(1);\n }\n }\n\n // Allow built-in socket.io reconnection handling.\n if (isInternalSocketReconnectionEnabled() &&\n internalSocketConnectionFailureCount < getMaxAllowedInternalSocketConnectionFailures()) {\n // Reconnection is enabled and maximum reconnect attempts have not been reached.\n return;\n }\n\n fail(true, this.createErrorObject(\"connect_error\", error));\n });\n\n // Listen for timeouts\n this.addConnectionListener(\"connect_timeout\", () => {\n fail(true, this.createErrorObject(\"connect_timeout\"));\n });\n\n this.addConnectionListener(\"connect_document_success\", (response: IConnected) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n response.nonce !== undefined &&\n response.nonce !== connectMessage.nonce) {\n return;\n }\n\n const requestedMode = connectMessage.mode;\n const actualMode = response.mode;\n const writingPermitted = response.claims.scopes.includes(ScopeType.DocWrite);\n\n if (writingPermitted) {\n // The only time we expect a mismatch in requested/actual is if we lack write permissions\n // In this case we will get \"read\", even if we requested \"write\"\n if (actualMode !== requestedMode) {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in a different mode than was requested\",\n false,\n ));\n return;\n }\n } else {\n if (actualMode === \"write\") {\n fail(false, this.createErrorObject(\n \"connect_document_success\",\n \"Connected in write mode without write permissions\",\n false,\n ));\n return;\n }\n }\n\n this.checkpointSequenceNumber = response.checkpointSequenceNumber;\n\n this.removeConnectionListeners();\n resolve(response);\n });\n\n // Socket can be disconnected while waiting for Fluid protocol messages\n // (connect_document_error / connect_document_success), as well as before DeltaManager\n // had a chance to register its handlers.\n this.addTrackedListener(\"disconnect\", (reason) => {\n const err = this.createErrorObject(\"disconnect\", reason);\n this.emit(\"disconnect\", err);\n fail(true, err);\n });\n\n this.addTrackedListener(\"error\", ((error) => {\n // First, raise an error event, to give clients a chance to observe error contents\n // This includes \"Invalid namespace\" error, which we consider critical (reconnecting will not help)\n const err = this.createErrorObject(\"error\", error, error !== \"Invalid namespace\");\n this.emit(\"error\", err);\n // Disconnect socket - required if happened before initial handshake\n fail(true, err);\n }));\n\n this.addConnectionListener(\"connect_document_error\", ((error) => {\n // If we sent a nonce and the server supports nonces, check that the nonces match\n if (connectMessage.nonce !== undefined &&\n error.nonce !== undefined &&\n error.nonce !== connectMessage.nonce) {\n return;\n }\n\n // This is not an socket.io error - it's Fluid protocol error.\n // In this case fail connection and indicate that we were unable to create connection\n fail(false, this.createErrorObject(\"connect_document_error\", error));\n }));\n\n this.socket.emit(\"connect_document\", connectMessage);\n\n // Give extra 2 seconds for handshake on top of socket connection timeout\n this.socketConnectionTimeout = setTimeout(() => {\n fail(false, this.createErrorObject(\"orderingServiceHandshakeTimeout\"));\n }, timeout + 2000);\n });\n\n assert(!this.disposed, 0x246 /* \"checking consistency of socket & _disposed flags\" */);\n }\n\n protected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {\n this.queuedMessages.push(...msgs);\n };\n\n protected earlySignalHandler = (msg: ISignalMessage) => {\n this.queuedSignals.push(msg);\n };\n\n private removeEarlyOpHandler() {\n this.socket.removeListener(\"op\", this.earlyOpHandler);\n this.earlyOpHandlerAttached = false;\n }\n\n private removeEarlySignalHandler() {\n this.socket.removeListener(\"signal\", this.earlySignalHandler);\n }\n\n private addConnectionListener(event: string, listener: (...args: any[]) => void) {\n assert(!DocumentDeltaConnection.eventsAlwaysForwarded.includes(event),\n 0x247 /* \"Use addTrackedListener instead\" */);\n assert(!DocumentDeltaConnection.eventsToForward.includes(event),\n 0x248 /* \"should not subscribe to forwarded events\" */);\n this.socket.on(event, listener);\n assert(!this.connectionListeners.has(event), 0x20d /* \"double connection listener\" */);\n this.connectionListeners.set(event, listener);\n }\n\n protected addTrackedListener(event: string, listener: (...args: any[]) => void) {\n this.socket.on(event, listener);\n assert(!this.trackedListeners.has(event), 0x20e /* \"double tracked listener\" */);\n this.trackedListeners.set(event, listener);\n }\n\n private removeTrackedListeners() {\n for (const [event, listener] of this.trackedListeners.entries()) {\n this.socket.off(event, listener);\n }\n // removeTrackedListeners removes all listeners, including connection listeners\n this.removeConnectionListeners();\n\n this.removeEarlyOpHandler();\n this.removeEarlySignalHandler();\n\n this.trackedListeners.clear();\n }\n\n private removeConnectionListeners() {\n if (this.socketConnectionTimeout !== undefined) {\n clearTimeout(this.socketConnectionTimeout);\n }\n\n for (const [event, listener] of this.connectionListeners.entries()) {\n this.socket.off(event, listener);\n }\n this.connectionListeners.clear();\n }\n\n /**\n * Error raising for socket.io issues\n */\n protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {\n // Note: we suspect the incoming error object is either:\n // - a string: log it in the message (if not a string, it may contain PII but will print as [object Object])\n // - an Error object thrown by socket.io engine. Be careful with not recording PII!\n let message: string;\n if (error?.type === \"TransportError\") {\n // JSON.stringify drops Error.message\n const messagePrefix = (error?.message !== undefined)\n ? `${error.message}: `\n : \"\";\n\n // Websocket errors reported by engine.io-client.\n // They are Error objects with description containing WS error and description = \"TransportError\"\n // Please see https://github.com/socketio/engine.io-client/blob/7245b80/lib/transport.ts#L44,\n message = `${messagePrefix}${JSON.stringify(error, getCircularReplacer())}`;\n } else {\n message = extractLogSafeErrorProperties(error).message;\n }\n\n const errorObj = createGenericNetworkError(\n `socket.io (${handler}): ${message}`,\n { canRetry },\n { driverVersion },\n );\n\n return errorObj;\n }\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 = "0.59.3003";
8
+ export declare const pkgVersion = "0.59.4000-71128";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,cAAc,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,oBAAoB,CAAC"}
@@ -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 = "0.59.3003";
8
+ export const pkgVersion = "0.59.4000-71128";
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,WAAW,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 = \"0.59.3003\";\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,iBAAiB,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 = \"0.59.4000-71128\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/driver-base",
3
- "version": "0.59.3003",
3
+ "version": "0.59.4000-71128",
4
4
  "description": "Shared driver code for Fluid driver implementations",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -35,10 +35,10 @@
35
35
  "dependencies": {
36
36
  "@fluidframework/common-definitions": "^0.20.1",
37
37
  "@fluidframework/common-utils": "^0.32.1",
38
- "@fluidframework/driver-definitions": "^0.46.1000",
39
- "@fluidframework/driver-utils": "^0.59.3003",
40
- "@fluidframework/protocol-definitions": "^0.1028.1000",
41
- "@fluidframework/telemetry-utils": "^0.59.3003"
38
+ "@fluidframework/driver-definitions": "^0.46.2000-0",
39
+ "@fluidframework/driver-utils": "0.59.4000-71128",
40
+ "@fluidframework/protocol-definitions": "^0.1028.2000-0",
41
+ "@fluidframework/telemetry-utils": "0.59.4000-71128"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@fluidframework/build-common": "^0.23.0",
@@ -56,18 +56,20 @@
56
56
  "eslint-plugin-eslint-comments": "~3.2.0",
57
57
  "eslint-plugin-import": "~2.25.4",
58
58
  "eslint-plugin-jest": "~26.1.3",
59
+ "eslint-plugin-jsdoc": "~39.3.0",
59
60
  "eslint-plugin-mocha": "~10.0.3",
60
61
  "eslint-plugin-promise": "~6.0.0",
61
62
  "eslint-plugin-react": "~7.28.0",
62
63
  "eslint-plugin-tsdoc": "~0.2.14",
63
64
  "eslint-plugin-unicorn": "~40.0.0",
65
+ "eslint-plugin-unused-imports": "~2.0.0",
64
66
  "rimraf": "^2.6.2",
65
67
  "socket.io-client": "^4.4.1",
66
68
  "typescript": "~4.5.5",
67
69
  "typescript-formatter": "7.1.0"
68
70
  },
69
71
  "typeValidation": {
70
- "version": "0.59.3001",
72
+ "version": "0.59.4000",
71
73
  "broken": {}
72
74
  }
73
75
  }
@@ -66,8 +66,6 @@ export class DocumentDeltaConnection
66
66
 
67
67
  private _details: IConnected | undefined;
68
68
 
69
- private reconnectAttempts: number = 0;
70
-
71
69
  // Listeners only needed while the connection is in progress
72
70
  private readonly connectionListeners: Map<string, (...args: any[]) => void> = new Map();
73
71
  // Listeners used throughout the lifetime of the DocumentDeltaConnection
@@ -344,6 +342,15 @@ export class DocumentDeltaConnection
344
342
  this.socket.on("signal", this.earlySignalHandler);
345
343
  this.earlyOpHandlerAttached = true;
346
344
 
345
+ // Socket.io's reconnect_attempt event is unreliable, so we track connect_error count instead.
346
+ let internalSocketConnectionFailureCount: number = 0;
347
+ const isInternalSocketReconnectionEnabled = (): boolean => this.socket.io.reconnection();
348
+ const getMaxInternalSocketReconnectionAttempts = (): number => isInternalSocketReconnectionEnabled()
349
+ ? this.socket.io.reconnectionAttempts()
350
+ : 0;
351
+ const getMaxAllowedInternalSocketConnectionFailures = (): number =>
352
+ getMaxInternalSocketReconnectionAttempts() + 1;
353
+
347
354
  this._details = await new Promise<IConnected>((resolve, reject) => {
348
355
  const fail = (socketProtocolError: boolean, err: IAnyDriverError) => {
349
356
  this.disposeCore(socketProtocolError, err);
@@ -352,6 +359,7 @@ export class DocumentDeltaConnection
352
359
 
353
360
  // Listen for connection issues
354
361
  this.addConnectionListener("connect_error", (error) => {
362
+ internalSocketConnectionFailureCount++;
355
363
  let isWebSocketTransportError = false;
356
364
  try {
357
365
  const description = error?.description;
@@ -362,16 +370,17 @@ export class DocumentDeltaConnection
362
370
  // That's a WebSocket. Clear it as we can't log it.
363
371
  description.target = undefined;
364
372
  }
365
- } catch (_e) {}
373
+ } catch (_e) { }
366
374
 
367
- // Handle socket transport downgrading.
368
- if (isWebSocketTransportError &&
375
+ // Handle socket transport downgrading when not offline.
376
+ if (
377
+ isWebSocketTransportError &&
369
378
  this.enableLongPollingDowngrades &&
370
379
  this.socket.io.opts.transports?.[0] !== "polling") {
371
380
  // Downgrade transports to polling upgrade mechanism.
372
381
  this.socket.io.opts.transports = ["polling", "websocket"];
373
382
  // Don't alter reconnection behavior if already enabled.
374
- if (!this.socket.io.reconnection()) {
383
+ if (!isInternalSocketReconnectionEnabled()) {
375
384
  // Allow single reconnection attempt using polling upgrade mechanism.
376
385
  this.socket.io.reconnection(true);
377
386
  this.socket.io.reconnectionAttempts(1);
@@ -379,8 +388,8 @@ export class DocumentDeltaConnection
379
388
  }
380
389
 
381
390
  // Allow built-in socket.io reconnection handling.
382
- if (this.socket.io.reconnection() &&
383
- this.reconnectAttempts < this.socket.io.reconnectionAttempts()) {
391
+ if (isInternalSocketReconnectionEnabled() &&
392
+ internalSocketConnectionFailureCount < getMaxAllowedInternalSocketConnectionFailures()) {
384
393
  // Reconnection is enabled and maximum reconnect attempts have not been reached.
385
394
  return;
386
395
  }
@@ -388,10 +397,6 @@ export class DocumentDeltaConnection
388
397
  fail(true, this.createErrorObject("connect_error", error));
389
398
  });
390
399
 
391
- this.addConnectionListener("reconnect_attempt", () => {
392
- this.reconnectAttempts++;
393
- });
394
-
395
400
  // Listen for timeouts
396
401
  this.addConnectionListener("connect_timeout", () => {
397
402
  fail(true, this.createErrorObject("connect_timeout"));
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/driver-base";
9
- export const pkgVersion = "0.59.3003";
9
+ export const pkgVersion = "0.59.4000-71128";