mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-27 12:51:41 +00:00
* Use Promise for allResourceToken fabric message. Cleanup token message handling and add debounce. * Improve rpc and update initalization flow * Fix format * Rev up message names for new version * Refactor RPC with Fabric * Build fix * Fix build * Fix format * Update Message types * Fix format * Fix comments * Fabric toolbar style and support to show/hide it (#1720) * Add Fabric specific Toolbar design * Add Fabric message to show/hide the Toolbar * Fix CommandBarUtil formatting * Update zustand state on setToolbarStatus to trigger a redraw of the command bar with updated visibility --------- Co-authored-by: Laurent Nguyen <laurent.nguyen@microsoft.com> * Fix format --------- Co-authored-by: Vsevolod Kukol <sevoku@microsoft.com>
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
import Q from "q";
|
|
import * as _ from "underscore";
|
|
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
|
import { getDataExplorerWindow } from "../Utils/WindowUtils";
|
|
import * as Constants from "./Constants";
|
|
|
|
export interface CachedDataPromise<T> {
|
|
deferred: Q.Deferred<T>;
|
|
startTime: Date;
|
|
id: string;
|
|
}
|
|
|
|
export const RequestMap: Record<string, CachedDataPromise<any>> = {};
|
|
|
|
export function handleCachedDataMessage(message: any): void {
|
|
const messageContent = message && message.message;
|
|
if (message == null || messageContent == null || messageContent.id == null || !RequestMap[messageContent.id]) {
|
|
return;
|
|
}
|
|
|
|
const cachedDataPromise = RequestMap[messageContent.id];
|
|
if (messageContent.error != null) {
|
|
cachedDataPromise.deferred.reject(messageContent.error);
|
|
} else {
|
|
cachedDataPromise.deferred.resolve(messageContent.data);
|
|
}
|
|
runGarbageCollector();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param messageType
|
|
* @param params
|
|
* @param scope Use this string to identify request Useful to distinguish response from different senders
|
|
* @param timeoutInMs
|
|
* @returns
|
|
*/
|
|
export function sendCachedDataMessage<TResponseDataModel>(
|
|
messageType: MessageTypes,
|
|
params: Object[],
|
|
scope?: string,
|
|
timeoutInMs?: number,
|
|
): Q.Promise<TResponseDataModel> {
|
|
let cachedDataPromise: CachedDataPromise<TResponseDataModel> = {
|
|
deferred: Q.defer<TResponseDataModel>(),
|
|
startTime: new Date(),
|
|
id: _.uniqueId(scope),
|
|
};
|
|
RequestMap[cachedDataPromise.id] = cachedDataPromise;
|
|
sendMessage({ type: messageType, params: params, id: cachedDataPromise.id });
|
|
|
|
//TODO: Use telemetry to measure optimal time to resolve/reject promises
|
|
return cachedDataPromise.deferred.promise.timeout(
|
|
timeoutInMs || Constants.ClientDefaults.requestTimeoutMs,
|
|
"Timed out while waiting for response from portal",
|
|
);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param data Overwrite the data property of the message
|
|
*/
|
|
export function sendMessage(data: any): void {
|
|
_sendMessage({
|
|
signature: "pcIframe",
|
|
data: data,
|
|
});
|
|
}
|
|
|
|
export function sendReadyMessage(): void {
|
|
_sendMessage({
|
|
signature: "pcIframe",
|
|
kind: "ready",
|
|
data: "ready",
|
|
});
|
|
}
|
|
|
|
export function canSendMessage(): boolean {
|
|
return window.parent !== window;
|
|
}
|
|
|
|
// TODO: This is exported just for testing. It should not be.
|
|
export function runGarbageCollector() {
|
|
Object.keys(RequestMap).forEach((key: string) => {
|
|
const promise: Q.Promise<any> = RequestMap[key].deferred.promise;
|
|
if (promise.isFulfilled() || promise.isRejected()) {
|
|
delete RequestMap[key];
|
|
}
|
|
});
|
|
}
|
|
|
|
const _sendMessage = (message: any): void => {
|
|
if (canSendMessage()) {
|
|
// Portal window can receive messages from only child windows
|
|
const portalChildWindow = getDataExplorerWindow(window) || window;
|
|
if (portalChildWindow === window) {
|
|
// Current window is a child of portal, send message to portal window
|
|
portalChildWindow.parent.postMessage(message, portalChildWindow.document.referrer || "*");
|
|
} else {
|
|
// Current window is not a child of portal, send message to the child window instead (which is data explorer)
|
|
portalChildWindow.postMessage(message, portalChildWindow.location.origin || "*");
|
|
}
|
|
}
|
|
};
|