UNPKG

@atlaskit/node-data-provider

Version:

Node data provider for @atlaskit/editor-core plugins and @atlaskit/renderer

216 lines (213 loc) 8.12 kB
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); }