@roderickhsiao/react-i13n
Version:
[Experiment] React I13n provides a performant and scalable solution to application instrumentation.
267 lines (222 loc) • 9.54 kB
JavaScript
;
exports.__esModule = true;
exports["default"] = exports.getInstance = void 0;
var _variables = require("../utils/variables");
var _EventsQueue = _interopRequireDefault(require("../libs/EventsQueue"));
var _I13nNode = _interopRequireDefault(require("./I13nNode"));
var _warnAndPrintTrace = _interopRequireDefault(require("../utils/warnAndPrintTrace"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var debugLib = require('debug');
var debug = debugLib('ReactI13n');
var DEFAULT_HANDLER_TIMEOUT = 1000; // export the debug lib in client side
if (_variables.IS_CLIENT) {
window.debugLib = debugLib;
}
var _reactI13nInstance = null;
/**
* ReactI13n Library to build a tree for instrumentation
* @class ReactI13n
* @param {Object} options options object
* @param {Boolean} options.isViewportEnabled if enable viewport checking
* @param {Object} options.rootModelData model data of root i13n node
* @param {Object} options.i13nNodeClass the i13nNode class, you can inherit it with your own functionalities
* @param {String} options.scrollableContainerId id of the scrollable element that your components
* reside within. Normally, you won't need to provide a value for this. This is only to
* support viewport checking when your components are contained within a scrollable element.
* Currently, only elements that fill the viewport are supported.
* @constructor
*/
var ReactI13n = /*#__PURE__*/function () {
function ReactI13n(options) {
var _this = this;
if (options === void 0) {
options = {};
}
_defineProperty(this, "execute", function (eventName, payload, callback) {
payload = Object.assign({}, payload);
payload.env = _variables.ENVIRONMENT;
payload.i13nNode = payload.i13nNode || _this.getRootI13nNode();
var promiseHandlers = _this.getEventHandlers(eventName, payload);
if (promiseHandlers && promiseHandlers.length > 0) {
var handlerTimeout;
promiseHandlers.push(new Promise(function (resolve) {
handlerTimeout = setTimeout(function () {
debug("handler timeout in " + _this._handlerTimeout + "ms.");
resolve();
}, _this._handlerTimeout);
})); // promised execute all handlers if plugins and then call callback function
Promise.race(promiseHandlers).then(function () {
clearTimeout(handlerTimeout);
callback === null || callback === void 0 ? void 0 : callback();
}, function (e) {
clearTimeout(handlerTimeout);
debug('execute event failed', e);
callback === null || callback === void 0 ? void 0 : callback();
});
} else {
// if there's no handlers, execute callback directly
callback === null || callback === void 0 ? void 0 : callback();
}
});
_defineProperty(this, "getEventHandlers", function (eventName, payload) {
var promiseHandlers = [];
if (_this._plugins) {
Object.entries(_this._plugins).forEach(function (_ref) {
var pluginName = _ref[0],
plugin = _ref[1];
var eventsQueue = _this._eventsQueues[pluginName];
var eventHandler = plugin && plugin.eventHandlers && plugin.eventHandlers[eventName];
if (eventHandler) {
promiseHandlers.push(new Promise(function (resolve, reject) {
var _eventsQueue$executeE;
(_eventsQueue$executeE = eventsQueue.executeEvent) === null || _eventsQueue$executeE === void 0 ? void 0 : _eventsQueue$executeE.call(eventsQueue, eventName, payload, resolve, reject);
}));
}
});
}
return promiseHandlers;
});
debug('init', options);
this._eventsQueues = {};
this._plugins = {};
this._rootModelData = options.rootModelData || {};
this._handlerTimeout = options.handlerTimeout || DEFAULT_HANDLER_TIMEOUT;
this._i13nNodeClass = typeof options.i13nNodeClass === 'function' ? options.i13nNodeClass : _I13nNode["default"];
this._isViewportEnabled = options.isViewportEnabled || false;
this._scrollableContainerId = options.scrollableContainerId;
this._i13nInstance = null;
}
var _proto = ReactI13n.prototype;
/**
* Create root node and set to the global object
* @method createRootI13nNode
*/
_proto.createRootI13nNode = function createRootI13nNode() {
var I13nNodeClass = this.getI13nNodeClass();
this._rootI13nNode = new I13nNodeClass(null, this._rootModelData, false);
if (_variables.IS_CLIENT) {
this._rootI13nNode.setDOMNode(document.body);
}
return this._rootI13nNode;
}
/**
* Execute handlers asynchronously
* @method execute
* @param {String} eventName
* @param {Object} payload payload object
* @param {Function} callback callback function when all handlers are executed
* @async
*/
;
/**
* Setup plugins
* @method plug
* @param {Object} plugin the plugin object
*/
_proto.plug = function plug(plugin) {
if (!plugin) {
return;
}
debug('setup plugin', plugin);
this._plugins[plugin.name] = plugin;
this._eventsQueues[plugin.name] = new _EventsQueue["default"](plugin);
}
/**
* Get handlers from all plugin by event name
* @method getEventHandlers
* @param {String} eventName event name
* @param {Object} payload payload object
* @return {Array} the promise handlers
*/
;
/**
* Get I13n node class
* @method getI13nNodeClass
* @return {Object} I13nNode class
*/
_proto.getI13nNodeClass = function getI13nNodeClass() {
return this._i13nNodeClass;
}
/**
* Get isViewportEnabled value
* @method isViewportEnabled
* @return {Object} isViewportEnabled value
*/
;
_proto.isViewportEnabled = function isViewportEnabled() {
return this._isViewportEnabled;
}
/**
* Get scrollableContainerId value
* @method getScrollableContainerId
* @return {String} scrollableContainerId value
*/
;
_proto.getScrollableContainerId = function getScrollableContainerId() {
return this._scrollableContainerId;
}
/**
* Get scrollable container DOM node
* @method getScrollableContainerDOMNode
* @return {Object} scrollable container DOM node. This will be undefined if no
* scrollableContainerId was set, or null if the element was not found in the DOM.
*/
;
_proto.getScrollableContainerDOMNode = function getScrollableContainerDOMNode() {
if (this._scrollableContainerId) {
var _document;
return (_document = document) === null || _document === void 0 ? void 0 : _document.getElementById(this._scrollableContainerId);
}
}
/**
* Get root i13n node
* @method getRootI13nNode
* @return {Object} root react i13n node
*/
;
_proto.getRootI13nNode = function getRootI13nNode() {
return this._rootI13nNode;
}
/**
* Update ReactI13n options
* @method updateOptions
* @param {Object} options
*/
;
_proto.updateOptions = function updateOptions(options) {
var _options$isViewportEn, _options$rootModelDat, _options$handlerTimeo, _options$scrollableCo;
if (options === void 0) {
options = {};
}
debug('updated', options);
this._i13nNodeClass = typeof options.i13nNodeClass === 'function' ? options.i13nNodeClass : this._i13nNodeClass;
this._isViewportEnabled = (_options$isViewportEn = options.isViewportEnabled) !== null && _options$isViewportEn !== void 0 ? _options$isViewportEn : this._isViewportEnabled;
this._rootModelData = (_options$rootModelDat = options.rootModelData) !== null && _options$rootModelDat !== void 0 ? _options$rootModelDat : this._rootModelData;
this._handlerTimeout = (_options$handlerTimeo = options.handlerTimeout) !== null && _options$handlerTimeo !== void 0 ? _options$handlerTimeo : this._handlerTimeout;
this._scrollableContainerId = (_options$scrollableCo = options.scrollableContainerId) !== null && _options$scrollableCo !== void 0 ? _options$scrollableCo : this._scrollableContainerId;
};
_createClass(ReactI13n, [{
key: "i13nInstance",
get: function get() {
return this._i13nInstance;
},
set: function set(instance) {
_reactI13nInstance = instance;
this._i13nInstance = instance;
}
}]);
return ReactI13n;
}();
var getInstance = function getInstance() {
if (_variables.IS_CLIENT) {
return _reactI13nInstance;
}
(0, _warnAndPrintTrace["default"])('ReactI13n instance is not avaialble on server side with getInstance, ' + 'please use this.props.i13n or React context to access ReactI13n utils');
return null;
};
exports.getInstance = getInstance;
var _default = ReactI13n;
exports["default"] = _default;