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