@atlaskit/node-data-provider
Version:
Node data provider for @atlaskit/editor-core plugins and @atlaskit/renderer
216 lines (213 loc) • 8.12 kB
JavaScript
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import { findNodesToPrefetch } from './find-nodes-to-prefetch';
/**
* Represents the SSR data for a single provider.
* It's a map where each key is a unique node data key and the value is the prefetched data for that node.
*
* @example
* {
* 'node-id-1': { value: 'some data' },
* 'node-id-2': { value: 'other data' }
* }
*/
/**
* Represents the aggregated SSR data for all node data providers.
* Each key is a provider's name, and the value contains the fetch status, duration,
* and a map of node data keys to their prefetched data.
*
* @example
* ```
* {
* mentionProvider: {
* success: true,
* duration: 220,
* data: {
* 'mention-1': { id: '1', name: 'John Doe' }
* }
* },
* emojiProvider: {
* success: true,
* duration: 110,
* data: {
* 'emoji-123': { shortName: ':smile:', representation: '😊' }
* }
* }
* }
* ```
*/
/**
* Fetches data for nodes in the document that are supported by the given providers.
* This function will traverse the document and call the `fetchData` method for each node that is supported by the providers.
*
* @example
* ```
* const doc = JSON.parse('{"type": "doc", "content": [...] }');
* const providers = [
* {
* provider: new EditorCardProvider(),
* maxNodesToPrefetch: 10,
* timeout: 500,
* },
* {
* provider: new EditorMentionsProvider(),
* maxNodesToPrefetch: 50,
* timeout: 500,
* },
* ];
*
* const data = await prefetchNodeDataProvidersData({
* providers,
* doc,
* timeout: 1_000,
* maxNodesToVisit: 2_000
* });
* ```
*
* @param props The properties for prefetching node data.
* @returns Record of provider names to their respective SSR data,
* success status, and duration of the fetch operation.
*/
export function prefetchNodeDataProvidersData(_x) {
return _prefetchNodeDataProvidersData.apply(this, arguments);
}
function _prefetchNodeDataProvidersData() {
_prefetchNodeDataProvidersData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref) {
var providers, doc, timeout, _ref$maxNodesToVisit, maxNodesToVisit, providersWithDefaults, providerTimeouts, nodesWithProviders, promises, results;
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
providers = _ref.providers, doc = _ref.doc, timeout = _ref.timeout, _ref$maxNodesToVisit = _ref.maxNodesToVisit, maxNodesToVisit = _ref$maxNodesToVisit === void 0 ? Infinity : _ref$maxNodesToVisit;
if (!(timeout <= 0)) {
_context2.next = 3;
break;
}
return _context2.abrupt("return", providers.reduce(function (acc, _ref2) {
var provider = _ref2.provider;
acc[provider.name] = {
data: {},
success: false,
duration: 0
};
return acc;
}, {}));
case 3:
providersWithDefaults = providers.map(function (_ref3) {
var provider = _ref3.provider,
_ref3$maxNodesToPrefe = _ref3.maxNodesToPrefetch,
maxNodesToPrefetch = _ref3$maxNodesToPrefe === void 0 ? Infinity : _ref3$maxNodesToPrefe,
_ref3$timeout = _ref3.timeout,
providerTimeout = _ref3$timeout === void 0 ? Infinity : _ref3$timeout;
return {
provider: provider,
maxNodesToPrefetch: maxNodesToPrefetch,
// Use the minimum of the global timeout and the provider-specific timeout
timeout: Math.min(providerTimeout, timeout)
};
});
providerTimeouts = providersWithDefaults.reduce(function (acc, _ref4) {
var provider = _ref4.provider,
timeout = _ref4.timeout;
acc[provider.name] = timeout;
return acc;
}, {});
nodesWithProviders = findNodesToPrefetch(doc, providersWithDefaults, maxNodesToVisit).map(function (_ref5) {
var provider = _ref5.provider,
nodes = _ref5.nodes;
return {
provider: provider,
nodes: nodes,
timeout: providerTimeouts[provider.name]
};
});
promises = nodesWithProviders.map( /*#__PURE__*/function () {
var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref6) {
var nodes, provider, timeout, start, getDurationFromStart, timeoutPromise, data;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
getDurationFromStart = function _getDurationFromStart() {
return Math.min(performance.now() - start, timeout);
};
nodes = _ref6.nodes, provider = _ref6.provider, timeout = _ref6.timeout;
if (!(timeout <= 0)) {
_context.next = 4;
break;
}
return _context.abrupt("return", {
provider: provider,
success: false,
duration: 0,
nodes: nodes,
data: []
});
case 4:
start = performance.now();
_context.prev = 5;
timeoutPromise = new Promise(function (_, reject) {
setTimeout(function () {
reject();
}, timeout);
});
_context.next = 9;
return Promise.race([provider.fetchNodesData(nodes), timeoutPromise]);
case 9:
data = _context.sent;
return _context.abrupt("return", {
provider: provider,
success: true,
duration: getDurationFromStart(),
nodes: nodes,
data: data
});
case 13:
_context.prev = 13;
_context.t0 = _context["catch"](5);
return _context.abrupt("return", {
provider: provider,
success: false,
duration: getDurationFromStart(),
nodes: nodes,
data: []
});
case 16:
case "end":
return _context.stop();
}
}, _callee, null, [[5, 13]]);
}));
return function (_x2) {
return _ref7.apply(this, arguments);
};
}());
_context2.next = 9;
return Promise.all(promises);
case 9:
results = _context2.sent;
return _context2.abrupt("return", results.reduce(function (acc, _ref8) {
var provider = _ref8.provider,
success = _ref8.success,
duration = _ref8.duration,
nodes = _ref8.nodes,
data = _ref8.data;
var ssrData = data.reduce(function (providerSsrData, nodeData, nodeIndex) {
var node = nodes[nodeIndex];
var nodeDataKey = provider.nodeDataKey(node);
providerSsrData[nodeDataKey] = nodeData;
return providerSsrData;
}, {});
acc[provider.name] = {
data: ssrData,
success: success,
duration: duration
};
return acc;
}, {}));
case 11:
case "end":
return _context2.stop();
}
}, _callee2);
}));
return _prefetchNodeDataProvidersData.apply(this, arguments);
}