/* * GNU AGPL-3.0 License * * Copyright (c) 2021 - present core.ai . All rights reserved. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License * for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see https://opensource.org/licenses/AGPL-3.0. * */ /*global Phoenix*/ // @INCLUDE_IN_API_DOCS /** * PhoenixComm APIs can be used to communicate between Phoenix browser tabs/iframe instances across the browser. * * ### Import * ```js * // usage within core: * const PhoenixComm = require("utils/PhoenixComm"); * * // usage within default extensions: * const PhoenixComm = brackets.getModule("utils/PhoenixComm"); * ``` * * @module utils/PhoenixComm */ define(function (require, exports, module) { const EventDispatcher = require("utils/EventDispatcher"); const _phoenixBroadcastChannel = new BroadcastChannel("PhoenixComm"); /** * This section outlines the properties and methods available in this module * @name API */ /** * A unique ID for each phoenix window instance. Test windows also have an id. * @typedef PHOENIX_INSTANCE_ID * @type {String} */ const PHOENIX_INSTANCE_ID = "PH-" + Math.round( Math.random()*1000000000000); Phoenix.PHOENIX_INSTANCE_ID = PHOENIX_INSTANCE_ID; const EVENT_PHOENIX_CLOSING = "phoenixClosing", EVENT_PHOENIX_OPENED = "phoenixOpened", _EVENT_PHOENIX_INSTANCE_DETAILS = "phoenixInstanceDetails"; const _phoenixInstanceDetails = {}; Phoenix.PHOENIX_INSTANCE_DETAILS = _phoenixInstanceDetails; /** * Broadcast a message to other Phoenix instances. To listen to the broadcast message on another phoenix instance, * use PhoenixComm.on methord * @example To broadcast/receive a hello message to everyone * PhoenixComm.broadcast("MSG_TYPE", "hello world", "ms", 200); * // now to receive the message of the type, use the on method * PhoenixComm.on("MSG_TYPE", (evt, data) =>{ * console.log(data); // hello world * }) * * @param {string} eventType The kind of Event Type that needs to be sent to other phoenix instances * @param {Object} data The Data object to broadcast * @type {function} */ function broadcast(eventType, data) { _phoenixBroadcastChannel.postMessage({ eventType, data }); } /** * Returns a map of all instances of Phoenix. Mapped from instanceID to detail {instanceID, isTestWindow}. * Will not contain self instance details. * @return {Object} that maps instance IDs that are currently online to the instance details. */ function getAllInstanceDetails() { return _phoenixInstanceDetails; } function _processBroadcastMessage(event) { if(event.data && event.data.eventType){ exports.trigger(event.data.eventType, event.data.data); return; } console.error("Unknown event type for _phoenixBroadcastChannel message: ", event); } _phoenixBroadcastChannel.onmessage = _processBroadcastMessage; EventDispatcher.makeEventDispatcher(exports); function _getInstanceDetails() { return { instanceID: PHOENIX_INSTANCE_ID, isTestWindow: Phoenix.isTestWindow }; } broadcast(EVENT_PHOENIX_OPENED, _getInstanceDetails()); addEventListener( 'beforeunload', function() { broadcast(EVENT_PHOENIX_CLOSING, PHOENIX_INSTANCE_ID); }); exports.on(EVENT_PHOENIX_CLOSING, (_event, instanceID)=>{ delete _phoenixInstanceDetails[instanceID]; }); exports.on(EVENT_PHOENIX_OPENED, (_event, instanceDetails)=>{ _phoenixInstanceDetails[instanceDetails.instanceID] = instanceDetails; // a new window came up, so we broadcast our instance detail so that everyone(esp. the new window) is updated // of our instance detail. broadcast(_EVENT_PHOENIX_INSTANCE_DETAILS, _getInstanceDetails()); }); exports.on(_EVENT_PHOENIX_INSTANCE_DETAILS, (_event, instanceDetails)=>{ _phoenixInstanceDetails[instanceDetails.instanceID] = instanceDetails; }); // public events /** * This section outlines the standard events generated by PhoenixComm. use * `PhoenixComm.on(PhoenixComm.EVENT_PHOENIX_CLOSING,fn)` to listen to these events. * * * `EVENT_PHOENIX_CLOSING` - Event raised when another phoenix window is closing. Raises `instanceID` * * `EVENT_PHOENIX_OPENED` - Raises `{instanceID, isTestWindow}` when another phoenix window is opened. * @name EVENTS */ exports.EVENT_PHOENIX_CLOSING = EVENT_PHOENIX_CLOSING; exports.EVENT_PHOENIX_OPENED = EVENT_PHOENIX_OPENED; // Define public API // exports.on is injected by eventDispatcher exports.broadcast = broadcast; exports.getAllInstanceDetails = getAllInstanceDetails; exports.PHOENIX_INSTANCE_ID = PHOENIX_INSTANCE_ID; });