/*
* 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;
});