UNPKG

@microsoft/sp-webpart-base

Version:

SharePoint Framework support for building web parts

151 lines 8.09 kB
import { __assign } from "tslib"; import { SPComponentLoader } from '@microsoft/sp-loader'; import { DisplayMode } from '@microsoft/sp-core-library'; import { IdleLoadComponentFactory } from './IdleLoadComponentFactory'; // note: in the future this may return a value the web part can reference later like a list of events that were prefetched var DEFAULT_PREFETCH_COUNT = 3; var SUPER_MAX_PREFETCH_COUNT = 20; function getManifest(webPartData) { if (!webPartData || !webPartData.id) { return undefined; } return SPComponentLoader.tryGetManifestById(webPartData.id); } function getIdleLoadComponentsFromManifest(manifest) { var _a; // find it in either the top level or in the experimentalData return (manifest === null || manifest === void 0 ? void 0 : manifest.idleLoadComponents) || ((_a = manifest === null || manifest === void 0 ? void 0 : manifest.experimentalData) === null || _a === void 0 ? void 0 : _a.idleLoadComponents); } function getIdleLoadComponentIdsFromWebPartData(webPartData) { var _a; var manifest = getManifest(webPartData); return (_a = getIdleLoadComponentsFromManifest(manifest)) === null || _a === void 0 ? void 0 : _a.map(function (component) { return component.componentId; }); } function isIdleLoadComponentForDisplayMode(component, displayMode) { if (!component) { return false; } var idleDisplayMode = component.displayMode; if (!idleDisplayMode) { // if the component does not specify a display mode, it is assumed to be supported in all display modes return true; } switch (displayMode) { case DisplayMode.Edit: return idleDisplayMode === 'edit'; case DisplayMode.Read: return idleDisplayMode === 'read'; default: return false; // unsupported display mode } } /** * @internal * Manages the loading idle load components for web parts. * @privateRemarks * Idle load components can be loaded during idle to improve render performance of web parts - or in parallel of loading a web part. */ var WebPartIdleLoad = /** @class */ (function () { function WebPartIdleLoad() { this._prefetchWebParts = new Map(); } /** * Removes the web part from the specified displayMode prefetching queue. * @param instanceId - the instance ID of the web part to remove */ WebPartIdleLoad.prototype.cancelPrefetching = function (instanceId) { var _a; var webPartData = this._prefetchWebParts.get(instanceId); (_a = getIdleLoadComponentIdsFromWebPartData(webPartData)) === null || _a === void 0 ? void 0 : _a.forEach(function (componentId) { IdleLoadComponentFactory.instance.removeComponent(instanceId, componentId); }); this._prefetchWebParts.delete(instanceId); }; WebPartIdleLoad.prototype.cancelAllPrefetching = function () { IdleLoadComponentFactory.instance.reset(); this._prefetchWebParts.clear(); }; /** * Enables prefetching idle load components for the specified web parts. * @param controls - the web parts to prefetch */ WebPartIdleLoad.prototype.enablePrefetching = function (controls) { var _this = this; controls.forEach(function (control) { _this._prefetchWebParts.set(control.instanceId, control); }); }; /** * Prefetches the specified web part's idle load components for the specified display mode. * @param control - the specified web part * @param displayMode - the display mode of the web part to prefetch * @param manifest - the manifest of the web part, if not provided SPComponentLoader.tryGetManifestById will be called * @returns A function that can be called to cancel the prefetching of the web parts. */ WebPartIdleLoad.prototype.prefetchWebPart = function (control, displayMode, manifest) { var idleLoadComponents = getIdleLoadComponentsFromManifest(manifest || getManifest(control)); if (!idleLoadComponents || idleLoadComponents.length === 0) { return function () { }; } var idleLoadComponentsWithRequestorId = new Map(); for (var _i = 0, idleLoadComponents_1 = idleLoadComponents; _i < idleLoadComponents_1.length; _i++) { var component = idleLoadComponents_1[_i]; if (isIdleLoadComponentForDisplayMode(component, displayMode)) { idleLoadComponentsWithRequestorId.set(component.componentId, __assign(__assign({}, component), { requestorIds: [control.instanceId] // add the requestor ID to the component })); } } return IdleLoadComponentFactory.instance.fetchIdleLoadComponents(Array.from(idleLoadComponentsWithRequestorId.values())); }; /** * Prefetches the idle load components for web parts in the specified display mode. Note that enablePrefetching must be called first. * @param displayMode - the display mode of the web part to prefetch * @param limit - the maximum number of web parts to prefetch. * @defaultValue 3 * @returns A function that can be called to cancel the prefetching of the web parts. */ WebPartIdleLoad.prototype.prefetchWebParts = function (displayMode, limit) { if (limit === void 0) { limit = DEFAULT_PREFETCH_COUNT; } // nothing to prefetch if (this._prefetchWebParts.size === 0 || limit <= 0) { return function () { }; } var idleLoadComponentsWithRequestorId = new Map(); var webPartLimit = Math.min(SUPER_MAX_PREFETCH_COUNT, limit); var webPartDatas = Array.from(this._prefetchWebParts.values()); var _loop_1 = function (webPartData) { var idleLoadComponents = getIdleLoadComponentsFromManifest(getManifest(webPartData)); // filter for the specified display mode var idleLoadComponentsForDisplayMode = idleLoadComponents === null || idleLoadComponents === void 0 ? void 0 : idleLoadComponents.filter(function (component) { return isIdleLoadComponentForDisplayMode(component, displayMode); }); // build the map of idle load components with requestor IDs idleLoadComponentsForDisplayMode === null || idleLoadComponentsForDisplayMode === void 0 ? void 0 : idleLoadComponentsForDisplayMode.forEach(function (idleLoadComponent) { var existingComponent = idleLoadComponentsWithRequestorId.get(idleLoadComponent.componentId); if (existingComponent) { // deduplicate requestorIds var currentRequestorIds = new Set(existingComponent.requestorIds); // update the requestorIds currentRequestorIds.add(webPartData.instanceId); existingComponent.requestorIds = Array.from(currentRequestorIds); } else { idleLoadComponentsWithRequestorId.set(idleLoadComponent.componentId, __assign(__assign({}, idleLoadComponent), { requestorIds: [webPartData.instanceId] })); } }); // if the web part limit has been reached after processing this web part, then stop processing further web parts // otherwise if this web part has no idle load components do not update the limit if ((idleLoadComponentsForDisplayMode === null || idleLoadComponentsForDisplayMode === void 0 ? void 0 : idleLoadComponentsForDisplayMode.length) && --webPartLimit <= 0) { return "break"; } }; for (var _i = 0, webPartDatas_1 = webPartDatas; _i < webPartDatas_1.length; _i++) { var webPartData = webPartDatas_1[_i]; var state_1 = _loop_1(webPartData); if (state_1 === "break") break; } return IdleLoadComponentFactory.instance.fetchIdleLoadComponents(Array.from(idleLoadComponentsWithRequestorId.values())); }; return WebPartIdleLoad; }()); export { WebPartIdleLoad }; //# sourceMappingURL=WebPartIdleLoad.js.map