@shopify/hydrogen 1.2.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +1 -1
  2. package/dist/esnext/components/CartProvider/CartProvider.client.js +6 -0
  3. package/dist/esnext/components/CartProvider/cart-queries.d.ts +1 -1
  4. package/dist/esnext/components/CartProvider/cart-queries.js +1 -0
  5. package/dist/esnext/components/ExternalVideo/ExternalVideo.js +2 -2
  6. package/dist/esnext/components/Image/Image.d.ts +1 -1
  7. package/dist/esnext/components/Image/Image.js +4 -4
  8. package/dist/esnext/components/Image/index.d.ts +1 -1
  9. package/dist/esnext/components/index.d.ts +1 -1
  10. package/dist/esnext/components/index.js +1 -1
  11. package/dist/esnext/constants.d.ts +1 -0
  12. package/dist/esnext/constants.js +1 -0
  13. package/dist/esnext/entry-client.js +1 -1
  14. package/dist/esnext/entry-server.js +30 -28
  15. package/dist/esnext/experimental.d.ts +1 -0
  16. package/dist/esnext/experimental.js +1 -0
  17. package/dist/esnext/foundation/Cache/cache.js +0 -1
  18. package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.d.ts +1 -0
  19. package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.js +1 -0
  20. package/dist/esnext/foundation/HydrogenResponse/HydrogenResponse.server.d.ts +4 -2
  21. package/dist/esnext/foundation/HydrogenResponse/HydrogenResponse.server.js +17 -16
  22. package/dist/esnext/foundation/ServerPropsProvider/ServerPropsProvider.js +1 -3
  23. package/dist/esnext/foundation/fetchSync/ResponseSync.d.ts +2 -1
  24. package/dist/esnext/foundation/fetchSync/ResponseSync.js +14 -2
  25. package/dist/esnext/foundation/session/session-types.d.ts +2 -0
  26. package/dist/esnext/foundation/session/session.d.ts +3 -0
  27. package/dist/esnext/foundation/session/session.js +16 -0
  28. package/dist/esnext/foundation/useQuery/hooks.d.ts +3 -0
  29. package/dist/esnext/foundation/useQuery/hooks.js +1 -1
  30. package/dist/esnext/foundation/useSession/useSession.d.ts +1 -0
  31. package/dist/esnext/foundation/useSession/useSession.js +13 -0
  32. package/dist/esnext/framework/plugin.js +6 -5
  33. package/dist/esnext/framework/plugins/vite-plugin-assets-version.d.ts +2 -0
  34. package/dist/esnext/framework/plugins/vite-plugin-assets-version.js +12 -0
  35. package/dist/esnext/framework/plugins/vite-plugin-client-imports.js +6 -3
  36. package/dist/esnext/framework/plugins/vite-plugin-css-modules-rsc.js +3 -0
  37. package/dist/esnext/framework/plugins/vite-plugin-css-rsc.js +8 -5
  38. package/dist/esnext/framework/plugins/vite-plugin-hydration-auto-import.js +7 -1
  39. package/dist/{node/framework/plugins/vite-plugin-purge-query-cache.d.ts → esnext/framework/plugins/vite-plugin-hydrogen-client-components-cache.d.ts} +1 -1
  40. package/dist/esnext/framework/plugins/{vite-plugin-hydrogen-client-middleware.js → vite-plugin-hydrogen-client-components-cache.js} +2 -2
  41. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.d.ts +2 -1
  42. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.js +104 -90
  43. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.js +6 -6
  44. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-suppress-warnings.js +5 -0
  45. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-virtual-files.js +45 -7
  46. package/dist/esnext/framework/plugins/vite-plugin-platform-entry.js +14 -1
  47. package/dist/esnext/framework/plugins/vite-plugin-ssr-interop.js +5 -1
  48. package/dist/esnext/framework/types.d.ts +1 -0
  49. package/dist/esnext/framework/viteception.js +7 -1
  50. package/dist/esnext/storefront-api-types.d.ts +38 -31
  51. package/dist/esnext/storefront-api-types.js +4 -2
  52. package/dist/esnext/types.d.ts +2 -1
  53. package/dist/esnext/utilities/apiRoutes.d.ts +2 -0
  54. package/dist/esnext/utilities/apiRoutes.js +12 -1
  55. package/dist/esnext/utilities/fetch.js +4 -1
  56. package/dist/esnext/utilities/log/log.js +20 -5
  57. package/dist/esnext/utilities/log/utils.js +1 -1
  58. package/dist/esnext/utilities/template.d.ts +7 -6
  59. package/dist/esnext/utilities/template.js +39 -1
  60. package/dist/esnext/utilities/vite.d.ts +1 -0
  61. package/dist/esnext/utilities/vite.js +4 -0
  62. package/dist/esnext/version.d.ts +1 -1
  63. package/dist/esnext/version.js +1 -1
  64. package/dist/node/foundation/session/session-types.d.ts +2 -0
  65. package/dist/node/framework/plugin.js +6 -5
  66. package/dist/node/framework/plugins/vite-plugin-assets-version.d.ts +2 -0
  67. package/dist/node/framework/plugins/vite-plugin-assets-version.js +15 -0
  68. package/dist/node/framework/plugins/vite-plugin-client-imports.js +6 -3
  69. package/dist/node/framework/plugins/vite-plugin-css-modules-rsc.js +3 -0
  70. package/dist/node/framework/plugins/vite-plugin-css-rsc.js +8 -5
  71. package/dist/node/framework/plugins/vite-plugin-hydration-auto-import.js +7 -1
  72. package/dist/{esnext/framework/plugins/vite-plugin-purge-query-cache.d.ts → node/framework/plugins/vite-plugin-hydrogen-client-components-cache.d.ts} +1 -1
  73. package/dist/node/framework/plugins/{vite-plugin-hydrogen-client-middleware.js → vite-plugin-hydrogen-client-components-cache.js} +2 -2
  74. package/dist/node/framework/plugins/vite-plugin-hydrogen-config.d.ts +2 -1
  75. package/dist/node/framework/plugins/vite-plugin-hydrogen-config.js +107 -90
  76. package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.js +6 -6
  77. package/dist/node/framework/plugins/vite-plugin-hydrogen-suppress-warnings.js +5 -0
  78. package/dist/node/framework/plugins/vite-plugin-hydrogen-virtual-files.js +45 -7
  79. package/dist/node/framework/plugins/vite-plugin-platform-entry.js +14 -1
  80. package/dist/node/framework/plugins/vite-plugin-ssr-interop.js +5 -1
  81. package/dist/node/framework/types.d.ts +1 -0
  82. package/dist/node/framework/viteception.js +7 -1
  83. package/dist/node/utilities/vite.d.ts +1 -0
  84. package/dist/node/utilities/vite.js +30 -0
  85. package/package.json +7 -6
  86. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-plugin.js +36 -25
  87. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.browser.development.server.js +105 -29
  88. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.browser.production.min.server.js +30 -29
  89. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.node.development.server.js +92 -29
  90. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.node.production.min.server.js +31 -29
  91. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-plugin.js +29 -18
  92. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-writer.browser.server.js +105 -29
  93. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-writer.node.server.js +92 -29
  94. package/vendor/react-server-dom-vite/package.json +2 -2
  95. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-client-middleware.d.ts +0 -9
  96. package/dist/esnext/framework/plugins/vite-plugin-purge-query-cache.js +0 -11
  97. package/dist/node/framework/plugins/vite-plugin-hydrogen-client-middleware.d.ts +0 -9
  98. package/dist/node/framework/plugins/vite-plugin-purge-query-cache.js +0 -16
@@ -162,6 +162,11 @@ function processModelChunk(request, id, model) {
162
162
  var row = serializeRowHeader('J', id) + json + '\n';
163
163
  return stringToChunk(row);
164
164
  }
165
+ function processReferenceChunk(request, id, reference) {
166
+ var json = stringify(reference);
167
+ var row = serializeRowHeader('J', id) + json + '\n';
168
+ return stringToChunk(row);
169
+ }
165
170
  function processModuleChunk(request, id, moduleMetaData) {
166
171
  var json = stringify(moduleMetaData);
167
172
  var row = serializeRowHeader('M', id) + json + '\n';
@@ -504,6 +509,7 @@ var startInlineScript = stringToPrecomputedChunk('<script>');
504
509
  var endInlineScript = stringToPrecomputedChunk('</script>');
505
510
  var startScriptSrc = stringToPrecomputedChunk('<script src="');
506
511
  var startModuleSrc = stringToPrecomputedChunk('<script type="module" src="');
512
+ var scriptIntegirty = stringToPrecomputedChunk('" integrity="');
507
513
  var endAsyncScript = stringToPrecomputedChunk('" async=""></script>');
508
514
 
509
515
  var textSeparator = stringToPrecomputedChunk('<!-- -->');
@@ -981,6 +987,10 @@ function getOrCreateServerContext(globalName) {
981
987
  return ContextRegistry[globalName];
982
988
  }
983
989
 
990
+ var PENDING = 0;
991
+ var COMPLETED = 1;
992
+ var ABORTED = 3;
993
+ var ERRORED = 4;
984
994
  var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
985
995
 
986
996
  function defaultErrorHandler(error) {
@@ -991,7 +1001,8 @@ var OPEN = 0;
991
1001
  var CLOSING = 1;
992
1002
  var CLOSED = 2;
993
1003
  function createRequest(model, bundlerConfig, onError, context, identifierPrefix) {
994
- var pingedSegments = [];
1004
+ var abortSet = new Set();
1005
+ var pingedTasks = [];
995
1006
  var request = {
996
1007
  status: OPEN,
997
1008
  fatalError: null,
@@ -1000,7 +1011,8 @@ function createRequest(model, bundlerConfig, onError, context, identifierPrefix)
1000
1011
  cache: new Map(),
1001
1012
  nextChunkId: 0,
1002
1013
  pendingChunks: 0,
1003
- pingedSegments: pingedSegments,
1014
+ abortableTasks: abortSet,
1015
+ pingedTasks: pingedTasks,
1004
1016
  completedModuleChunks: [],
1005
1017
  completedJSONChunks: [],
1006
1018
  completedErrorChunks: [],
@@ -1016,8 +1028,8 @@ function createRequest(model, bundlerConfig, onError, context, identifierPrefix)
1016
1028
  };
1017
1029
  request.pendingChunks++;
1018
1030
  var rootContext = createRootContext(context);
1019
- var rootSegment = createSegment(request, model, rootContext);
1020
- pingedSegments.push(rootSegment);
1031
+ var rootTask = createTask(request, model, rootContext, abortSet);
1032
+ pingedTasks.push(rootTask);
1021
1033
  return request;
1022
1034
  }
1023
1035
 
@@ -1115,28 +1127,30 @@ function attemptResolveElement(type, key, ref, props) {
1115
1127
  throw new Error("Unsupported server component type: " + describeValueForErrorMessage(type));
1116
1128
  }
1117
1129
 
1118
- function pingSegment(request, segment) {
1119
- var pingedSegments = request.pingedSegments;
1120
- pingedSegments.push(segment);
1130
+ function pingTask(request, task) {
1131
+ var pingedTasks = request.pingedTasks;
1132
+ pingedTasks.push(task);
1121
1133
 
1122
- if (pingedSegments.length === 1) {
1134
+ if (pingedTasks.length === 1) {
1123
1135
  scheduleWork(function () {
1124
1136
  return performWork(request);
1125
1137
  });
1126
1138
  }
1127
1139
  }
1128
1140
 
1129
- function createSegment(request, model, context) {
1141
+ function createTask(request, model, context, abortSet) {
1130
1142
  var id = request.nextChunkId++;
1131
- var segment = {
1143
+ var task = {
1132
1144
  id: id,
1145
+ status: PENDING,
1133
1146
  model: model,
1134
1147
  context: context,
1135
1148
  ping: function () {
1136
- return pingSegment(request, segment);
1149
+ return pingTask(request, task);
1137
1150
  }
1138
1151
  };
1139
- return segment;
1152
+ abortSet.add(task);
1153
+ return task;
1140
1154
  }
1141
1155
 
1142
1156
  function serializeByValueID(id) {
@@ -1371,12 +1385,12 @@ function resolveModelToJSON(request, parent, key, value) {
1371
1385
  }
1372
1386
  } catch (x) {
1373
1387
  if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
1374
- // Something suspended, we'll need to create a new segment and resolve it later.
1388
+ // Something suspended, we'll need to create a new task and resolve it later.
1375
1389
  request.pendingChunks++;
1376
- var newSegment = createSegment(request, value, getActiveContext());
1377
- var ping = newSegment.ping;
1390
+ var newTask = createTask(request, value, getActiveContext(), request.abortableTasks);
1391
+ var ping = newTask.ping;
1378
1392
  x.then(ping, ping);
1379
- return serializeByRefID(newSegment.id);
1393
+ return serializeByRefID(newTask.id);
1380
1394
  } else {
1381
1395
  logRecoverableError(request, x); // Something errored. We'll still send everything we have up until this point.
1382
1396
  // We'll replace this element with a lazy reference that throws on the client
@@ -1584,34 +1598,43 @@ function emitProviderChunk(request, id, contextName) {
1584
1598
  request.completedJSONChunks.push(processedChunk);
1585
1599
  }
1586
1600
 
1587
- function retrySegment(request, segment) {
1588
- switchContext(segment.context);
1601
+ function retryTask(request, task) {
1602
+ if (task.status !== PENDING) {
1603
+ // We completed this by other means before we had a chance to retry it.
1604
+ return;
1605
+ }
1606
+
1607
+ switchContext(task.context);
1589
1608
 
1590
1609
  try {
1591
- var _value3 = segment.model;
1610
+ var _value3 = task.model;
1592
1611
 
1593
1612
  while (typeof _value3 === 'object' && _value3 !== null && _value3.$$typeof === REACT_ELEMENT_TYPE) {
1594
1613
  // TODO: Concatenate keys of parents onto children.
1595
1614
  var element = _value3; // Attempt to render the server component.
1596
- // Doing this here lets us reuse this same segment if the next component
1615
+ // Doing this here lets us reuse this same task if the next component
1597
1616
  // also suspends.
1598
1617
 
1599
- segment.model = _value3;
1618
+ task.model = _value3;
1600
1619
  _value3 = attemptResolveElement(element.type, element.key, element.ref, element.props);
1601
1620
  }
1602
1621
 
1603
- var processedChunk = processModelChunk(request, segment.id, _value3);
1622
+ var processedChunk = processModelChunk(request, task.id, _value3);
1604
1623
  request.completedJSONChunks.push(processedChunk);
1624
+ request.abortableTasks.delete(task);
1625
+ task.status = COMPLETED;
1605
1626
  } catch (x) {
1606
1627
  if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
1607
1628
  // Something suspended again, let's pick it back up later.
1608
- var ping = segment.ping;
1629
+ var ping = task.ping;
1609
1630
  x.then(ping, ping);
1610
1631
  return;
1611
1632
  } else {
1633
+ request.abortableTasks.delete(task);
1634
+ task.status = ERRORED;
1612
1635
  logRecoverableError(request, x); // This errored, we need to serialize this error to the
1613
1636
 
1614
- emitErrorChunk(request, segment.id, x);
1637
+ emitErrorChunk(request, task.id, x);
1615
1638
  }
1616
1639
  }
1617
1640
  }
@@ -1624,12 +1647,12 @@ function performWork(request) {
1624
1647
  prepareToUseHooksForRequest(request);
1625
1648
 
1626
1649
  try {
1627
- var pingedSegments = request.pingedSegments;
1628
- request.pingedSegments = [];
1650
+ var pingedTasks = request.pingedTasks;
1651
+ request.pingedTasks = [];
1629
1652
 
1630
- for (var i = 0; i < pingedSegments.length; i++) {
1631
- var segment = pingedSegments[i];
1632
- retrySegment(request, segment);
1653
+ for (var i = 0; i < pingedTasks.length; i++) {
1654
+ var task = pingedTasks[i];
1655
+ retryTask(request, task);
1633
1656
  }
1634
1657
 
1635
1658
  if (request.destination !== null) {
@@ -1645,6 +1668,15 @@ function performWork(request) {
1645
1668
  }
1646
1669
  }
1647
1670
 
1671
+ function abortTask(task, request, errorId) {
1672
+ task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only
1673
+ // has a single value referencing the error.
1674
+
1675
+ var ref = serializeByValueID(errorId);
1676
+ var processedChunk = processReferenceChunk(request, task.id, ref);
1677
+ request.completedJSONChunks.push(processedChunk);
1678
+ }
1679
+
1648
1680
  function flushCompletedChunks(request, destination) {
1649
1681
  beginWriting();
1650
1682
 
@@ -1744,6 +1776,34 @@ function startFlowing(request, destination) {
1744
1776
  logRecoverableError(request, error);
1745
1777
  fatalError(request, error);
1746
1778
  }
1779
+ } // This is called to early terminate a request. It creates an error at all pending tasks.
1780
+
1781
+ function abort(request, reason) {
1782
+ try {
1783
+ var abortableTasks = request.abortableTasks;
1784
+
1785
+ if (abortableTasks.size > 0) {
1786
+ // We have tasks to abort. We'll emit one error row and then emit a reference
1787
+ // to that row from every row that's still remaining.
1788
+ var _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason;
1789
+
1790
+ logRecoverableError(request, _error);
1791
+ request.pendingChunks++;
1792
+ var errorId = request.nextChunkId++;
1793
+ emitErrorChunk(request, errorId, _error);
1794
+ abortableTasks.forEach(function (task) {
1795
+ return abortTask(task, request, errorId);
1796
+ });
1797
+ abortableTasks.clear();
1798
+ }
1799
+
1800
+ if (request.destination !== null) {
1801
+ flushCompletedChunks(request, request.destination);
1802
+ }
1803
+ } catch (error) {
1804
+ logRecoverableError(request, error);
1805
+ fatalError(request, error);
1806
+ }
1747
1807
  }
1748
1808
 
1749
1809
  function importServerContexts(contexts) {
@@ -1781,6 +1841,22 @@ function renderToReadableStream(model, options) {
1781
1841
  }
1782
1842
  }), {}, // Manifest, not used
1783
1843
  options ? options.onError : undefined, options ? options.context : undefined, options ? options.identifierPrefix : undefined);
1844
+
1845
+ if (options && options.signal) {
1846
+ var signal = options.signal;
1847
+
1848
+ if (signal.aborted) {
1849
+ abort(request, signal.reason);
1850
+ } else {
1851
+ var listener = function () {
1852
+ abort(request, signal.reason);
1853
+ signal.removeEventListener('abort', listener);
1854
+ };
1855
+
1856
+ signal.addEventListener('abort', listener);
1857
+ }
1858
+ }
1859
+
1784
1860
  var stream = new ReadableStream({
1785
1861
  type: 'bytes',
1786
1862
  start: function (controller) {
@@ -228,6 +228,11 @@ function processModelChunk(request, id, model) {
228
228
  var row = serializeRowHeader('J', id) + json + '\n';
229
229
  return stringToChunk(row);
230
230
  }
231
+ function processReferenceChunk(request, id, reference) {
232
+ var json = stringify(reference);
233
+ var row = serializeRowHeader('J', id) + json + '\n';
234
+ return stringToChunk(row);
235
+ }
231
236
  function processModuleChunk(request, id, moduleMetaData) {
232
237
  var json = stringify(moduleMetaData);
233
238
  var row = serializeRowHeader('M', id) + json + '\n';
@@ -570,6 +575,7 @@ var startInlineScript = stringToPrecomputedChunk('<script>');
570
575
  var endInlineScript = stringToPrecomputedChunk('</script>');
571
576
  var startScriptSrc = stringToPrecomputedChunk('<script src="');
572
577
  var startModuleSrc = stringToPrecomputedChunk('<script type="module" src="');
578
+ var scriptIntegirty = stringToPrecomputedChunk('" integrity="');
573
579
  var endAsyncScript = stringToPrecomputedChunk('" async=""></script>');
574
580
 
575
581
  var textSeparator = stringToPrecomputedChunk('<!-- -->');
@@ -1047,6 +1053,10 @@ function getOrCreateServerContext(globalName) {
1047
1053
  return ContextRegistry[globalName];
1048
1054
  }
1049
1055
 
1056
+ var PENDING = 0;
1057
+ var COMPLETED = 1;
1058
+ var ABORTED = 3;
1059
+ var ERRORED = 4;
1050
1060
  var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
1051
1061
 
1052
1062
  function defaultErrorHandler(error) {
@@ -1057,7 +1067,8 @@ var OPEN = 0;
1057
1067
  var CLOSING = 1;
1058
1068
  var CLOSED = 2;
1059
1069
  function createRequest(model, bundlerConfig, onError, context, identifierPrefix) {
1060
- var pingedSegments = [];
1070
+ var abortSet = new Set();
1071
+ var pingedTasks = [];
1061
1072
  var request = {
1062
1073
  status: OPEN,
1063
1074
  fatalError: null,
@@ -1066,7 +1077,8 @@ function createRequest(model, bundlerConfig, onError, context, identifierPrefix)
1066
1077
  cache: new Map(),
1067
1078
  nextChunkId: 0,
1068
1079
  pendingChunks: 0,
1069
- pingedSegments: pingedSegments,
1080
+ abortableTasks: abortSet,
1081
+ pingedTasks: pingedTasks,
1070
1082
  completedModuleChunks: [],
1071
1083
  completedJSONChunks: [],
1072
1084
  completedErrorChunks: [],
@@ -1082,8 +1094,8 @@ function createRequest(model, bundlerConfig, onError, context, identifierPrefix)
1082
1094
  };
1083
1095
  request.pendingChunks++;
1084
1096
  var rootContext = createRootContext(context);
1085
- var rootSegment = createSegment(request, model, rootContext);
1086
- pingedSegments.push(rootSegment);
1097
+ var rootTask = createTask(request, model, rootContext, abortSet);
1098
+ pingedTasks.push(rootTask);
1087
1099
  return request;
1088
1100
  }
1089
1101
 
@@ -1181,28 +1193,30 @@ function attemptResolveElement(type, key, ref, props) {
1181
1193
  throw new Error("Unsupported server component type: " + describeValueForErrorMessage(type));
1182
1194
  }
1183
1195
 
1184
- function pingSegment(request, segment) {
1185
- var pingedSegments = request.pingedSegments;
1186
- pingedSegments.push(segment);
1196
+ function pingTask(request, task) {
1197
+ var pingedTasks = request.pingedTasks;
1198
+ pingedTasks.push(task);
1187
1199
 
1188
- if (pingedSegments.length === 1) {
1200
+ if (pingedTasks.length === 1) {
1189
1201
  scheduleWork(function () {
1190
1202
  return performWork(request);
1191
1203
  });
1192
1204
  }
1193
1205
  }
1194
1206
 
1195
- function createSegment(request, model, context) {
1207
+ function createTask(request, model, context, abortSet) {
1196
1208
  var id = request.nextChunkId++;
1197
- var segment = {
1209
+ var task = {
1198
1210
  id: id,
1211
+ status: PENDING,
1199
1212
  model: model,
1200
1213
  context: context,
1201
1214
  ping: function () {
1202
- return pingSegment(request, segment);
1215
+ return pingTask(request, task);
1203
1216
  }
1204
1217
  };
1205
- return segment;
1218
+ abortSet.add(task);
1219
+ return task;
1206
1220
  }
1207
1221
 
1208
1222
  function serializeByValueID(id) {
@@ -1437,12 +1451,12 @@ function resolveModelToJSON(request, parent, key, value) {
1437
1451
  }
1438
1452
  } catch (x) {
1439
1453
  if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
1440
- // Something suspended, we'll need to create a new segment and resolve it later.
1454
+ // Something suspended, we'll need to create a new task and resolve it later.
1441
1455
  request.pendingChunks++;
1442
- var newSegment = createSegment(request, value, getActiveContext());
1443
- var ping = newSegment.ping;
1456
+ var newTask = createTask(request, value, getActiveContext(), request.abortableTasks);
1457
+ var ping = newTask.ping;
1444
1458
  x.then(ping, ping);
1445
- return serializeByRefID(newSegment.id);
1459
+ return serializeByRefID(newTask.id);
1446
1460
  } else {
1447
1461
  logRecoverableError(request, x); // Something errored. We'll still send everything we have up until this point.
1448
1462
  // We'll replace this element with a lazy reference that throws on the client
@@ -1650,34 +1664,43 @@ function emitProviderChunk(request, id, contextName) {
1650
1664
  request.completedJSONChunks.push(processedChunk);
1651
1665
  }
1652
1666
 
1653
- function retrySegment(request, segment) {
1654
- switchContext(segment.context);
1667
+ function retryTask(request, task) {
1668
+ if (task.status !== PENDING) {
1669
+ // We completed this by other means before we had a chance to retry it.
1670
+ return;
1671
+ }
1672
+
1673
+ switchContext(task.context);
1655
1674
 
1656
1675
  try {
1657
- var _value3 = segment.model;
1676
+ var _value3 = task.model;
1658
1677
 
1659
1678
  while (typeof _value3 === 'object' && _value3 !== null && _value3.$$typeof === REACT_ELEMENT_TYPE) {
1660
1679
  // TODO: Concatenate keys of parents onto children.
1661
1680
  var element = _value3; // Attempt to render the server component.
1662
- // Doing this here lets us reuse this same segment if the next component
1681
+ // Doing this here lets us reuse this same task if the next component
1663
1682
  // also suspends.
1664
1683
 
1665
- segment.model = _value3;
1684
+ task.model = _value3;
1666
1685
  _value3 = attemptResolveElement(element.type, element.key, element.ref, element.props);
1667
1686
  }
1668
1687
 
1669
- var processedChunk = processModelChunk(request, segment.id, _value3);
1688
+ var processedChunk = processModelChunk(request, task.id, _value3);
1670
1689
  request.completedJSONChunks.push(processedChunk);
1690
+ request.abortableTasks.delete(task);
1691
+ task.status = COMPLETED;
1671
1692
  } catch (x) {
1672
1693
  if (typeof x === 'object' && x !== null && typeof x.then === 'function') {
1673
1694
  // Something suspended again, let's pick it back up later.
1674
- var ping = segment.ping;
1695
+ var ping = task.ping;
1675
1696
  x.then(ping, ping);
1676
1697
  return;
1677
1698
  } else {
1699
+ request.abortableTasks.delete(task);
1700
+ task.status = ERRORED;
1678
1701
  logRecoverableError(request, x); // This errored, we need to serialize this error to the
1679
1702
 
1680
- emitErrorChunk(request, segment.id, x);
1703
+ emitErrorChunk(request, task.id, x);
1681
1704
  }
1682
1705
  }
1683
1706
  }
@@ -1690,12 +1713,12 @@ function performWork(request) {
1690
1713
  prepareToUseHooksForRequest(request);
1691
1714
 
1692
1715
  try {
1693
- var pingedSegments = request.pingedSegments;
1694
- request.pingedSegments = [];
1716
+ var pingedTasks = request.pingedTasks;
1717
+ request.pingedTasks = [];
1695
1718
 
1696
- for (var i = 0; i < pingedSegments.length; i++) {
1697
- var segment = pingedSegments[i];
1698
- retrySegment(request, segment);
1719
+ for (var i = 0; i < pingedTasks.length; i++) {
1720
+ var task = pingedTasks[i];
1721
+ retryTask(request, task);
1699
1722
  }
1700
1723
 
1701
1724
  if (request.destination !== null) {
@@ -1711,6 +1734,15 @@ function performWork(request) {
1711
1734
  }
1712
1735
  }
1713
1736
 
1737
+ function abortTask(task, request, errorId) {
1738
+ task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only
1739
+ // has a single value referencing the error.
1740
+
1741
+ var ref = serializeByValueID(errorId);
1742
+ var processedChunk = processReferenceChunk(request, task.id, ref);
1743
+ request.completedJSONChunks.push(processedChunk);
1744
+ }
1745
+
1714
1746
  function flushCompletedChunks(request, destination) {
1715
1747
  beginWriting();
1716
1748
 
@@ -1812,6 +1844,34 @@ function startFlowing(request, destination) {
1812
1844
  logRecoverableError(request, error);
1813
1845
  fatalError(request, error);
1814
1846
  }
1847
+ } // This is called to early terminate a request. It creates an error at all pending tasks.
1848
+
1849
+ function abort(request, reason) {
1850
+ try {
1851
+ var abortableTasks = request.abortableTasks;
1852
+
1853
+ if (abortableTasks.size > 0) {
1854
+ // We have tasks to abort. We'll emit one error row and then emit a reference
1855
+ // to that row from every row that's still remaining.
1856
+ var _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason;
1857
+
1858
+ logRecoverableError(request, _error);
1859
+ request.pendingChunks++;
1860
+ var errorId = request.nextChunkId++;
1861
+ emitErrorChunk(request, errorId, _error);
1862
+ abortableTasks.forEach(function (task) {
1863
+ return abortTask(task, request, errorId);
1864
+ });
1865
+ abortableTasks.clear();
1866
+ }
1867
+
1868
+ if (request.destination !== null) {
1869
+ flushCompletedChunks(request, request.destination);
1870
+ }
1871
+ } catch (error) {
1872
+ logRecoverableError(request, error);
1873
+ fatalError(request, error);
1874
+ }
1815
1875
  }
1816
1876
 
1817
1877
  function importServerContexts(contexts) {
@@ -1867,6 +1927,9 @@ function renderToPipeableStream(model, options) {
1867
1927
  startFlowing(request, destination);
1868
1928
  destination.on('drain', createDrainHandler(destination, request));
1869
1929
  return destination;
1930
+ },
1931
+ abort: function (reason) {
1932
+ abort(request, reason);
1870
1933
  }
1871
1934
  };
1872
1935
  }
@@ -54,8 +54,8 @@
54
54
  "node": ">=0.10.0"
55
55
  },
56
56
  "peerDependencies": {
57
- "react": "^17.0.0",
58
- "vite": "^2.7.1"
57
+ "react": "^18.0.0",
58
+ "vite": "^2.7.1 || ^3.0.7"
59
59
  },
60
60
  "dependencies": {
61
61
  "es-module-lexer": "^0.9.3",
@@ -1,9 +0,0 @@
1
- import { type Plugin } from 'vite';
2
- /**
3
- * This dev server middleware prevents Vite from applying immutable cache control headers to client
4
- * components. These client components are part of the user's local source, but since they are
5
- * referenced via import globs in the `react-dom-server-vite` NPM package, Vite assumes they
6
- * are 3P deps that can be cached. This middleware responds to the requests early with `no-cache`.
7
- */
8
- declare const _default: () => Plugin;
9
- export default _default;
@@ -1,11 +0,0 @@
1
- import Crypto from 'crypto';
2
- export default () => {
3
- const buildCacheId = Crypto.randomBytes(8).toString('hex').slice(0, 8);
4
- return {
5
- name: 'vite-plugin-purge-query-cache',
6
- enforce: 'pre',
7
- transform(code) {
8
- return code.replace('__QUERY_CACHE_ID__', buildCacheId);
9
- },
10
- };
11
- };
@@ -1,9 +0,0 @@
1
- import { type Plugin } from 'vite';
2
- /**
3
- * This dev server middleware prevents Vite from applying immutable cache control headers to client
4
- * components. These client components are part of the user's local source, but since they are
5
- * referenced via import globs in the `react-dom-server-vite` NPM package, Vite assumes they
6
- * are 3P deps that can be cached. This middleware responds to the requests early with `no-cache`.
7
- */
8
- declare const _default: () => Plugin;
9
- export default _default;
@@ -1,16 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const crypto_1 = __importDefault(require("crypto"));
7
- exports.default = () => {
8
- const buildCacheId = crypto_1.default.randomBytes(8).toString('hex').slice(0, 8);
9
- return {
10
- name: 'vite-plugin-purge-query-cache',
11
- enforce: 'pre',
12
- transform(code) {
13
- return code.replace('__QUERY_CACHE_ID__', buildCacheId);
14
- },
15
- };
16
- };