Dashboard sipadu mbip
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

react-dom-unstable-flight-server.node.development.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /** @license React v16.12.0
  2. * react-dom-unstable-flight-server.node.development.js
  3. *
  4. * Copyright (c) Facebook, Inc. and its affiliates.
  5. *
  6. * This source code is licensed under the MIT license found in the
  7. * LICENSE file in the root directory of this source tree.
  8. */
  9. 'use strict';
  10. if (process.env.NODE_ENV !== "production") {
  11. (function() {
  12. 'use strict';
  13. var ReactDOMServer = require('react-dom/server');
  14. function scheduleWork(callback) {
  15. setImmediate(callback);
  16. }
  17. function flushBuffered(destination) {
  18. // If we don't have any more data to send right now.
  19. // Flush whatever is in the buffer to the wire.
  20. if (typeof destination.flush === 'function') {
  21. // http.createServer response have flush(), but it has a different meaning and
  22. // is deprecated in favor of flushHeaders(). Detect to avoid a warning.
  23. if (typeof destination.flushHeaders !== 'function') {
  24. // By convention the Zlib streams provide a flush function for this purpose.
  25. destination.flush();
  26. }
  27. }
  28. }
  29. function beginWriting(destination) {
  30. // Older Node streams like http.createServer don't have this.
  31. if (typeof destination.cork === 'function') {
  32. destination.cork();
  33. }
  34. }
  35. function writeChunk(destination, buffer) {
  36. var nodeBuffer = buffer; // close enough
  37. return destination.write(nodeBuffer);
  38. }
  39. function completeWriting(destination) {
  40. // Older Node streams like http.createServer don't have this.
  41. if (typeof destination.uncork === 'function') {
  42. destination.uncork();
  43. }
  44. }
  45. function close(destination) {
  46. destination.end();
  47. }
  48. function convertStringToBuffer(content) {
  49. return Buffer.from(content, 'utf8');
  50. }
  51. function renderHostChildrenToString(children) {
  52. // TODO: This file is used to actually implement a server renderer
  53. // so we can't actually reference the renderer here. Instead, we
  54. // should replace this method with a reference to Fizz which
  55. // then uses this file to implement the server renderer.
  56. return ReactDOMServer.renderToStaticMarkup(children);
  57. }
  58. // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
  59. // nor polyfill, then a plain number is used for performance.
  60. var hasSymbol = typeof Symbol === 'function' && Symbol.for;
  61. var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
  62. // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
  63. // (unstable) APIs that have been removed. Can we remove the symbols?
  64. /*
  65. FLIGHT PROTOCOL GRAMMAR
  66. Response
  67. - JSONData RowSequence
  68. - JSONData
  69. RowSequence
  70. - Row RowSequence
  71. - Row
  72. Row
  73. - "J" RowID JSONData
  74. - "H" RowID HTMLData
  75. - "B" RowID BlobData
  76. - "U" RowID URLData
  77. - "E" RowID ErrorData
  78. RowID
  79. - HexDigits ":"
  80. HexDigits
  81. - HexDigit HexDigits
  82. - HexDigit
  83. HexDigit
  84. - 0-F
  85. URLData
  86. - (UTF8 encoded URL) "\n"
  87. ErrorData
  88. - (UTF8 encoded JSON: {message: "...", stack: "..."}) "\n"
  89. JSONData
  90. - (UTF8 encoded JSON) "\n"
  91. - String values that begin with $ are escaped with a "$" prefix.
  92. - References to other rows are encoding as JSONReference strings.
  93. JSONReference
  94. - "$" HexDigits
  95. HTMLData
  96. - ByteSize (UTF8 encoded HTML)
  97. BlobData
  98. - ByteSize (Binary Data)
  99. ByteSize
  100. - (unsigned 32-bit integer)
  101. */
  102. // TODO: Implement HTMLData, BlobData and URLData.
  103. var stringify = JSON.stringify;
  104. function createRequest(model, destination) {
  105. var pingedSegments = [];
  106. var request = {
  107. destination: destination,
  108. nextChunkId: 0,
  109. pendingChunks: 0,
  110. pingedSegments: pingedSegments,
  111. completedJSONChunks: [],
  112. completedErrorChunks: [],
  113. flowing: false,
  114. toJSON: function (key, value) {
  115. return resolveModelToJSON(request, value);
  116. }
  117. };
  118. request.pendingChunks++;
  119. var rootSegment = createSegment(request, model);
  120. pingedSegments.push(rootSegment);
  121. return request;
  122. }
  123. function attemptResolveModelComponent(element) {
  124. var type = element.type;
  125. var props = element.props;
  126. if (typeof type === 'function') {
  127. // This is a nested view model.
  128. return type(props);
  129. } else if (typeof type === 'string') {
  130. // This is a host element. E.g. HTML.
  131. return renderHostChildrenToString(element);
  132. } else {
  133. throw new Error('Unsupported type.');
  134. }
  135. }
  136. function pingSegment(request, segment) {
  137. var pingedSegments = request.pingedSegments;
  138. pingedSegments.push(segment);
  139. if (pingedSegments.length === 1) {
  140. scheduleWork(function () {
  141. return performWork(request);
  142. });
  143. }
  144. }
  145. function createSegment(request, model) {
  146. var id = request.nextChunkId++;
  147. var segment = {
  148. id: id,
  149. model: model,
  150. ping: function () {
  151. return pingSegment(request, segment);
  152. }
  153. };
  154. return segment;
  155. }
  156. function serializeIDRef(id) {
  157. return '$' + id.toString(16);
  158. }
  159. function serializeRowHeader(tag, id) {
  160. return tag + id.toString(16) + ':';
  161. }
  162. function escapeStringValue(value) {
  163. if (value[0] === '$') {
  164. // We need to escape $ prefixed strings since we use that to encode
  165. // references to IDs.
  166. return '$' + value;
  167. } else {
  168. return value;
  169. }
  170. }
  171. function resolveModelToJSON(request, value) {
  172. if (typeof value === 'string') {
  173. return escapeStringValue(value);
  174. }
  175. while (typeof value === 'object' && value !== null && value.$$typeof === REACT_ELEMENT_TYPE) {
  176. var element = value;
  177. try {
  178. value = attemptResolveModelComponent(element);
  179. } catch (x) {
  180. if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
  181. // Something suspended, we'll need to create a new segment and resolve it later.
  182. request.pendingChunks++;
  183. var newSegment = createSegment(request, element);
  184. var ping = newSegment.ping;
  185. x.then(ping, ping);
  186. return serializeIDRef(newSegment.id);
  187. } else {
  188. request.pendingChunks++;
  189. var errorId = request.nextChunkId++;
  190. emitErrorChunk(request, errorId, x);
  191. return serializeIDRef(errorId);
  192. }
  193. }
  194. }
  195. return value;
  196. }
  197. function emitErrorChunk(request, id, error) {
  198. // TODO: We should not leak error messages to the client in prod.
  199. // Give this an error code instead and log on the server.
  200. // We can serialize the error in DEV as a convenience.
  201. var message;
  202. var stack = '';
  203. try {
  204. if (error instanceof Error) {
  205. message = '' + error.message;
  206. stack = '' + error.stack;
  207. } else {
  208. message = 'Error: ' + error;
  209. }
  210. } catch (x) {
  211. message = 'An error occurred but serializing the error message failed.';
  212. }
  213. var errorInfo = {
  214. message: message,
  215. stack: stack
  216. };
  217. var row = serializeRowHeader('E', id) + stringify(errorInfo) + '\n';
  218. request.completedErrorChunks.push(convertStringToBuffer(row));
  219. }
  220. function retrySegment(request, segment) {
  221. var value = segment.model;
  222. try {
  223. while (typeof value === 'object' && value !== null && value.$$typeof === REACT_ELEMENT_TYPE) {
  224. // If this is a nested model, there's no need to create another chunk,
  225. // we can reuse the existing one and try again.
  226. var element = value;
  227. segment.model = element;
  228. value = attemptResolveModelComponent(element);
  229. }
  230. var json = stringify(value, request.toJSON);
  231. var row;
  232. var id = segment.id;
  233. if (id === 0) {
  234. row = json + '\n';
  235. } else {
  236. row = serializeRowHeader('J', id) + json + '\n';
  237. }
  238. request.completedJSONChunks.push(convertStringToBuffer(row));
  239. } catch (x) {
  240. if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
  241. // Something suspended again, let's pick it back up later.
  242. var ping = segment.ping;
  243. x.then(ping, ping);
  244. return;
  245. } else {
  246. // This errored, we need to serialize this error to the
  247. emitErrorChunk(request, segment.id, x);
  248. }
  249. }
  250. }
  251. function performWork(request) {
  252. var pingedSegments = request.pingedSegments;
  253. request.pingedSegments = [];
  254. for (var i = 0; i < pingedSegments.length; i++) {
  255. var segment = pingedSegments[i];
  256. retrySegment(request, segment);
  257. }
  258. if (request.flowing) {
  259. flushCompletedChunks(request);
  260. }
  261. }
  262. var reentrant = false;
  263. function flushCompletedChunks(request) {
  264. if (reentrant) {
  265. return;
  266. }
  267. reentrant = true;
  268. var destination = request.destination;
  269. beginWriting(destination);
  270. try {
  271. var jsonChunks = request.completedJSONChunks;
  272. var i = 0;
  273. for (; i < jsonChunks.length; i++) {
  274. request.pendingChunks--;
  275. var chunk = jsonChunks[i];
  276. if (!writeChunk(destination, chunk)) {
  277. request.flowing = false;
  278. i++;
  279. break;
  280. }
  281. }
  282. jsonChunks.splice(0, i);
  283. var errorChunks = request.completedErrorChunks;
  284. i = 0;
  285. for (; i < errorChunks.length; i++) {
  286. request.pendingChunks--;
  287. var _chunk = errorChunks[i];
  288. if (!writeChunk(destination, _chunk)) {
  289. request.flowing = false;
  290. i++;
  291. break;
  292. }
  293. }
  294. errorChunks.splice(0, i);
  295. } finally {
  296. reentrant = false;
  297. completeWriting(destination);
  298. }
  299. flushBuffered(destination);
  300. if (request.pendingChunks === 0) {
  301. // We're done.
  302. close(destination);
  303. }
  304. }
  305. function startWork(request) {
  306. request.flowing = true;
  307. scheduleWork(function () {
  308. return performWork(request);
  309. });
  310. }
  311. function startFlowing(request) {
  312. request.flowing = true;
  313. flushCompletedChunks(request);
  314. }
  315. // This file intentionally does *not* have the Flow annotation.
  316. // Don't add it. See `./inline-typed.js` for an explanation.
  317. function createDrainHandler(destination, request) {
  318. return function () {
  319. return startFlowing(request);
  320. };
  321. }
  322. function pipeToNodeWritable(model, destination) {
  323. var request = createRequest(model, destination);
  324. destination.on('drain', createDrainHandler(destination, request));
  325. startWork(request);
  326. }
  327. var ReactFlightDOMServerNode = {
  328. pipeToNodeWritable: pipeToNodeWritable
  329. };
  330. var ReactFlightDOMServerNode$1 = Object.freeze({
  331. default: ReactFlightDOMServerNode
  332. });
  333. var ReactFlightDOMServerNode$2 = ( ReactFlightDOMServerNode$1 && ReactFlightDOMServerNode ) || ReactFlightDOMServerNode$1;
  334. // TODO: decide on the top-level export form.
  335. // This is hacky but makes it work with both Rollup and Jest
  336. var unstableFlightServer_node = ReactFlightDOMServerNode$2.default || ReactFlightDOMServerNode$2;
  337. module.exports = unstableFlightServer_node;
  338. })();
  339. }