UNPKG

@roderickhsiao/react-i13n

Version:

[Experiment] React I13n provides a performant and scalable solution to application instrumentation.

267 lines (222 loc) 9.54 kB
"use strict"; 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;