UNPKG

@microsoft/sp-webpart-base

Version:

SharePoint Framework support for building web parts

132 lines 6.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IdleLoadComponentFactory = void 0; var sp_idle_web_task_1 = require("@msinternal/sp-idle-web-task"); var sp_idle_web_task_2 = require("@msinternal/sp-idle-web-task"); var sp_loader_1 = require("@microsoft/sp-loader"); var ID = 'IdleLoadComponentFactory'; /** * @internal * A factory that manages the loading of idle load components. * It allows components to be loaded when the browser is idle or immediately. */ var IdleLoadComponentFactory = /** @class */ (function () { function IdleLoadComponentFactory() { this._removedComponentIds = new Map(); this._cancelCallbacks = new Set(); } Object.defineProperty(IdleLoadComponentFactory, "instance", { get: function () { if (!IdleLoadComponentFactory._instance) { IdleLoadComponentFactory._instance = new IdleLoadComponentFactory(); } return IdleLoadComponentFactory._instance; }, enumerable: false, configurable: true }); /** * Resets the idle load component factory, clearing all queued requests. */ IdleLoadComponentFactory.prototype.reset = function () { this._cancelCallbacks.forEach(function (callback) { return callback(); }); this._cancelCallbacks.clear(); this._removedComponentIds.clear(); }; /** * Removes the component from the idle load component factory. * @param requestorId - the ID of the requestor that requested this component * @param componentId - the ID of the component to remove */ IdleLoadComponentFactory.prototype.removeComponent = function (requestorId, componentId) { var requestorIds = this._removedComponentIds.get(componentId); if (!requestorIds) { this._removedComponentIds.set(componentId, new Set([requestorId])); } else { requestorIds.add(requestorId); } }; /** * Fetches the idle load components when the browser is idle. * @param components - the idle load components to fetch when the browser is idle * @returns A function that can be called to cancel the idle load component fetching. */ IdleLoadComponentFactory.prototype.fetchIdleLoadComponentsWhenIdle = function (components) { var _this = this; if (components.length === 0) { return function () { }; } var idleTaskId = "".concat(ID, "-").concat(Math.random()); var prefetchDependencyQueue; sp_idle_web_task_2.IdleTaskQueue.instance.enqueueTask({ id: idleTaskId, priority: sp_idle_web_task_2.IdleTaskPriority.OPTIONAL_HIGH, optOutOfAnimationFrames: true, task: function () { prefetchDependencyQueue = _this._convertIdleLoadComponentsToPrefectchDependencyQueue(components); prefetchDependencyQueue.prefetchByPriorityWhenIdle(); } }); return this._addCancelCallback(function () { sp_idle_web_task_2.IdleTaskQueue.instance.removeTask(idleTaskId); prefetchDependencyQueue === null || prefetchDependencyQueue === void 0 ? void 0 : prefetchDependencyQueue.cancelPrefetching(); }); }; /** * Fetches the idle load components without waiting for the browser is idle. * @param components - the idle load components to fetch when the browser is idle * @returns A function that can be called to cancel the idle load component fetching. */ IdleLoadComponentFactory.prototype.fetchIdleLoadComponents = function (components) { var _this = this; if (components.length === 0) { return function () { }; } var animationFrameId = window.requestAnimationFrame(function () { var prefetchDependencyQueue = _this._convertIdleLoadComponentsToPrefectchDependencyQueue(components); prefetchDependencyQueue.prefetchByPriority(); }); return this._addCancelCallback(function () { window.cancelAnimationFrame(animationFrameId); }); }; IdleLoadComponentFactory.prototype._isComponentRemoved = function (requestorIds, componentId) { // if all the requestors are removed, we should not load the component. if (!this._removedComponentIds.has(componentId)) { return false; } var removedRequestorIds = this._removedComponentIds.get(componentId); return !!removedRequestorIds && requestorIds.every(function (id) { return removedRequestorIds.has(id); }); }; IdleLoadComponentFactory.prototype._addCancelCallback = function (callback) { this._cancelCallbacks.add(callback); return callback; }; IdleLoadComponentFactory.prototype._convertIdleLoadComponentsToPrefectchDependencyQueue = function (idleLoadComponents) { var _this = this; var idleLoadPrefetchDependencies = idleLoadComponents.reduce(function (map, _a) { var componentId = _a.componentId, priority = _a.priority, requestorIds = _a.requestorIds; if (!_this._isComponentRemoved(requestorIds, componentId)) { map[componentId] = { // createPrefetchDependencyQueue won't request this component again if it has already been requested urlOrChunkName: componentId, priority: priority === 'high' ? sp_idle_web_task_1.PrefetchDependencyPriority.high : sp_idle_web_task_1.PrefetchDependencyPriority.low, prefetch: function () { if (_this._isComponentRemoved(requestorIds, componentId)) { return Promise.resolve(); } // we are doing nothing with the import. In the future this would update to support passing in // the web part data to the component so stateful prefetching can occur (eg: prefetching image, or events) return sp_loader_1.SPComponentLoader.loadComponentById(componentId); } }; } return map; }, {}); return (0, sp_idle_web_task_2.createPrefetchDependencyQueue)(ID, idleLoadPrefetchDependencies); }; return IdleLoadComponentFactory; }()); exports.IdleLoadComponentFactory = IdleLoadComponentFactory; //# sourceMappingURL=IdleLoadComponentFactory.js.map