@fluidframework/driver-base 0.47.0-36699 → 0.48.0-38142
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/documentDeltaConnection.js +7 -7
- package/dist/documentDeltaConnection.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/documentDeltaConnection.js +7 -7
- package/lib/documentDeltaConnection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +3 -3
- package/src/documentDeltaConnection.ts +7 -7
- package/src/packageVersion.ts +1 -1
|
@@ -237,7 +237,7 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
|
|
|
237
237
|
*/
|
|
238
238
|
dispose() {
|
|
239
239
|
this.disposeCore(false, // socketProtocolError
|
|
240
|
-
driver_utils_1.createGenericNetworkError("
|
|
240
|
+
driver_utils_1.createGenericNetworkError("clientClosingConnection", true /* canRetry */));
|
|
241
241
|
}
|
|
242
242
|
// back-compat: became @deprecated in 0.45 / driver-definitions 0.40
|
|
243
243
|
close() { this.dispose(); }
|
|
@@ -277,11 +277,11 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
|
|
|
277
277
|
};
|
|
278
278
|
// Listen for connection issues
|
|
279
279
|
this.addConnectionListener("connect_error", (error) => {
|
|
280
|
-
fail(true, this.createErrorObject("
|
|
280
|
+
fail(true, this.createErrorObject("connectError", error));
|
|
281
281
|
});
|
|
282
282
|
// Listen for timeouts
|
|
283
283
|
this.addConnectionListener("connect_timeout", () => {
|
|
284
|
-
fail(true, this.createErrorObject("
|
|
284
|
+
fail(true, this.createErrorObject("connectTimeout"));
|
|
285
285
|
});
|
|
286
286
|
this.addConnectionListener("connect_document_success", (response) => {
|
|
287
287
|
// If we sent a nonce and the server supports nonces, check that the nonces match
|
|
@@ -297,13 +297,13 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
|
|
|
297
297
|
// The only time we expect a mismatch in requested/actual is if we lack write permissions
|
|
298
298
|
// In this case we will get "read", even if we requested "write"
|
|
299
299
|
if (actualMode !== requestedMode) {
|
|
300
|
-
fail(false, this.createErrorObject("
|
|
300
|
+
fail(false, this.createErrorObject("connectDocumentSuccess", "Connected in a different mode than was requested", false));
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
else {
|
|
305
305
|
if (actualMode === "write") {
|
|
306
|
-
fail(false, this.createErrorObject("
|
|
306
|
+
fail(false, this.createErrorObject("connectDocumentSuccess", "Connected in write mode without write permissions", false));
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
309
309
|
}
|
|
@@ -336,12 +336,12 @@ class DocumentDeltaConnection extends common_utils_1.TypedEventEmitter {
|
|
|
336
336
|
}
|
|
337
337
|
// This is not an socket.io error - it's Fluid protocol error.
|
|
338
338
|
// In this case fail connection and indicate that we were unable to create connection
|
|
339
|
-
fail(false, this.createErrorObject("
|
|
339
|
+
fail(false, this.createErrorObject("connectDocumentError", error));
|
|
340
340
|
}));
|
|
341
341
|
this.socket.emit("connect_document", connectMessage);
|
|
342
342
|
// Give extra 2 seconds for handshake on top of socket connection timeout
|
|
343
343
|
this.socketConnectionTimeout = setTimeout(() => {
|
|
344
|
-
fail(false, this.createErrorObject("
|
|
344
|
+
fail(false, this.createErrorObject("orderingServiceHandshakeTimeout"));
|
|
345
345
|
}, timeout + 2000);
|
|
346
346
|
});
|
|
347
347
|
common_utils_1.assert(!this.disposed, 0x246 /* "checking consistency of socket & _disposed flags" */);
|
|
@@ -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, BatchManager, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n DriverError,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } 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 { ChildLogger } from \"@fluidframework/telemetry-utils\";\n\n// Local storage key to disable the BatchManager\nconst batchManagerDisabledKey = \"FluidDisableBatchManager\";\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 protected readonly submitManager: BatchManager<IDocumentMessage[]>;\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 protected readonly logger: ITelemetryLogger;\n protected readonly isBatchManagerDisabled: boolean = false;\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 */\n protected constructor(\n protected readonly socket: SocketIOClient.Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n ) {\n super();\n\n this.logger = ChildLogger.create(logger, \"DeltaConnection\");\n\n this.submitManager = new BatchManager<IDocumentMessage[]>(\n (submitType, work) => this.emitMessages(submitType, work));\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 this.isBatchManagerDisabled = DocumentDeltaConnection.disabledBatchManagerFeatureGate;\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.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 private static get disabledBatchManagerFeatureGate() {\n try {\n return localStorage !== undefined\n && typeof localStorage === \"object\"\n && localStorage.getItem(batchManagerDisabledKey) === \"1\";\n } catch (e) { }\n return false;\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n if (this.isBatchManagerDisabled) {\n this.emitMessages(type, [messages]);\n } else {\n this.submitManager.add(type, messages);\n }\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(\"client closing connection\", true /* canRetry */));\n }\n\n // back-compat: became @deprecated in 0.45 / driver-definitions 0.40\n public close() { this.dispose(); }\n\n protected disposeCore(socketProtocolError: boolean, err: DriverError) {\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: DriverError) {\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: DriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\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(\"Timeout waiting for handshake from ordering service\"));\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): DriverError {\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 // - a socketError: add it to the OdspError object for driver to be able to parse it and reason\n // over it.\n let message = `socket.io: ${handler}`;\n if (typeof error === \"string\") {\n message = `${message}: ${error}`;\n }\n const errorObj = createGenericNetworkError(\n message,\n canRetry,\n );\n\n return errorObj;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentDeltaConnection.js","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAuF;AAMvF,+DAAyE;AACzE,+EAW8C;AAE9C,qEAA8D;AAE9D,gDAAgD;AAChD,MAAM,uBAAuB,GAAG,0BAA0B,CAAC;AAE3D;;GAEG;AACH,MAAa,uBACT,SAAQ,gCAAiD;IA4DzD;;;OAGG;IACH,YACuB,MAA6B,EACzC,UAAkB,EACzB,MAAwB;QAExB,KAAK,EAAE,CAAC;QAJW,WAAM,GAAN,MAAM,CAAuB;QACzC,eAAU,GAAV,UAAU,CAAQ;QAjD7B,uEAAuE;QACpD,mBAAc,GAAgC,EAAE,CAAC;QACjD,kBAAa,GAAqB,EAAE,CAAC;QACxD;;;WAGG;QACK,2BAAsB,GAAY,KAAK,CAAC;QAQhD,4DAA4D;QAC3C,wBAAmB,GAA0C,IAAI,GAAG,EAAE,CAAC;QACxF,wEAAwE;QACvD,qBAAgB,GAA0C,IAAI,GAAG,EAAE,CAAC;QAUrF;;;WAGG;QACO,cAAS,GAAY,KAAK,CAAC;QAElB,2BAAsB,GAAY,KAAK,CAAC;QA6WjD,mBAAc,GAAG,CAAC,UAAkB,EAAE,IAAiC,EAAE,EAAE;YACjF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC;QAEQ,uBAAkB,GAAG,CAAC,GAAmB,EAAE,EAAE;YACnD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC,CAAC;QA/VE,IAAI,CAAC,MAAM,GAAG,6BAAW,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAE5D,IAAI,CAAC,aAAa,GAAG,IAAI,2BAAY,CACjC,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QAE/D,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACvC,qBAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAE5E,2FAA2F;YAC3F,IAAI,uBAAuB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAC/D,qBAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBACzE,OAAO;aACV;YAED,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAC1D,MAAM,IAAI,KAAK,CAAC,2DAA2D,KAAK,EAAE,CAAC,CAAC;aACvF;YAED,+FAA+F;YAC/F,kGAAkG;YAClG,yFAAyF;YACzF,iGAAiG;YACjG,0GAA0G;YAC1G,qBAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC1G,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBACnC,IAAI,CAAC,kBAAkB,CACnB,KAAK,EACL,CAAC,GAAG,IAAW,EAAE,EAAE;oBACf,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;gBAC9B,CAAC,CAAC,CAAC;aACV;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,sBAAsB,GAAG,uBAAuB,CAAC,+BAA+B,CAAC;IAC1F,CAAC;IApED,IAAc,UAAU;QACpB,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAW,QAAQ;QACf,qBAAM,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACxG,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IASD,IAAW,OAAO;QACd,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;SACrF;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAiDD;;;;OAIG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAW,cAAc;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,IAAW,OAAO;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,IAAW,oBAAoB;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;IAC7C,CAAC;IAEO,cAAc;QAClB,qBAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,IAAW,eAAe;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,uGAAuG;QACvG,mFAAmF;QACnF,qBAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACvF,qFAAqF;QACrF,qBAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAEjF,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE5B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,6BAA6B;YAC7B,0DAA0D;YAC1D,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1D,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;YACjF,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;SAClC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,IAAW,cAAc;QACrB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,qBAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAEzF,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;YAC/B,4BAA4B;YAC5B,yDAAyD;YACzD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;YACxD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,IAAW,cAAc;QACrB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;IAES,YAAY,CAAC,IAAY,EAAE,QAA8B;QAC/D,kGAAkG;QAClG,sGAAsG;QACtG,4BAA4B;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;SACnD;IACL,CAAC;IAEO,MAAM,KAAK,+BAA+B;QAC9C,IAAI;YACA,OAAO,YAAY,KAAK,SAAS;mBAC1B,OAAO,YAAY,KAAK,QAAQ;mBAChC,YAAY,CAAC,OAAO,CAAC,uBAAuB,CAAC,KAAK,GAAG,CAAC;SAChE;QAAC,OAAO,CAAC,EAAE,GAAG;QACf,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,UAAU,CAAC,IAAY,EAAE,QAA4B;QAC3D,IAAI,IAAI,CAAC,sBAAsB,EAAE;YAC7B,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;SACvC;aAAM;YACH,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;SAC1C;IACL,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAA4B;QACtC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,YAAY,CAAC,OAAyB;QACzC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,CAAC,WAAW,CACZ,KAAK,EAAE,sBAAsB;QAC7B,wCAAyB,CAAC,yBAAyB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,oEAAoE;IAC7D,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAExB,WAAW,CAAC,mBAA4B,EAAE,GAAgB;QAChE,oEAAoE;QACpE,wEAAwE;QACxE,mBAAmB;QACnB,IAAI,IAAI,CAAC,SAAS,EAAE;YAChB,OAAO;SACV;QAED,2GAA2G;QAC3G,qGAAqG;QACrG,8GAA8G;QAC9G,yGAAyG;QACzG,iDAAiD;QACjD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACO,UAAU,CAAC,mBAA4B,EAAE,MAAmB;QAClE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,cAAwB,EAAE,OAAe;QAChE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QAEnC,IAAI,CAAC,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAC,mBAA4B,EAAE,GAAgB,EAAE,EAAE;gBAC5D,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;gBAC3C,MAAM,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC,CAAC;YAEF,+BAA+B;YAC/B,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClD,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;YAEH,sBAAsB;YACtB,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,GAAG,EAAE;gBAC/C,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,qBAAqB,CAAC,0BAA0B,EAAE,CAAC,QAAoB,EAAE,EAAE;gBAC5E,iFAAiF;gBACjF,IAAI,cAAc,CAAC,KAAK,KAAK,SAAS;oBAClC,QAAQ,CAAC,KAAK,KAAK,SAAS;oBAC5B,QAAQ,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,EAAE;oBACzC,OAAO;iBACV;gBAED,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC;gBAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;gBACjC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,gCAAS,CAAC,QAAQ,CAAC,CAAC;gBAE7E,IAAI,gBAAgB,EAAE;oBAClB,yFAAyF;oBACzF,gEAAgE;oBAChE,IAAI,UAAU,KAAK,aAAa,EAAE;wBAC9B,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAC9B,wBAAwB,EACxB,kDAAkD,EAClD,KAAK,CACR,CAAC,CAAC;wBACH,OAAO;qBACV;iBACJ;qBAAM;oBACH,IAAI,UAAU,KAAK,OAAO,EAAE;wBACxB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAC9B,wBAAwB,EACxB,mDAAmD,EACnD,KAAK,CACR,CAAC,CAAC;wBACH,OAAO;qBACV;iBACJ;gBAED,IAAI,CAAC,wBAAwB,GAAG,QAAQ,CAAC,wBAAwB,CAAC;gBAElE,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACjC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YAEH,uEAAuE;YACvE,sFAAsF;YACtF,yCAAyC;YACzC,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;gBACzD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE;gBACxC,kFAAkF;gBAClF,mGAAmG;gBACnG,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,mBAAmB,CAAC,CAAC;gBAClF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACxB,oEAAoE;gBACpE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,qBAAqB,CAAC,wBAAwB,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC5D,iFAAiF;gBACjF,IAAI,cAAc,CAAC,KAAK,KAAK,SAAS;oBAClC,KAAK,CAAC,KAAK,KAAK,SAAS;oBACzB,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,EAAE;oBACtC,OAAO;iBACV;gBAED,8DAA8D;gBAC9D,qFAAqF;gBACrF,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAErD,yEAAyE;YACzE,IAAI,CAAC,uBAAuB,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC3C,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAC3E,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,qBAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC3F,CAAC;IAUO,oBAAoB;QACxB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACtD,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;IACxC,CAAC;IAEO,wBAAwB;QAC5B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAEO,qBAAqB,CAAC,KAAa,EAAE,QAAkC;QAC3E,qBAAM,CAAC,CAAC,uBAAuB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,EACjE,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAClD,qBAAM,CAAC,CAAC,uBAAuB,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC3D,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChC,qBAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACvF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAES,kBAAkB,CAAC,KAAa,EAAE,QAAkC;QAC1E,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChC,qBAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACjF,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAEO,sBAAsB;QAC1B,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE;YAC7D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SACpC;QACD,+EAA+E;QAC/E,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAEjC,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAEO,yBAAyB;QAC7B,IAAI,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAAE;YAC5C,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;SAC9C;QAED,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE;YAChE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SACpC;QACD,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACO,iBAAiB,CAAC,OAAe,EAAE,KAAW,EAAE,QAAQ,GAAG,IAAI;QACrE,wDAAwD;QACxD,4GAA4G;QAC5G,+FAA+F;QAC/F,aAAa;QACb,IAAI,OAAO,GAAG,cAAc,OAAO,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC3B,OAAO,GAAG,GAAG,OAAO,KAAK,KAAK,EAAE,CAAC;SACpC;QACD,MAAM,QAAQ,GAAG,wCAAyB,CACtC,OAAO,EACP,QAAQ,CACX,CAAC;QAEF,OAAO,QAAQ,CAAC;IACpB,CAAC;;AA5eL,0DA6eC;AA1emB,uCAAe,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAEnE,mHAAmH;AACnH,oHAAoH;AACpG,6CAAqB,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, BatchManager, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n DriverError,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } 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 { ChildLogger } from \"@fluidframework/telemetry-utils\";\n\n// Local storage key to disable the BatchManager\nconst batchManagerDisabledKey = \"FluidDisableBatchManager\";\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 protected readonly submitManager: BatchManager<IDocumentMessage[]>;\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 protected readonly logger: ITelemetryLogger;\n protected readonly isBatchManagerDisabled: boolean = false;\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 */\n protected constructor(\n protected readonly socket: SocketIOClient.Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n ) {\n super();\n\n this.logger = ChildLogger.create(logger, \"DeltaConnection\");\n\n this.submitManager = new BatchManager<IDocumentMessage[]>(\n (submitType, work) => this.emitMessages(submitType, work));\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 this.isBatchManagerDisabled = DocumentDeltaConnection.disabledBatchManagerFeatureGate;\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.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 private static get disabledBatchManagerFeatureGate() {\n try {\n return localStorage !== undefined\n && typeof localStorage === \"object\"\n && localStorage.getItem(batchManagerDisabledKey) === \"1\";\n } catch (e) { }\n return false;\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n if (this.isBatchManagerDisabled) {\n this.emitMessages(type, [messages]);\n } else {\n this.submitManager.add(type, messages);\n }\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(\"clientClosingConnection\", true /* canRetry */));\n }\n\n // back-compat: became @deprecated in 0.45 / driver-definitions 0.40\n public close() { this.dispose(); }\n\n protected disposeCore(socketProtocolError: boolean, err: DriverError) {\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: DriverError) {\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: DriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\n fail(true, this.createErrorObject(\"connectError\", error));\n });\n\n // Listen for timeouts\n this.addConnectionListener(\"connect_timeout\", () => {\n fail(true, this.createErrorObject(\"connectTimeout\"));\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 \"connectDocumentSuccess\",\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 \"connectDocumentSuccess\",\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(\"connectDocumentError\", 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): DriverError {\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 // - a socketError: add it to the OdspError object for driver to be able to parse it and reason\n // over it.\n let message = `socket.io: ${handler}`;\n if (typeof error === \"string\") {\n message = `${message}: ${error}`;\n }\n const errorObj = createGenericNetworkError(\n message,\n canRetry,\n );\n\n return errorObj;\n }\n}\n"]}
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -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.
|
|
8
|
+
export declare const pkgVersion = "0.48.0-38142";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/dist/packageVersion.js
CHANGED
|
@@ -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.
|
|
11
|
+
exports.pkgVersion = "0.48.0-38142";
|
|
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,cAAc,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.
|
|
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,cAAc,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.48.0-38142\";\n"]}
|
|
@@ -234,7 +234,7 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
|
|
|
234
234
|
*/
|
|
235
235
|
dispose() {
|
|
236
236
|
this.disposeCore(false, // socketProtocolError
|
|
237
|
-
createGenericNetworkError("
|
|
237
|
+
createGenericNetworkError("clientClosingConnection", true /* canRetry */));
|
|
238
238
|
}
|
|
239
239
|
// back-compat: became @deprecated in 0.45 / driver-definitions 0.40
|
|
240
240
|
close() { this.dispose(); }
|
|
@@ -274,11 +274,11 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
|
|
|
274
274
|
};
|
|
275
275
|
// Listen for connection issues
|
|
276
276
|
this.addConnectionListener("connect_error", (error) => {
|
|
277
|
-
fail(true, this.createErrorObject("
|
|
277
|
+
fail(true, this.createErrorObject("connectError", error));
|
|
278
278
|
});
|
|
279
279
|
// Listen for timeouts
|
|
280
280
|
this.addConnectionListener("connect_timeout", () => {
|
|
281
|
-
fail(true, this.createErrorObject("
|
|
281
|
+
fail(true, this.createErrorObject("connectTimeout"));
|
|
282
282
|
});
|
|
283
283
|
this.addConnectionListener("connect_document_success", (response) => {
|
|
284
284
|
// If we sent a nonce and the server supports nonces, check that the nonces match
|
|
@@ -294,13 +294,13 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
|
|
|
294
294
|
// The only time we expect a mismatch in requested/actual is if we lack write permissions
|
|
295
295
|
// In this case we will get "read", even if we requested "write"
|
|
296
296
|
if (actualMode !== requestedMode) {
|
|
297
|
-
fail(false, this.createErrorObject("
|
|
297
|
+
fail(false, this.createErrorObject("connectDocumentSuccess", "Connected in a different mode than was requested", false));
|
|
298
298
|
return;
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
else {
|
|
302
302
|
if (actualMode === "write") {
|
|
303
|
-
fail(false, this.createErrorObject("
|
|
303
|
+
fail(false, this.createErrorObject("connectDocumentSuccess", "Connected in write mode without write permissions", false));
|
|
304
304
|
return;
|
|
305
305
|
}
|
|
306
306
|
}
|
|
@@ -333,12 +333,12 @@ export class DocumentDeltaConnection extends TypedEventEmitter {
|
|
|
333
333
|
}
|
|
334
334
|
// This is not an socket.io error - it's Fluid protocol error.
|
|
335
335
|
// In this case fail connection and indicate that we were unable to create connection
|
|
336
|
-
fail(false, this.createErrorObject("
|
|
336
|
+
fail(false, this.createErrorObject("connectDocumentError", error));
|
|
337
337
|
}));
|
|
338
338
|
this.socket.emit("connect_document", connectMessage);
|
|
339
339
|
// Give extra 2 seconds for handshake on top of socket connection timeout
|
|
340
340
|
this.socketConnectionTimeout = setTimeout(() => {
|
|
341
|
-
fail(false, this.createErrorObject("
|
|
341
|
+
fail(false, this.createErrorObject("orderingServiceHandshakeTimeout"));
|
|
342
342
|
}, timeout + 2000);
|
|
343
343
|
});
|
|
344
344
|
assert(!this.disposed, 0x246 /* "checking consistency of socket & _disposed flags" */);
|
|
@@ -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, BatchManager, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n DriverError,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } 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 { ChildLogger } from \"@fluidframework/telemetry-utils\";\n\n// Local storage key to disable the BatchManager\nconst batchManagerDisabledKey = \"FluidDisableBatchManager\";\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 protected readonly submitManager: BatchManager<IDocumentMessage[]>;\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 protected readonly logger: ITelemetryLogger;\n protected readonly isBatchManagerDisabled: boolean = false;\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 */\n protected constructor(\n protected readonly socket: SocketIOClient.Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n ) {\n super();\n\n this.logger = ChildLogger.create(logger, \"DeltaConnection\");\n\n this.submitManager = new BatchManager<IDocumentMessage[]>(\n (submitType, work) => this.emitMessages(submitType, work));\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 this.isBatchManagerDisabled = DocumentDeltaConnection.disabledBatchManagerFeatureGate;\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.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 private static get disabledBatchManagerFeatureGate() {\n try {\n return localStorage !== undefined\n && typeof localStorage === \"object\"\n && localStorage.getItem(batchManagerDisabledKey) === \"1\";\n } catch (e) { }\n return false;\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n if (this.isBatchManagerDisabled) {\n this.emitMessages(type, [messages]);\n } else {\n this.submitManager.add(type, messages);\n }\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(\"client closing connection\", true /* canRetry */));\n }\n\n // back-compat: became @deprecated in 0.45 / driver-definitions 0.40\n public close() { this.dispose(); }\n\n protected disposeCore(socketProtocolError: boolean, err: DriverError) {\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: DriverError) {\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: DriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\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(\"Timeout waiting for handshake from ordering service\"));\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): DriverError {\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 // - a socketError: add it to the OdspError object for driver to be able to parse it and reason\n // over it.\n let message = `socket.io: ${handler}`;\n if (typeof error === \"string\") {\n message = `${message}: ${error}`;\n }\n const errorObj = createGenericNetworkError(\n message,\n canRetry,\n );\n\n return errorObj;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentDeltaConnection.js","sourceRoot":"","sources":["../src/documentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAMvF,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAUH,SAAS,GACZ,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,gDAAgD;AAChD,MAAM,uBAAuB,GAAG,0BAA0B,CAAC;AAE3D;;GAEG;AACH,MAAM,OAAO,uBACT,SAAQ,iBAAiD;IA4DzD;;;OAGG;IACH,YACuB,MAA6B,EACzC,UAAkB,EACzB,MAAwB;QAExB,KAAK,EAAE,CAAC;QAJW,WAAM,GAAN,MAAM,CAAuB;QACzC,eAAU,GAAV,UAAU,CAAQ;QAjD7B,uEAAuE;QACpD,mBAAc,GAAgC,EAAE,CAAC;QACjD,kBAAa,GAAqB,EAAE,CAAC;QACxD;;;WAGG;QACK,2BAAsB,GAAY,KAAK,CAAC;QAQhD,4DAA4D;QAC3C,wBAAmB,GAA0C,IAAI,GAAG,EAAE,CAAC;QACxF,wEAAwE;QACvD,qBAAgB,GAA0C,IAAI,GAAG,EAAE,CAAC;QAUrF;;;WAGG;QACO,cAAS,GAAY,KAAK,CAAC;QAElB,2BAAsB,GAAY,KAAK,CAAC;QA6WjD,mBAAc,GAAG,CAAC,UAAkB,EAAE,IAAiC,EAAE,EAAE;YACjF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC;QAEQ,uBAAkB,GAAG,CAAC,GAAmB,EAAE,EAAE;YACnD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC,CAAC;QA/VE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAE5D,IAAI,CAAC,aAAa,GAAG,IAAI,YAAY,CACjC,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QAE/D,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACvC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAE5E,2FAA2F;YAC3F,IAAI,uBAAuB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAC/D,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBACzE,OAAO;aACV;YAED,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAC1D,MAAM,IAAI,KAAK,CAAC,2DAA2D,KAAK,EAAE,CAAC,CAAC;aACvF;YAED,+FAA+F;YAC/F,kGAAkG;YAClG,yFAAyF;YACzF,iGAAiG;YACjG,0GAA0G;YAC1G,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC1G,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBACnC,IAAI,CAAC,kBAAkB,CACnB,KAAK,EACL,CAAC,GAAG,IAAW,EAAE,EAAE;oBACf,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;gBAC9B,CAAC,CAAC,CAAC;aACV;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,sBAAsB,GAAG,uBAAuB,CAAC,+BAA+B,CAAC;IAC1F,CAAC;IApED,IAAc,UAAU;QACpB,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAW,QAAQ;QACf,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACxG,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IASD,IAAW,OAAO;QACd,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;SACrF;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAiDD;;;;OAIG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,IAAW,cAAc;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,IAAW,OAAO;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,IAAW,oBAAoB;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;IAC7C,CAAC;IAEO,cAAc;QAClB,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,IAAW,eAAe;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,uGAAuG;QACvG,mFAAmF;QACnF,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACvF,qFAAqF;QACrF,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAEjF,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE5B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,6BAA6B;YAC7B,0DAA0D;YAC1D,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1D,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;YACjF,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;SAClC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,IAAW,cAAc;QACrB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAEzF,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;YAC/B,4BAA4B;YAC5B,yDAAyD;YACzD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;YACxD,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,IAAW,cAAc;QACrB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;IAES,YAAY,CAAC,IAAY,EAAE,QAA8B;QAC/D,kGAAkG;QAClG,sGAAsG;QACtG,4BAA4B;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;SACnD;IACL,CAAC;IAEO,MAAM,KAAK,+BAA+B;QAC9C,IAAI;YACA,OAAO,YAAY,KAAK,SAAS;mBAC1B,OAAO,YAAY,KAAK,QAAQ;mBAChC,YAAY,CAAC,OAAO,CAAC,uBAAuB,CAAC,KAAK,GAAG,CAAC;SAChE;QAAC,OAAO,CAAC,EAAE,GAAG;QACf,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,UAAU,CAAC,IAAY,EAAE,QAA4B;QAC3D,IAAI,IAAI,CAAC,sBAAsB,EAAE;YAC7B,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;SACvC;aAAM;YACH,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;SAC1C;IACL,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAA4B;QACtC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,YAAY,CAAC,OAAyB;QACzC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,CAAC,WAAW,CACZ,KAAK,EAAE,sBAAsB;QAC7B,yBAAyB,CAAC,yBAAyB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,oEAAoE;IAC7D,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAExB,WAAW,CAAC,mBAA4B,EAAE,GAAgB;QAChE,oEAAoE;QACpE,wEAAwE;QACxE,mBAAmB;QACnB,IAAI,IAAI,CAAC,SAAS,EAAE;YAChB,OAAO;SACV;QAED,2GAA2G;QAC3G,qGAAqG;QACrG,8GAA8G;QAC9G,yGAAyG;QACzG,iDAAiD;QACjD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACO,UAAU,CAAC,mBAA4B,EAAE,MAAmB;QAClE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,cAAwB,EAAE,OAAe;QAChE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QAEnC,IAAI,CAAC,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAC,mBAA4B,EAAE,GAAgB,EAAE,EAAE;gBAC5D,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;gBAC3C,MAAM,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC,CAAC;YAEF,+BAA+B;YAC/B,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClD,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;YAEH,sBAAsB;YACtB,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,GAAG,EAAE;gBAC/C,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,qBAAqB,CAAC,0BAA0B,EAAE,CAAC,QAAoB,EAAE,EAAE;gBAC5E,iFAAiF;gBACjF,IAAI,cAAc,CAAC,KAAK,KAAK,SAAS;oBAClC,QAAQ,CAAC,KAAK,KAAK,SAAS;oBAC5B,QAAQ,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,EAAE;oBACzC,OAAO;iBACV;gBAED,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC;gBAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;gBACjC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAE7E,IAAI,gBAAgB,EAAE;oBAClB,yFAAyF;oBACzF,gEAAgE;oBAChE,IAAI,UAAU,KAAK,aAAa,EAAE;wBAC9B,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAC9B,wBAAwB,EACxB,kDAAkD,EAClD,KAAK,CACR,CAAC,CAAC;wBACH,OAAO;qBACV;iBACJ;qBAAM;oBACH,IAAI,UAAU,KAAK,OAAO,EAAE;wBACxB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAC9B,wBAAwB,EACxB,mDAAmD,EACnD,KAAK,CACR,CAAC,CAAC;wBACH,OAAO;qBACV;iBACJ;gBAED,IAAI,CAAC,wBAAwB,GAAG,QAAQ,CAAC,wBAAwB,CAAC;gBAElE,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACjC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YAEH,uEAAuE;YACvE,sFAAsF;YACtF,yCAAyC;YACzC,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;gBACzD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE;gBACxC,kFAAkF;gBAClF,mGAAmG;gBACnG,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,mBAAmB,CAAC,CAAC;gBAClF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACxB,oEAAoE;gBACpE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,qBAAqB,CAAC,wBAAwB,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC5D,iFAAiF;gBACjF,IAAI,cAAc,CAAC,KAAK,KAAK,SAAS;oBAClC,KAAK,CAAC,KAAK,KAAK,SAAS;oBACzB,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC,KAAK,EAAE;oBACtC,OAAO;iBACV;gBAED,8DAA8D;gBAC9D,qFAAqF;gBACrF,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAErD,yEAAyE;YACzE,IAAI,CAAC,uBAAuB,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC3C,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAC3E,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC3F,CAAC;IAUO,oBAAoB;QACxB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACtD,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;IACxC,CAAC;IAEO,wBAAwB;QAC5B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAEO,qBAAqB,CAAC,KAAa,EAAE,QAAkC;QAC3E,MAAM,CAAC,CAAC,uBAAuB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,EACjE,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAClD,MAAM,CAAC,CAAC,uBAAuB,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC3D,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChC,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACvF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAES,kBAAkB,CAAC,KAAa,EAAE,QAAkC;QAC1E,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAChC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACjF,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAEO,sBAAsB;QAC1B,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE;YAC7D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SACpC;QACD,+EAA+E;QAC/E,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAEjC,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAEO,yBAAyB;QAC7B,IAAI,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAAE;YAC5C,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;SAC9C;QAED,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE;YAChE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;SACpC;QACD,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACO,iBAAiB,CAAC,OAAe,EAAE,KAAW,EAAE,QAAQ,GAAG,IAAI;QACrE,wDAAwD;QACxD,4GAA4G;QAC5G,+FAA+F;QAC/F,aAAa;QACb,IAAI,OAAO,GAAG,cAAc,OAAO,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC3B,OAAO,GAAG,GAAG,OAAO,KAAK,KAAK,EAAE,CAAC;SACpC;QACD,MAAM,QAAQ,GAAG,yBAAyB,CACtC,OAAO,EACP,QAAQ,CACX,CAAC;QAEF,OAAO,QAAQ,CAAC;IACpB,CAAC;;AAzee,uCAAe,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAEnE,mHAAmH;AACnH,oHAAoH;AACpG,6CAAqB,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, BatchManager, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IDocumentDeltaConnection,\n IDocumentDeltaConnectionEvents,\n DriverError,\n} from \"@fluidframework/driver-definitions\";\nimport { createGenericNetworkError } 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 { ChildLogger } from \"@fluidframework/telemetry-utils\";\n\n// Local storage key to disable the BatchManager\nconst batchManagerDisabledKey = \"FluidDisableBatchManager\";\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 protected readonly submitManager: BatchManager<IDocumentMessage[]>;\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 protected readonly logger: ITelemetryLogger;\n protected readonly isBatchManagerDisabled: boolean = false;\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 */\n protected constructor(\n protected readonly socket: SocketIOClient.Socket,\n public documentId: string,\n logger: ITelemetryLogger,\n ) {\n super();\n\n this.logger = ChildLogger.create(logger, \"DeltaConnection\");\n\n this.submitManager = new BatchManager<IDocumentMessage[]>(\n (submitType, work) => this.emitMessages(submitType, work));\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 this.isBatchManagerDisabled = DocumentDeltaConnection.disabledBatchManagerFeatureGate;\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.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 private static get disabledBatchManagerFeatureGate() {\n try {\n return localStorage !== undefined\n && typeof localStorage === \"object\"\n && localStorage.getItem(batchManagerDisabledKey) === \"1\";\n } catch (e) { }\n return false;\n }\n\n protected submitCore(type: string, messages: IDocumentMessage[]) {\n if (this.isBatchManagerDisabled) {\n this.emitMessages(type, [messages]);\n } else {\n this.submitManager.add(type, messages);\n }\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(\"clientClosingConnection\", true /* canRetry */));\n }\n\n // back-compat: became @deprecated in 0.45 / driver-definitions 0.40\n public close() { this.dispose(); }\n\n protected disposeCore(socketProtocolError: boolean, err: DriverError) {\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: DriverError) {\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: DriverError) => {\n this.disposeCore(socketProtocolError, err);\n reject(err);\n };\n\n // Listen for connection issues\n this.addConnectionListener(\"connect_error\", (error) => {\n fail(true, this.createErrorObject(\"connectError\", error));\n });\n\n // Listen for timeouts\n this.addConnectionListener(\"connect_timeout\", () => {\n fail(true, this.createErrorObject(\"connectTimeout\"));\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 \"connectDocumentSuccess\",\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 \"connectDocumentSuccess\",\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(\"connectDocumentError\", 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): DriverError {\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 // - a socketError: add it to the OdspError object for driver to be able to parse it and reason\n // over it.\n let message = `socket.io: ${handler}`;\n if (typeof error === \"string\") {\n message = `${message}: ${error}`;\n }\n const errorObj = createGenericNetworkError(\n message,\n canRetry,\n );\n\n return errorObj;\n }\n}\n"]}
|
package/lib/packageVersion.d.ts
CHANGED
|
@@ -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.
|
|
8
|
+
export declare const pkgVersion = "0.48.0-38142";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/lib/packageVersion.js
CHANGED
|
@@ -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,cAAc,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.
|
|
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,cAAc,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.48.0-38142\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/driver-base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0-38142",
|
|
4
4
|
"description": "Shared driver code for Fluid driver implementations",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": "https://github.com/microsoft/FluidFramework",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
33
33
|
"@fluidframework/common-utils": "^0.32.1",
|
|
34
34
|
"@fluidframework/driver-definitions": "^0.39.6",
|
|
35
|
-
"@fluidframework/driver-utils": "0.
|
|
35
|
+
"@fluidframework/driver-utils": "0.48.0-38142",
|
|
36
36
|
"@fluidframework/protocol-definitions": "^0.1024.0",
|
|
37
|
-
"@fluidframework/telemetry-utils": "0.
|
|
37
|
+
"@fluidframework/telemetry-utils": "0.48.0-38142"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@fluidframework/build-common": "^0.23.0-0",
|
|
@@ -310,7 +310,7 @@ export class DocumentDeltaConnection
|
|
|
310
310
|
public dispose() {
|
|
311
311
|
this.disposeCore(
|
|
312
312
|
false, // socketProtocolError
|
|
313
|
-
createGenericNetworkError("
|
|
313
|
+
createGenericNetworkError("clientClosingConnection", true /* canRetry */));
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
// back-compat: became @deprecated in 0.45 / driver-definitions 0.40
|
|
@@ -358,12 +358,12 @@ export class DocumentDeltaConnection
|
|
|
358
358
|
|
|
359
359
|
// Listen for connection issues
|
|
360
360
|
this.addConnectionListener("connect_error", (error) => {
|
|
361
|
-
fail(true, this.createErrorObject("
|
|
361
|
+
fail(true, this.createErrorObject("connectError", error));
|
|
362
362
|
});
|
|
363
363
|
|
|
364
364
|
// Listen for timeouts
|
|
365
365
|
this.addConnectionListener("connect_timeout", () => {
|
|
366
|
-
fail(true, this.createErrorObject("
|
|
366
|
+
fail(true, this.createErrorObject("connectTimeout"));
|
|
367
367
|
});
|
|
368
368
|
|
|
369
369
|
this.addConnectionListener("connect_document_success", (response: IConnected) => {
|
|
@@ -383,7 +383,7 @@ export class DocumentDeltaConnection
|
|
|
383
383
|
// In this case we will get "read", even if we requested "write"
|
|
384
384
|
if (actualMode !== requestedMode) {
|
|
385
385
|
fail(false, this.createErrorObject(
|
|
386
|
-
"
|
|
386
|
+
"connectDocumentSuccess",
|
|
387
387
|
"Connected in a different mode than was requested",
|
|
388
388
|
false,
|
|
389
389
|
));
|
|
@@ -392,7 +392,7 @@ export class DocumentDeltaConnection
|
|
|
392
392
|
} else {
|
|
393
393
|
if (actualMode === "write") {
|
|
394
394
|
fail(false, this.createErrorObject(
|
|
395
|
-
"
|
|
395
|
+
"connectDocumentSuccess",
|
|
396
396
|
"Connected in write mode without write permissions",
|
|
397
397
|
false,
|
|
398
398
|
));
|
|
@@ -434,14 +434,14 @@ export class DocumentDeltaConnection
|
|
|
434
434
|
|
|
435
435
|
// This is not an socket.io error - it's Fluid protocol error.
|
|
436
436
|
// In this case fail connection and indicate that we were unable to create connection
|
|
437
|
-
fail(false, this.createErrorObject("
|
|
437
|
+
fail(false, this.createErrorObject("connectDocumentError", error));
|
|
438
438
|
}));
|
|
439
439
|
|
|
440
440
|
this.socket.emit("connect_document", connectMessage);
|
|
441
441
|
|
|
442
442
|
// Give extra 2 seconds for handshake on top of socket connection timeout
|
|
443
443
|
this.socketConnectionTimeout = setTimeout(() => {
|
|
444
|
-
fail(false, this.createErrorObject("
|
|
444
|
+
fail(false, this.createErrorObject("orderingServiceHandshakeTimeout"));
|
|
445
445
|
}, timeout + 2000);
|
|
446
446
|
});
|
|
447
447
|
|
package/src/packageVersion.ts
CHANGED