UNPKG

next-utils

Version:

Collection of handy utility functions for working within a Next.js project.

93 lines (73 loc) 3.23 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); function makeDefaultQueryInfo() { return { seen: false, observable: null }; } var RenderPromises = /*#__PURE__*/function () { function RenderPromises() { (0, _defineProperty2["default"])(this, "renderPromises", new Map()); (0, _defineProperty2["default"])(this, "queryInfoTrie", new Map()); } var _proto = RenderPromises.prototype; // Registers the server side rendered observable. _proto.registerSSRObservable = function registerSSRObservable(instance, observable) { this.lookupQueryInfo(instance).observable = observable; } // Get's the cached observable that matches the SSR Query instances query and variables. ; _proto.getSSRObservable = function getSSRObservable(instance) { return this.lookupQueryInfo(instance).observable; }; _proto.addQueryPromise = function addQueryPromise(instance, finish) { var info = this.lookupQueryInfo(instance); if (!info.seen) { this.renderPromises.set(instance, new Promise(function (resolve) { resolve(instance.fetchData()); })); // Render null to abandon this subtree for this rendering, so that we // can wait for the data to arrive. return null; } return finish(); }; _proto.hasPromises = function hasPromises() { return this.renderPromises.size > 0; }; _proto.consumeAndAwaitPromises = function consumeAndAwaitPromises() { var _this = this; var promises = []; this.renderPromises.forEach(function (promise, instance) { // Make sure we never try to call fetchData for this query document and // these variables again. Since the instance objects change with // every rendering, deduplicating them by query and variables is the // best we can do. If a different Query component happens to have the // same query document and variables, it will be immediately rendered // by calling finish() in addQueryPromise, which could result in the // rendering of an unwanted loading state, but that's not nearly as bad // as getting stuck in an infinite rendering loop because we kept calling // instance.fetchData for the same Query component indefinitely. _this.lookupQueryInfo(instance).seen = true; promises.push(promise); }); this.renderPromises.clear(); return Promise.all(promises); }; _proto.lookupQueryInfo = function lookupQueryInfo(instance) { var queryInfoTrie = this.queryInfoTrie; var queryObject = instance.props; var varMap = queryInfoTrie.get(JSON.stringify(queryObject)) || new Map(); if (!queryInfoTrie.has(JSON.stringify(queryObject))) { queryInfoTrie.set(JSON.stringify(queryObject), varMap); } var variablesString = JSON.stringify(queryObject); var info = varMap.get(variablesString) || makeDefaultQueryInfo(); if (!varMap.has(variablesString)) varMap.set(variablesString, info); return info; }; return RenderPromises; }(); exports["default"] = RenderPromises;