UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

1 lines 27.9 kB
{"version":3,"sources":["../../../packages/core/rpc/rpc-channel.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,OAAO,EACP,kBAAkB,EAClB,gBAAgB,EAEhB,OAAO,EAEP,OAAO,EACV,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,UAAW,SAAQ,OAAO;IAE5B,OAAO,EAAE,OAAO,CAAC;IAGjB,SAAS,EAAE,MAAM,CAAC;IAGzB,OAAO,CAAC,aAAa,CAAgC;IAErD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,gBAAgB,CAAe;IACvC,OAAO,CAAC,cAAc,CAAS;IAE/B;;;;;;OAMG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAY3D;;OAEG;IACH,IAAW,kBAAkB,CAAC,QAAQ,EAAE,kBAAkB,EAEzD;IAED;;;;;OAKG;IACI,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAS3D;;;;;;OAMG;IACI,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC;IAiBxF;;;;;;;;OAQG;IACI,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,CAAC;IAejG;;OAEG;IACI,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,EAAE;IAavD;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACI,KAAK,IAAI,IAAI;IAKpB;;OAEG;IACI,IAAI,IAAI,IAAI;IAInB;;;;;;;;OAQG;IACI,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IA8C5G;;;;;;;OAOG;IACI,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgDxH;;;;;OAKG;IACI,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAUzC;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAIvD;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAUnF;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IA4MhB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAgBhB;;;;;OAKG;IACH,OAAO,CAAC,KAAK;CAehB","file":"rpc-channel.d.ts","sourcesContent":["import { NativeDeferred } from '../data/native-q';\r\nimport { Net } from '../data/net';\r\nimport { LogLevel } from '../diagnostics/log-level';\r\nimport { LogRecord } from '../diagnostics/log-record';\r\nimport { Logging } from '../diagnostics/logging';\r\nimport { Strings } from '../generated/strings';\r\nimport { EnvironmentModule } from '../manifest/environment-modules';\r\nimport {\r\n RpcBase,\r\n RpcInboundHandlers,\r\n RpcMessagePacket,\r\n RpcMessagePacketType,\r\n RpcMode,\r\n RpcOutboundCommands,\r\n RpcType\r\n} from './rpc-base';\r\nimport { RpcOutbound } from './rpc-outbound';\r\nimport { RpcSeek, RpcSeekKey, RpcSeekMode } from './seek/rpc-seek-model';\r\n\r\n/**\r\n * RpcChannel class.\r\n * - Both Shell and Module creates one instance to present itself.\r\n */\r\nexport class RpcChannel extends RpcBase {\r\n // Current Rpc mode.\r\n public rpcMode: RpcMode;\r\n\r\n // Signature of the gateway running instance.\r\n public signature: string;\r\n\r\n // RpcShell/RpcModule collection.\r\n private rpcCollection = new Map<string, RpcBase[]>();\r\n\r\n private sequence = 0;\r\n private deferredQueue = new Map<number, NativeDeferred<any>>();\r\n private global: Window = window;\r\n private inboundHandlers: RpcInboundHandlers;\r\n private listenerFunction: (ev) => void;\r\n private webpackInvalid = false;\r\n\r\n /**\r\n * Initiates a new instance of the RpcChannel class.\r\n *\r\n * @param name the public name of itself.\r\n * @param origin the origin url of itself.\r\n * @param signature the signature of the gateway running instance.\r\n */\r\n constructor(name: string, origin: string, signature: string) {\r\n super(null, name, origin, RpcType.Channel);\r\n this.signature = signature;\r\n if (MsftSme.isShell()) {\r\n this.rpcMode = RpcMode.Shell;\r\n this.depth = 0;\r\n } else {\r\n this.rpcMode = RpcMode.Module;\r\n this.depth = null;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the rpc inbound handlers to use when creating for seek command.\r\n */\r\n public set rpcInboundHandlers(handlers: RpcInboundHandlers) {\r\n this.inboundHandlers = handlers;\r\n }\r\n\r\n /**\r\n * Register Inbound/Outbound.\r\n *\r\n * @param rpcObject the RpcInbound/RpcOutbound class instance.\r\n * @param type the type of rpc object.\r\n */\r\n public registerRpc(rpcObject: RpcBase, type: RpcType): void {\r\n if (rpcObject.type !== type) {\r\n const message = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTypeNoMatch.message;\r\n throw new Error(message.format('registerRpc'));\r\n }\r\n\r\n this.addToCollection(rpcObject);\r\n }\r\n\r\n /**\r\n * Unregister module with subName\r\n *\r\n * @param name the name of module.\r\n * @param subName the subName.\r\n * @return RpcBase the rpc object.\r\n */\r\n public unregisterRpc<T extends RpcBase>(name: string, subName: string, type: RpcType): T {\r\n // unregister it by both origin and name.\r\n const rpcObject = <T>this.getFromCollection(name, subName, true);\r\n if (rpcObject.type !== type) {\r\n const message = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTypeNoMatch.message;\r\n throw new Error(message.format('unregisterRpc'));\r\n }\r\n\r\n if (rpcObject) {\r\n this.removeFromCollection(rpcObject);\r\n return rpcObject;\r\n } else {\r\n const message = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcNotFoundModule.message;\r\n throw new Error(message.format(name, subName));\r\n }\r\n }\r\n\r\n /**\r\n * Get Rpc object by module with subName for Inbound.\r\n *\r\n * @param name the name of module.\r\n * @param subName the subName.\r\n * @param type the type of rpc object.\r\n * @param exact the matching type forced.\r\n * @return RpcBase the rpc object.\r\n */\r\n public getRpc<T extends RpcBase>(name: string, subName: string, type: RpcType, nullOk = false): T {\r\n const rpcObject = <T>this.getFromCollection(name, subName, true);\r\n if (rpcObject && rpcObject.type !== type) {\r\n if (nullOk) {\r\n return null;\r\n }\r\n\r\n const message = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTypeNoMatch.message;\r\n throw new Error(message.format('getRpc'));\r\n }\r\n\r\n // return null if it cannot find.\r\n return rpcObject;\r\n }\r\n\r\n /**\r\n * Get all Rpc objects for the specified type.\r\n */\r\n public getAllRpc<T extends RpcBase>(type: RpcType): T[] {\r\n const results: T[] = [];\r\n this.rpcCollection.forEach((subCollection) => {\r\n subCollection.forEach((rpc) => {\r\n if (rpc.type === type) {\r\n results.push(<T>rpc);\r\n }\r\n });\r\n });\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Get RpcInbound/RpcOutbound object for module name and module sub name.\r\n * If it doesn't configure subName yet, it returns it so the channel set it up.\r\n *\r\n * @param name the module name.\r\n * @param subName the sub name of the iframe object.\r\n * @return RpcBase the matched Rpc object.\r\n */\r\n private getFromCollection(name: string, subName: string, exact: boolean): RpcBase {\r\n const subCollection: RpcBase[] = this.rpcCollection.get(name);\r\n if (subCollection == null) {\r\n return null;\r\n }\r\n\r\n return subCollection.find(value => (!exact && value.subName == null) || value.subName === subName);\r\n }\r\n\r\n private removeFromCollection(rpcObject: RpcBase): RpcBase {\r\n const subCollection: RpcBase[] = this.rpcCollection.get(rpcObject.name);\r\n if (subCollection == null) {\r\n return null;\r\n }\r\n\r\n const results = MsftSme.remove(subCollection, rpcObject);\r\n if (subCollection.length === 0) {\r\n // remove the entry if it's empty.\r\n this.rpcCollection.delete(rpcObject.name);\r\n }\r\n\r\n if (results && results.length === 1) {\r\n return results[0];\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private addToCollection(rpcObject: RpcBase): void {\r\n let subCollection: RpcBase[] = this.rpcCollection.get(rpcObject.name);\r\n if (subCollection == null) {\r\n subCollection = [rpcObject];\r\n this.rpcCollection.set(rpcObject.name, subCollection);\r\n } else {\r\n subCollection.push(rpcObject);\r\n }\r\n }\r\n\r\n /**\r\n * Start the message listener.\r\n */\r\n public start(): void {\r\n this.listenerFunction = (ev) => this.listener(ev);\r\n this.global.addEventListener('message', this.listenerFunction);\r\n }\r\n\r\n /**\r\n * Stop the message listener.\r\n */\r\n public stop(): void {\r\n this.global.removeEventListener('message', this.listenerFunction);\r\n }\r\n\r\n /**\r\n * Post the message with retry delay.\r\n *\r\n * @param target the RpcToModule or RpcToShell object.\r\n * @param message the message packet.\r\n * @param count the retry count.\r\n * @param delay the interval milliseconds.\r\n * @return Promise<T> the promise object.\r\n */\r\n public retryPost<T>(target: RpcBase, message: RpcMessagePacket<T>, count: number, delay: number): Promise<T> {\r\n if (target == null || target.window == null) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTargetWindowNotConfigured.message;\r\n throw new Error(message2);\r\n }\r\n\r\n const deferred = new NativeDeferred<T>();\r\n const lastSequence = this.sequence;\r\n this.deferredQueue[this.sequence] = deferred;\r\n message.srcName = this.name;\r\n message.srcSubName = this.subName;\r\n message.srcDepth = this.depth;\r\n message.destName = target.name;\r\n message.destSubName = target.subName;\r\n message.signature = this.signature;\r\n message.sequence = this.sequence;\r\n message.type = RpcMessagePacketType.Request; // post\r\n this.sequence++;\r\n const header = `Retry ${RpcMessagePacketType[message.type]} \"${message.command}\" to ${message.destName}!${message.destSubName}`;\r\n this.debugLogRpcMessage(message, header);\r\n target.window.postMessage(message, target.origin);\r\n const timer = setInterval(\r\n () => {\r\n if (deferred.isPending) {\r\n if (--count < 0) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcExpiredRetry.message;\r\n clearInterval(timer);\r\n deferred.reject(message2.format(message.command));\r\n if (this.deferredQueue[lastSequence]) {\r\n delete this.deferredQueue[lastSequence];\r\n }\r\n\r\n return;\r\n }\r\n\r\n target.window.postMessage(message, target.origin);\r\n return;\r\n }\r\n\r\n clearInterval(timer);\r\n },\r\n delay);\r\n\r\n return deferred.promise;\r\n }\r\n\r\n /**\r\n * Post the request message.\r\n *\r\n * @param target the RpcToModule or RpcToShell object.\r\n * @param message the message packet.\r\n * @param timeout the timeout. (10 seconds at default)\r\n * @return Promise<TResult> the promise object.\r\n */\r\n public post<TMessage, TResult>(target: RpcBase, message: RpcMessagePacket<TMessage>, timeout?: number): Promise<TResult> {\r\n let ignoreTimeout = false;\r\n if (timeout === -1) {\r\n ignoreTimeout = true;\r\n timeout = null;\r\n }\r\n\r\n timeout = timeout || 10 * 1000; // 10 seconds\r\n if (target == null || target.window == null) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTargetWindowNotConfigured.message;\r\n throw new Error(message2);\r\n }\r\n\r\n const deferred = new NativeDeferred<TResult>();\r\n const lastSequence = this.sequence;\r\n this.deferredQueue[this.sequence] = deferred;\r\n message.srcName = this.name;\r\n message.srcSubName = this.subName;\r\n message.srcDepth = this.depth;\r\n message.destName = target.name;\r\n message.destSubName = target.subName;\r\n message.signature = this.signature;\r\n message.sequence = this.sequence;\r\n message.type = RpcMessagePacketType.Request; // post\r\n this.sequence++;\r\n const header = `${RpcMessagePacketType[message.type]} \"${message.command}\" to ${message.destName}!${message.destSubName}`;\r\n this.debugLogRpcMessage(message, header);\r\n target.window.postMessage(message, target.origin);\r\n setTimeout(\r\n () => {\r\n if (deferred.isPending) {\r\n if (ignoreTimeout) {\r\n deferred.resolve();\r\n } else {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcExpired.message;\r\n deferred.reject(\r\n message2.format(this.name, this.subName, target.name, target.subName, message.command, message.type));\r\n }\r\n }\r\n\r\n if (this.deferredQueue[lastSequence]) {\r\n delete this.deferredQueue[lastSequence];\r\n }\r\n },\r\n timeout);\r\n return deferred.promise;\r\n }\r\n\r\n /**\r\n * Validate the target window if exist by sending null packet.\r\n *\r\n * @param target the target Rpc object.\r\n * @return boolean if false, it remove the target from the list.\r\n */\r\n public validate(target: RpcBase): boolean {\r\n try {\r\n target.window.postMessage({ validate: 'validate' }, target.origin);\r\n return true;\r\n } catch (error) {\r\n this.removeFromCollection(target);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Log the debug message.\r\n * @param message the message object.\r\n * @param header the header string (used for the log group header).\r\n */\r\n protected debugLog(message: any, header?: string): void {\r\n Logging.log({ source: 'rpc', message: message, level: LogLevel.Debug, consoleGroupHeader: header });\r\n }\r\n\r\n /**\r\n * Process and log and rpc message.\r\n * @param message the rpc message packet\r\n * @param header the header string (used for the log group header).\r\n */\r\n protected debugLogRpcMessage(message: RpcMessagePacket<any>, header?: string): void {\r\n const logMessage = { ...message };\r\n if (message.command === RpcOutboundCommands[RpcOutboundCommands.Init]) {\r\n // Why is this hidden?\r\n logMessage.data = '(hidden...)';\r\n }\r\n\r\n this.debugLog(logMessage, header);\r\n }\r\n\r\n /**\r\n * The listen handler.\r\n *\r\n * @param messageEvent the Rpc message event.\r\n */\r\n private listener(messageEvent: MessageEvent): void {\r\n\r\n // ignore any shell hosting messages (don't handle them at all)\r\n if (MsftSme.isShell()) {\r\n const type = MsftSme.getValue<string>(messageEvent, 'data.type');\r\n if (typeof type === 'string' && type.startsWith('msft-sme-shell-host')) {\r\n return;\r\n }\r\n }\r\n\r\n // We are operating as an iframe, any message we get, we should format to the parent to handle\r\n if (MsftSme.isExtension() &&\r\n window &&\r\n window.parent &&\r\n messageEvent.source === window.self &&\r\n messageEvent.data &&\r\n (messageEvent.data.type === 'webpackInvalid' ||\r\n messageEvent.data.type === 'webpackOk')) {\r\n // The rpc channel is an iframe, we need to send a message to the parent for the parent to reload after code change\r\n // window.parent references the parent window, postMessage sends a message to the parent\r\n // the '*' refers to sending the message to any origin, this can introduce potential security\r\n // concerns so we only send messages of type 'webpackInvalid' and 'webpackOk'\r\n window.parent.postMessage(messageEvent.data, '*');\r\n }\r\n\r\n if (\r\n // Extension windows will only trust messages from there parent window\r\n (MsftSme.isExtension() && messageEvent.source !== window.parent)\r\n // Shell window only trusts extension origins on rpc\r\n || (MsftSme.isShell() && !EnvironmentModule.isExtensionOrigin(messageEvent.origin))\r\n ) {\r\n // if we don't trust the origin, then just log a message\r\n this.debugLog('RPC listener received message from untrusted sender: {0}'.format(messageEvent));\r\n return;\r\n }\r\n\r\n if (messageEvent.data && messageEvent.data.type) {\r\n // Watch for webpack reloads coming from the iframe\r\n if (messageEvent.data.type === 'webpackInvalid') {\r\n // Webpack is invalid, 1st message\r\n this.webpackInvalid = true;\r\n } else if (this.webpackInvalid && messageEvent.data.type === 'webpackOk') {\r\n // Webpack is okay, 2nd message, we can reload\r\n this.webpackInvalid = false;\r\n location.reload();\r\n }\r\n }\r\n\r\n // if the message if malformed, ignore it.\r\n if (!messageEvent.data || !messageEvent.data.command) {\r\n // ignore null event.\r\n this.debugLog('RPC listener received malformed message from sender: {0}'.format(messageEvent));\r\n return;\r\n }\r\n\r\n const message = messageEvent.data;\r\n const header = `${RpcMessagePacketType[message.type]} \"${message.command}\" from ${message.srcName}!${message.srcSubName}`;\r\n this.debugLogRpcMessage(message, header);\r\n if (message.signature !== this.signature) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcSignatureError.message;\r\n throw new Error(message2);\r\n }\r\n\r\n // accept shell seek query\r\n if (message.destName !== this.name) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcUnexpectedDestination.message;\r\n throw new Error(message2.format(message.destName));\r\n }\r\n\r\n let target: RpcBase = this.getFromCollection(message.srcName, message.srcSubName, false);\r\n if (!target) {\r\n // unknown request was received.\r\n if (message.type === RpcMessagePacketType.Request\r\n && message.command === RpcOutboundCommands[RpcOutboundCommands.Ping]) {\r\n target = this.getFromCollection('*', '*', true);\r\n if (target) {\r\n // keep remote window object to respond.\r\n // current channel is child, and target is parent.\r\n // target could be shell or a parent module.\r\n // remove the rpcInbound object once and re-register back again with new name.\r\n this.removeFromCollection(target);\r\n target.name = message.srcName;\r\n target.subName = message.srcSubName;\r\n target.window = <Window>messageEvent.source;\r\n target.origin = messageEvent.origin;\r\n target.depth = message.srcDepth;\r\n this.subName = message.destSubName;\r\n this.depth = message.srcDepth + 1;\r\n this.registerRpc(target, RpcType.Inbound);\r\n }\r\n }\r\n }\r\n\r\n // Seek to create or delete RpcInbound on the shell to access a child call.\r\n if (message.command === RpcSeekKey.command\r\n && this.name === EnvironmentModule.nameOfShell\r\n && message.type === RpcMessagePacketType.Request) {\r\n const seekData = <RpcSeek>message.data;\r\n if (seekData.mode === RpcSeekMode.Create) {\r\n if (target) {\r\n // update window object.\r\n target.subName = message.srcSubName;\r\n target.window = <Window>messageEvent.source;\r\n target.depth = message.srcDepth;\r\n } else {\r\n target = new RpcOutbound(this, message.srcName, messageEvent.origin);\r\n target.subName = message.srcSubName;\r\n target.window = <Window>messageEvent.source;\r\n target.depth = message.srcDepth;\r\n (<RpcOutbound>target).registerAll(this.inboundHandlers);\r\n this.registerRpc(target, RpcType.Outbound);\r\n }\r\n } else if (seekData.mode === RpcSeekMode.Delete && target) {\r\n this.removeFromCollection(target);\r\n }\r\n }\r\n\r\n if (!target) {\r\n // ignore older/unknown response packet. current channel no longer watching it for response, but treat new request as an error.\r\n if (message.type === RpcMessagePacketType.Request) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcUnexpectedEvent.message;\r\n throw new Error(message2.format(message.srcName, message.srcSubName));\r\n }\r\n\r\n return;\r\n }\r\n\r\n let deferred: NativeDeferred<any>;\r\n switch (message.type) {\r\n case RpcMessagePacketType.Request: // post: processing response/error.\r\n target.handle(message.command, message.version, message.srcName, message.srcSubName, message.data).then(\r\n (data: any) => {\r\n message.data = data;\r\n return this.response(target, message);\r\n },\r\n error => {\r\n let logMessage = '';\r\n let logStack = '';\r\n if (typeof error === 'string') {\r\n message.data = error;\r\n logMessage = error;\r\n } else {\r\n message.data = {};\r\n if (error && error.xhr) {\r\n const netError = Net.getErrorMessage(error);\r\n message.data.message = netError;\r\n logMessage = netError;\r\n } else if (error.message) {\r\n message.data.message = error.message;\r\n logMessage = error.message;\r\n }\r\n\r\n if (error.stack) {\r\n message.data.stack = error.stack;\r\n logStack = error.stack;\r\n }\r\n }\r\n\r\n Logging.log(<LogRecord>{\r\n source: 'RpcChannel',\r\n level: LogLevel.Error,\r\n message: logMessage,\r\n stack: logStack\r\n });\r\n\r\n // telemetry with predefined view/action name.\r\n Logging.trace({\r\n view: 'sme-generic-error',\r\n instance: 'rpc-channel',\r\n action: 'exceptionLog',\r\n data: { stack: '' }\r\n });\r\n\r\n return this.error(target, message);\r\n });\r\n break;\r\n case RpcMessagePacketType.Response: // response: received result with success.\r\n deferred = this.deferredQueue[message.sequence];\r\n if (!deferred) {\r\n if (message.command === RpcOutboundCommands[RpcOutboundCommands.Ping]) {\r\n // ping can be sent multiple times and deferred could be settled already.\r\n break;\r\n }\r\n\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcUnexpectedSequence.message;\r\n throw new Error(message2);\r\n }\r\n\r\n delete this.deferredQueue[message.sequence];\r\n deferred.resolve(message.data);\r\n break;\r\n case RpcMessagePacketType.Error: // error: received result with error.\r\n deferred = this.deferredQueue[message.sequence];\r\n if (!deferred) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcUnexpectedErrorSequence.message;\r\n throw new Error(message2);\r\n }\r\n\r\n delete this.deferredQueue[message.sequence];\r\n deferred.reject(message.data);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Sending response message.\r\n *\r\n * @param target the RpcToModule or RpcToShell object.\r\n * @param message the Rpc message packet.\r\n */\r\n private response<T>(target: RpcBase, message: RpcMessagePacket<T>): void {\r\n if (target == null || target.window == null) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTargetWindowNotConfigured.message;\r\n throw new Error(message2);\r\n }\r\n\r\n message.srcName = this.name;\r\n message.srcSubName = this.subName;\r\n message.srcDepth = this.depth;\r\n message.destName = target.name;\r\n message.destSubName = target.subName;\r\n message.signature = this.signature;\r\n message.type = RpcMessagePacketType.Response; // response\r\n target.window.postMessage(message, target.origin);\r\n }\r\n\r\n /**\r\n * Sending error message.\r\n *\r\n * @param target the RpcToModule or RpcToShell object.\r\n * @param message the Rpc message packet.\r\n */\r\n private error<T>(target: RpcBase, message: RpcMessagePacket<T>): void {\r\n if (target == null || target.window == null) {\r\n const message2 = MsftSme.getStrings<Strings>().MsftSmeShell.Core.Error.RpcTargetWindowNotConfigured.message;\r\n throw new Error(message2);\r\n }\r\n\r\n message.srcName = this.name;\r\n message.srcSubName = this.subName;\r\n message.srcDepth = this.depth;\r\n message.destName = target.name;\r\n message.destSubName = target.subName;\r\n message.signature = this.signature;\r\n message.type = RpcMessagePacketType.Error; // error\r\n target.window.postMessage(message, target.origin);\r\n }\r\n}\r\n"]}