@microsoft/sp-webpart-base
Version:
SharePoint Framework support for building web parts
132 lines • 6.49 kB
JavaScript
;
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