react-server-dom-webpack 18.3.0-canary-a870b2d54-20240314 → 18.3.0-canary-4b84f1161-20240318

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 (39) hide show
  1. package/cjs/react-server-dom-webpack-client.browser.development.js +176 -272
  2. package/cjs/react-server-dom-webpack-client.browser.production.js +146 -127
  3. package/cjs/react-server-dom-webpack-client.browser.production.min.js +25 -24
  4. package/cjs/react-server-dom-webpack-client.browser.production.min.js.map +1 -1
  5. package/cjs/react-server-dom-webpack-client.edge.development.js +181 -324
  6. package/cjs/react-server-dom-webpack-client.edge.production.js +151 -168
  7. package/cjs/react-server-dom-webpack-client.edge.production.min.js +30 -30
  8. package/cjs/react-server-dom-webpack-client.edge.production.min.js.map +1 -1
  9. package/cjs/react-server-dom-webpack-client.node.development.js +181 -324
  10. package/cjs/react-server-dom-webpack-client.node.production.js +151 -168
  11. package/cjs/react-server-dom-webpack-client.node.production.min.js +29 -28
  12. package/cjs/react-server-dom-webpack-client.node.production.min.js.map +1 -1
  13. package/cjs/react-server-dom-webpack-client.node.unbundled.development.js +181 -324
  14. package/cjs/react-server-dom-webpack-client.node.unbundled.production.js +151 -168
  15. package/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js +30 -30
  16. package/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js.map +1 -1
  17. package/cjs/react-server-dom-webpack-node-register.js.map +1 -1
  18. package/cjs/react-server-dom-webpack-plugin.js.map +1 -1
  19. package/cjs/react-server-dom-webpack-server.browser.development.js +424 -587
  20. package/cjs/react-server-dom-webpack-server.browser.production.js +368 -403
  21. package/cjs/react-server-dom-webpack-server.browser.production.min.js +68 -65
  22. package/cjs/react-server-dom-webpack-server.browser.production.min.js.map +1 -1
  23. package/cjs/react-server-dom-webpack-server.edge.development.js +424 -590
  24. package/cjs/react-server-dom-webpack-server.edge.production.js +369 -407
  25. package/cjs/react-server-dom-webpack-server.edge.production.min.js +69 -67
  26. package/cjs/react-server-dom-webpack-server.edge.production.min.js.map +1 -1
  27. package/cjs/react-server-dom-webpack-server.node.development.js +423 -586
  28. package/cjs/react-server-dom-webpack-server.node.production.js +368 -403
  29. package/cjs/react-server-dom-webpack-server.node.production.min.js +72 -70
  30. package/cjs/react-server-dom-webpack-server.node.production.min.js.map +1 -1
  31. package/cjs/react-server-dom-webpack-server.node.unbundled.development.js +423 -586
  32. package/cjs/react-server-dom-webpack-server.node.unbundled.production.js +368 -403
  33. package/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js +69 -67
  34. package/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js.map +1 -1
  35. package/package.json +11 -5
  36. package/umd/react-server-dom-webpack-client.browser.development.js +176 -272
  37. package/umd/react-server-dom-webpack-client.browser.production.min.js +23 -22
  38. package/umd/react-server-dom-webpack-server.browser.development.js +424 -587
  39. package/umd/react-server-dom-webpack-server.browser.production.min.js +52 -52
@@ -13,8 +13,8 @@
13
13
  var util = require('util');
14
14
  require('crypto');
15
15
  var async_hooks = require('async_hooks');
16
- var ReactDOM = require('react-dom');
17
16
  var React = require('react');
17
+ var ReactDOM = require('react-dom');
18
18
 
19
19
  // -----------------------------------------------------------------------------
20
20
  const enablePostpone = false;
@@ -89,10 +89,9 @@ function writeViewChunk(destination, chunk) {
89
89
  }
90
90
 
91
91
  if (chunk.byteLength > VIEW_SIZE) {
92
+ // this chunk may overflow a single view which implies it was not
92
93
  // one that is cached by the streaming renderer. We will enqueu
93
94
  // it directly and expect it is not re-used
94
-
95
-
96
95
  if (writtenBytes > 0) {
97
96
  writeToDestination(destination, currentView.subarray(0, writtenBytes));
98
97
  currentView = new Uint8Array(VIEW_SIZE);
@@ -177,10 +176,10 @@ function closeWithError(destination, error) {
177
176
  }
178
177
 
179
178
  // eslint-disable-next-line no-unused-vars
180
- const CLIENT_REFERENCE_TAG$1 = Symbol.for('react.client.reference');
179
+ const CLIENT_REFERENCE_TAG = Symbol.for('react.client.reference');
181
180
  const SERVER_REFERENCE_TAG = Symbol.for('react.server.reference');
182
181
  function isClientReference(reference) {
183
- return reference.$$typeof === CLIENT_REFERENCE_TAG$1;
182
+ return reference.$$typeof === CLIENT_REFERENCE_TAG;
184
183
  }
185
184
  function isServerReference(reference) {
186
185
  return reference.$$typeof === SERVER_REFERENCE_TAG;
@@ -192,7 +191,7 @@ function registerClientReference(proxyImplementation, id, exportName) {
192
191
  function registerClientReferenceImpl(proxyImplementation, id, async) {
193
192
  return Object.defineProperties(proxyImplementation, {
194
193
  $$typeof: {
195
- value: CLIENT_REFERENCE_TAG$1
194
+ value: CLIENT_REFERENCE_TAG
196
195
  },
197
196
  $$id: {
198
197
  value: id
@@ -213,7 +212,6 @@ function bind() {
213
212
  const newFn = FunctionBind.apply(this, arguments);
214
213
 
215
214
  if (this.$$typeof === SERVER_REFERENCE_TAG) {
216
-
217
215
  const args = ArraySlice.call(arguments, 1);
218
216
  return Object.defineProperties(newFn, {
219
217
  $$typeof: {
@@ -240,16 +238,13 @@ function registerServerReference(reference, id, exportName) {
240
238
  value: SERVER_REFERENCE_TAG
241
239
  },
242
240
  $$id: {
243
- value: exportName === null ? id : id + '#' + exportName,
244
- configurable: true
241
+ value: exportName === null ? id : id + '#' + exportName
245
242
  },
246
243
  $$bound: {
247
- value: null,
248
- configurable: true
244
+ value: null
249
245
  },
250
246
  bind: {
251
- value: bind,
252
- configurable: true
247
+ value: bind
253
248
  }
254
249
  });
255
250
  }
@@ -288,10 +283,6 @@ const deepProxyHandlers = {
288
283
  // $FlowFixMe[prop-missing]
289
284
  return Object.prototype[Symbol.toPrimitive];
290
285
 
291
- case Symbol.toStringTag:
292
- // $FlowFixMe[prop-missing]
293
- return Object.prototype[Symbol.toStringTag];
294
-
295
286
  case 'Provider':
296
287
  throw new Error("Cannot render a Client Context Provider on the Server. " + "Instead, you can export a Client Component wrapper " + "that itself renders a Client Context Provider.");
297
288
  } // eslint-disable-next-line react-internal/safe-string-coercion
@@ -333,10 +324,6 @@ function getReference(target, name) {
333
324
  // $FlowFixMe[prop-missing]
334
325
  return Object.prototype[Symbol.toPrimitive];
335
326
 
336
- case Symbol.toStringTag:
337
- // $FlowFixMe[prop-missing]
338
- return Object.prototype[Symbol.toStringTag];
339
-
340
327
  case '__esModule':
341
328
  // Something is conditionally checking which export to use. We'll pretend to be
342
329
  // an ESM compat module but then we'll check again on the client.
@@ -377,10 +364,6 @@ function getReference(target, name) {
377
364
 
378
365
  }
379
366
 
380
- if (typeof name === 'symbol') {
381
- throw new Error('Cannot read Symbol exports. Only named exports are supported on a client module ' + 'imported on the server.');
382
- }
383
-
384
367
  let cachedReference = target[name];
385
368
 
386
369
  if (!cachedReference) {
@@ -475,9 +458,7 @@ function getServerReferenceBoundArguments(config, serverReference) {
475
458
 
476
459
  const ReactDOMSharedInternals = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
477
460
 
478
- const ReactDOMCurrentDispatcher = ReactDOMSharedInternals.ReactDOMCurrentDispatcher;
479
- const previousDispatcher = ReactDOMCurrentDispatcher.current;
480
- ReactDOMCurrentDispatcher.current = {
461
+ const ReactDOMFlightServerDispatcher = {
481
462
  prefetchDNS,
482
463
  preconnect,
483
464
  preload,
@@ -503,8 +484,6 @@ function prefetchDNS(href) {
503
484
 
504
485
  hints.add(key);
505
486
  emitHint(request, 'D', href);
506
- } else {
507
- previousDispatcher.prefetchDNS(href);
508
487
  }
509
488
  }
510
489
  }
@@ -531,8 +510,6 @@ function preconnect(href, crossOrigin) {
531
510
  } else {
532
511
  emitHint(request, 'C', href);
533
512
  }
534
- } else {
535
- previousDispatcher.preconnect(href, crossOrigin);
536
513
  }
537
514
  }
538
515
  }
@@ -566,8 +543,6 @@ function preload(href, as, options) {
566
543
  } else {
567
544
  emitHint(request, 'L', [href, as]);
568
545
  }
569
- } else {
570
- previousDispatcher.preload(href, as, options);
571
546
  }
572
547
  }
573
548
  }
@@ -595,8 +570,6 @@ function preloadModule$1(href, options) {
595
570
  } else {
596
571
  return emitHint(request, 'm', href);
597
572
  }
598
- } else {
599
- previousDispatcher.preloadModule(href, options);
600
573
  }
601
574
  }
602
575
  }
@@ -626,21 +599,19 @@ function preinitStyle(href, precedence, options) {
626
599
  } else {
627
600
  return emitHint(request, 'S', href);
628
601
  }
629
- } else {
630
- previousDispatcher.preinitStyle(href, precedence, options);
631
602
  }
632
603
  }
633
604
  }
634
605
  }
635
606
 
636
- function preinitScript(src, options) {
607
+ function preinitScript(href, options) {
637
608
  {
638
- if (typeof src === 'string') {
609
+ if (typeof href === 'string') {
639
610
  const request = resolveRequest();
640
611
 
641
612
  if (request) {
642
613
  const hints = getHints(request);
643
- const key = 'X|' + src;
614
+ const key = 'X|' + href;
644
615
 
645
616
  if (hints.has(key)) {
646
617
  // duplicate hint
@@ -651,25 +622,23 @@ function preinitScript(src, options) {
651
622
  const trimmed = trimOptions(options);
652
623
 
653
624
  if (trimmed) {
654
- return emitHint(request, 'X', [src, trimmed]);
625
+ return emitHint(request, 'X', [href, trimmed]);
655
626
  } else {
656
- return emitHint(request, 'X', src);
627
+ return emitHint(request, 'X', href);
657
628
  }
658
- } else {
659
- previousDispatcher.preinitScript(src, options);
660
629
  }
661
630
  }
662
631
  }
663
632
  }
664
633
 
665
- function preinitModuleScript(src, options) {
634
+ function preinitModuleScript(href, options) {
666
635
  {
667
- if (typeof src === 'string') {
636
+ if (typeof href === 'string') {
668
637
  const request = resolveRequest();
669
638
 
670
639
  if (request) {
671
640
  const hints = getHints(request);
672
- const key = 'M|' + src;
641
+ const key = 'M|' + href;
673
642
 
674
643
  if (hints.has(key)) {
675
644
  // duplicate hint
@@ -680,12 +649,10 @@ function preinitModuleScript(src, options) {
680
649
  const trimmed = trimOptions(options);
681
650
 
682
651
  if (trimmed) {
683
- return emitHint(request, 'M', [src, trimmed]);
652
+ return emitHint(request, 'M', [href, trimmed]);
684
653
  } else {
685
- return emitHint(request, 'M', src);
654
+ return emitHint(request, 'M', href);
686
655
  }
687
- } else {
688
- previousDispatcher.preinitModuleScript(src, options);
689
656
  }
690
657
  }
691
658
  }
@@ -727,7 +694,10 @@ function getImagePreloadKey(href, imageSrcSet, imageSizes) {
727
694
  return "[image]" + uniquePart;
728
695
  }
729
696
 
730
- // This module registers the host dispatcher so it needs to be imported
697
+ const ReactDOMCurrentDispatcher = ReactDOMSharedInternals.Dispatcher;
698
+ function prepareHostDispatcher() {
699
+ ReactDOMCurrentDispatcher.current = ReactDOMFlightServerDispatcher;
700
+ } // Used to distinguish these contexts from ones used in other renderers.
731
701
  // small, smaller than how we encode undefined, and is unambiguous. We could use
732
702
  // a different tuple structure to encode this instead but this makes the runtime
733
703
  // cost cheaper by eliminating a type checks in more positions.
@@ -737,7 +707,6 @@ function createHints() {
737
707
  return new Set();
738
708
  }
739
709
 
740
- const supportsRequestStorage = true;
741
710
  const requestStorage = new async_hooks.AsyncLocalStorage();
742
711
 
743
712
  // ATTENTION
@@ -746,7 +715,7 @@ const requestStorage = new async_hooks.AsyncLocalStorage();
746
715
  // The Symbol used to tag the ReactElement-like types.
747
716
  const REACT_ELEMENT_TYPE = Symbol.for('react.element');
748
717
  const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
749
- const REACT_CONTEXT_TYPE = Symbol.for('react.context');
718
+ const REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
750
719
  const REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
751
720
  const REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
752
721
  const REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
@@ -770,6 +739,146 @@ function getIteratorFn(maybeIterable) {
770
739
  return null;
771
740
  }
772
741
 
742
+ // Forming a reverse tree.
743
+ // The structure of a context snapshot is an implementation of this file.
744
+ // Currently, it's implemented as tracking the current active node.
745
+
746
+
747
+ const rootContextSnapshot = null; // We assume that this runtime owns the "current" field on all ReactContext instances.
748
+ // This global (actually thread local) state represents what state all those "current",
749
+ // fields are currently in.
750
+
751
+ let currentActiveSnapshot = null;
752
+
753
+ function popNode(prev) {
754
+ {
755
+ prev.context._currentValue = prev.parentValue;
756
+ }
757
+ }
758
+
759
+ function pushNode(next) {
760
+ {
761
+ next.context._currentValue = next.value;
762
+ }
763
+ }
764
+
765
+ function popToNearestCommonAncestor(prev, next) {
766
+ if (prev === next) ; else {
767
+ popNode(prev);
768
+ const parentPrev = prev.parent;
769
+ const parentNext = next.parent;
770
+
771
+ if (parentPrev === null) {
772
+ if (parentNext !== null) {
773
+ throw new Error('The stacks must reach the root at the same time. This is a bug in React.');
774
+ }
775
+ } else {
776
+ if (parentNext === null) {
777
+ throw new Error('The stacks must reach the root at the same time. This is a bug in React.');
778
+ }
779
+
780
+ popToNearestCommonAncestor(parentPrev, parentNext); // On the way back, we push the new ones that weren't common.
781
+
782
+ pushNode(next);
783
+ }
784
+ }
785
+ }
786
+
787
+ function popAllPrevious(prev) {
788
+ popNode(prev);
789
+ const parentPrev = prev.parent;
790
+
791
+ if (parentPrev !== null) {
792
+ popAllPrevious(parentPrev);
793
+ }
794
+ }
795
+
796
+ function pushAllNext(next) {
797
+ const parentNext = next.parent;
798
+
799
+ if (parentNext !== null) {
800
+ pushAllNext(parentNext);
801
+ }
802
+
803
+ pushNode(next);
804
+ }
805
+
806
+ function popPreviousToCommonLevel(prev, next) {
807
+ popNode(prev);
808
+ const parentPrev = prev.parent;
809
+
810
+ if (parentPrev === null) {
811
+ throw new Error('The depth must equal at least at zero before reaching the root. This is a bug in React.');
812
+ }
813
+
814
+ if (parentPrev.depth === next.depth) {
815
+ // We found the same level. Now we just need to find a shared ancestor.
816
+ popToNearestCommonAncestor(parentPrev, next);
817
+ } else {
818
+ // We must still be deeper.
819
+ popPreviousToCommonLevel(parentPrev, next);
820
+ }
821
+ }
822
+
823
+ function popNextToCommonLevel(prev, next) {
824
+ const parentNext = next.parent;
825
+
826
+ if (parentNext === null) {
827
+ throw new Error('The depth must equal at least at zero before reaching the root. This is a bug in React.');
828
+ }
829
+
830
+ if (prev.depth === parentNext.depth) {
831
+ // We found the same level. Now we just need to find a shared ancestor.
832
+ popToNearestCommonAncestor(prev, parentNext);
833
+ } else {
834
+ // We must still be deeper.
835
+ popNextToCommonLevel(prev, parentNext);
836
+ }
837
+
838
+ pushNode(next);
839
+ } // Perform context switching to the new snapshot.
840
+ // To make it cheap to read many contexts, while not suspending, we make the switch eagerly by
841
+ // updating all the context's current values. That way reads, always just read the current value.
842
+ // At the cost of updating contexts even if they're never read by this subtree.
843
+
844
+
845
+ function switchContext(newSnapshot) {
846
+ // The basic algorithm we need to do is to pop back any contexts that are no longer on the stack.
847
+ // We also need to update any new contexts that are now on the stack with the deepest value.
848
+ // The easiest way to update new contexts is to just reapply them in reverse order from the
849
+ // perspective of the backpointers. To avoid allocating a lot when switching, we use the stack
850
+ // for that. Therefore this algorithm is recursive.
851
+ // 1) First we pop which ever snapshot tree was deepest. Popping old contexts as we go.
852
+ // 2) Then we find the nearest common ancestor from there. Popping old contexts as we go.
853
+ // 3) Then we reapply new contexts on the way back up the stack.
854
+ const prev = currentActiveSnapshot;
855
+ const next = newSnapshot;
856
+
857
+ if (prev !== next) {
858
+ if (prev === null) {
859
+ // $FlowFixMe[incompatible-call]: This has to be non-null since it's not equal to prev.
860
+ pushAllNext(next);
861
+ } else if (next === null) {
862
+ popAllPrevious(prev);
863
+ } else if (prev.depth === next.depth) {
864
+ popToNearestCommonAncestor(prev, next);
865
+ } else if (prev.depth > next.depth) {
866
+ popPreviousToCommonLevel(prev, next);
867
+ } else {
868
+ popNextToCommonLevel(prev, next);
869
+ }
870
+
871
+ currentActiveSnapshot = next;
872
+ }
873
+ }
874
+ function getActiveContext() {
875
+ return currentActiveSnapshot;
876
+ }
877
+ function readContext$1(context) {
878
+ const value = context._currentValue ;
879
+ return value;
880
+ }
881
+
773
882
  // Corresponds to ReactFiberWakeable and ReactFizzWakeable modules. Generally,
774
883
  // changes to one module should be reflected in the others.
775
884
  // TODO: Rename this module and the corresponding Fiber one to "Thenable"
@@ -898,13 +1007,16 @@ function prepareToUseHooksForComponent(prevThenableState) {
898
1007
  thenableState = prevThenableState;
899
1008
  }
900
1009
  function getThenableStateAfterSuspending() {
901
- // If you use() to Suspend this should always exist but if you throw a Promise instead,
902
- // which is not really supported anymore, it will be empty. We use the empty set as a
903
- // marker to know if this was a replay of the same component or first attempt.
904
- const state = thenableState || createThenableState();
1010
+ const state = thenableState;
905
1011
  thenableState = null;
906
1012
  return state;
907
1013
  }
1014
+
1015
+ function readContext(context) {
1016
+
1017
+ return readContext$1(context);
1018
+ }
1019
+
908
1020
  const HooksDispatcher = {
909
1021
  useMemo(nextCreate) {
910
1022
  return nextCreate();
@@ -918,8 +1030,8 @@ const HooksDispatcher = {
918
1030
 
919
1031
  useDeferredValue: unsupportedHook,
920
1032
  useTransition: unsupportedHook,
921
- readContext: unsupportedContext,
922
- useContext: unsupportedContext,
1033
+ readContext,
1034
+ useContext: readContext,
923
1035
  useReducer: unsupportedHook,
924
1036
  useRef: unsupportedHook,
925
1037
  useState: unsupportedHook,
@@ -955,10 +1067,6 @@ function unsupportedRefresh() {
955
1067
  throw new Error('Refreshing the cache is not supported in Server Components.');
956
1068
  }
957
1069
 
958
- function unsupportedContext() {
959
- throw new Error('Cannot read a Client Context from a Server Component.');
960
- }
961
-
962
1070
  function useId() {
963
1071
  if (currentRequest$1 === null) {
964
1072
  throw new Error('useId can only be used while React is rendering');
@@ -984,22 +1092,14 @@ function use(usable) {
984
1092
  }
985
1093
 
986
1094
  return trackUsedThenable(thenableState, thenable, index);
987
- } else if (usable.$$typeof === REACT_CONTEXT_TYPE) {
988
- unsupportedContext();
1095
+ } else if (usable.$$typeof === REACT_SERVER_CONTEXT_TYPE) {
1096
+ const context = usable;
1097
+ return readContext(context);
989
1098
  }
990
1099
  }
991
1100
 
992
- if (isClientReference(usable)) {
993
- if (usable.value != null && usable.value.$$typeof === REACT_CONTEXT_TYPE) {
994
- // Show a more specific message since it's a common mistake.
995
- throw new Error('Cannot read a Client Context from a Server Component.');
996
- } else {
997
- throw new Error('Cannot use() an already resolved Client Reference.');
998
- }
999
- } else {
1000
- throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion
1001
- 'An unsupported type was passed to use(): ' + String(usable));
1002
- }
1101
+
1102
+ throw new Error('An unsupported type was passed to use(): ' + String(usable));
1003
1103
  }
1004
1104
 
1005
1105
  function createSignal() {
@@ -1078,10 +1178,6 @@ function describeValueForErrorMessage(value) {
1078
1178
  return '[...]';
1079
1179
  }
1080
1180
 
1081
- if (value !== null && value.$$typeof === CLIENT_REFERENCE_TAG) {
1082
- return describeClientReference();
1083
- }
1084
-
1085
1181
  const name = objectName(value);
1086
1182
 
1087
1183
  if (name === 'Object') {
@@ -1092,14 +1188,7 @@ function describeValueForErrorMessage(value) {
1092
1188
  }
1093
1189
 
1094
1190
  case 'function':
1095
- {
1096
- if (value.$$typeof === CLIENT_REFERENCE_TAG) {
1097
- return describeClientReference();
1098
- }
1099
-
1100
- const name = value.displayName || value.name;
1101
- return name ? 'function ' + name : 'function';
1102
- }
1191
+ return 'function';
1103
1192
 
1104
1193
  default:
1105
1194
  // eslint-disable-next-line react-internal/safe-string-coercion
@@ -1145,12 +1234,6 @@ function describeElementType(type) {
1145
1234
  return '';
1146
1235
  }
1147
1236
 
1148
- const CLIENT_REFERENCE_TAG = Symbol.for('react.client.reference');
1149
-
1150
- function describeClientReference(ref) {
1151
- return 'client';
1152
- }
1153
-
1154
1237
  function describeObjectForErrorMessage(objectOrArray, expandedName) {
1155
1238
  const objKind = objectName(objectOrArray);
1156
1239
 
@@ -1198,8 +1281,6 @@ function describeObjectForErrorMessage(objectOrArray, expandedName) {
1198
1281
  } else {
1199
1282
  if (objectOrArray.$$typeof === REACT_ELEMENT_TYPE) {
1200
1283
  str = '<' + describeElementType(objectOrArray.type) + '/>';
1201
- } else if (objectOrArray.$$typeof === CLIENT_REFERENCE_TAG) {
1202
- return describeClientReference();
1203
1284
  } else {
1204
1285
  // Print Object
1205
1286
  str = '{';
@@ -1279,11 +1360,12 @@ function defaultPostponeHandler(reason) {// Noop
1279
1360
  const OPEN = 0;
1280
1361
  const CLOSING = 1;
1281
1362
  const CLOSED = 2;
1282
- function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName) {
1363
+ function createRequest(model, bundlerConfig, onError, context, identifierPrefix, onPostpone) {
1283
1364
  if (ReactCurrentCache.current !== null && ReactCurrentCache.current !== DefaultCacheDispatcher) {
1284
1365
  throw new Error('Currently React only supports one RSC renderer at a time.');
1285
1366
  }
1286
1367
 
1368
+ prepareHostDispatcher();
1287
1369
  ReactCurrentCache.current = DefaultCacheDispatcher;
1288
1370
  const abortSet = new Set();
1289
1371
  const pingedTasks = [];
@@ -1309,15 +1391,21 @@ function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpo
1309
1391
  writtenSymbols: new Map(),
1310
1392
  writtenClientReferences: new Map(),
1311
1393
  writtenServerReferences: new Map(),
1394
+ writtenProviders: new Map(),
1312
1395
  writtenObjects: new WeakMap(),
1313
1396
  identifierPrefix: identifierPrefix || '',
1314
1397
  identifierCount: 1,
1315
1398
  taintCleanupQueue: cleanupQueue,
1316
1399
  onError: onError === undefined ? defaultErrorHandler : onError,
1317
- onPostpone: onPostpone === undefined ? defaultPostponeHandler : onPostpone
1400
+ onPostpone: onPostpone === undefined ? defaultPostponeHandler : onPostpone,
1401
+ // $FlowFixMe[missing-this-annot]
1402
+ toJSON: function (key, value) {
1403
+ return resolveModelToJSON(request, this, key, value);
1404
+ }
1318
1405
  };
1319
-
1320
- const rootTask = createTask(request, model, null, false, abortSet);
1406
+ request.pendingChunks++;
1407
+ const rootContext = createRootContext();
1408
+ const rootTask = createTask(request, model, rootContext, abortSet);
1321
1409
  pingedTasks.push(rootTask);
1322
1410
  return request;
1323
1411
  }
@@ -1333,9 +1421,13 @@ function resolveRequest() {
1333
1421
  return null;
1334
1422
  }
1335
1423
 
1336
- function serializeThenable(request, task, thenable) {
1337
- const newTask = createTask(request, null, task.keyPath, // the server component sequence continues through Promise-as-a-child.
1338
- task.implicitSlot, request.abortableTasks);
1424
+ function createRootContext(reqContext) {
1425
+ return importServerContexts();
1426
+ }
1427
+
1428
+ function serializeThenable(request, thenable) {
1429
+ request.pendingChunks++;
1430
+ const newTask = createTask(request, null, getActiveContext(), request.abortableTasks);
1339
1431
 
1340
1432
  switch (thenable.status) {
1341
1433
  case 'fulfilled':
@@ -1469,117 +1561,61 @@ function createLazyWrapperAroundWakeable(wakeable) {
1469
1561
  _payload: thenable,
1470
1562
  _init: readThenable
1471
1563
  };
1472
-
1473
1564
  return lazyType;
1474
1565
  }
1475
1566
 
1476
- function renderFunctionComponent(request, task, key, Component, props) {
1477
- // Reset the task's thenable state before continuing, so that if a later
1478
- // component suspends we can reuse the same task object. If the same
1479
- // component suspends again, the thenable state will be restored.
1480
- const prevThenableState = task.thenableState;
1481
- task.thenableState = null;
1482
-
1483
- prepareToUseHooksForComponent(prevThenableState); // The secondArg is always undefined in Server Components since refs error early.
1484
-
1485
- const secondArg = undefined;
1486
- let result = Component(props, secondArg);
1487
-
1488
- if (typeof result === 'object' && result !== null && typeof result.then === 'function') {
1489
- // When the return value is in children position we can resolve it immediately,
1490
- // to its value without a wrapper if it's synchronously available.
1491
- const thenable = result;
1492
-
1493
- if (thenable.status === 'fulfilled') {
1494
- return thenable.value;
1495
- } // TODO: Once we accept Promises as children on the client, we can just return
1496
- // the thenable here.
1497
-
1498
-
1499
- result = createLazyWrapperAroundWakeable(result);
1500
- } // Track this element's key on the Server Component on the keyPath context..
1501
-
1502
-
1503
- const prevKeyPath = task.keyPath;
1504
- const prevImplicitSlot = task.implicitSlot;
1505
-
1506
- if (key !== null) {
1507
- // Append the key to the path. Technically a null key should really add the child
1508
- // index. We don't do that to hold the payload small and implementation simple.
1509
- task.keyPath = prevKeyPath === null ? key : prevKeyPath + ',' + key;
1510
- } else if (prevKeyPath === null) {
1511
- // This sequence of Server Components has no keys. This means that it was rendered
1512
- // in a slot that needs to assign an implicit key. Even if children below have
1513
- // explicit keys, they should not be used for the outer most key since it might
1514
- // collide with other slots in that set.
1515
- task.implicitSlot = true;
1516
- }
1517
-
1518
- const json = renderModelDestructive(request, task, emptyRoot, '', result);
1519
- task.keyPath = prevKeyPath;
1520
- task.implicitSlot = prevImplicitSlot;
1521
- return json;
1522
- }
1523
-
1524
- function renderFragment(request, task, children) {
1525
-
1526
- {
1527
- return children;
1528
- }
1529
- }
1530
-
1531
- function renderClientElement(task, type, key, props) {
1532
- {
1533
- return [REACT_ELEMENT_TYPE, type, key, props];
1534
- } // We prepend the terminal client element that actually gets serialized with
1535
- } // The chunk ID we're currently rendering that we can assign debug data to.
1536
-
1537
-
1538
- let debugID = null;
1539
-
1540
- function renderElement(request, task, type, key, ref, props) {
1567
+ function attemptResolveElement(request, type, key, ref, props, prevThenableState) {
1541
1568
  if (ref !== null && ref !== undefined) {
1542
1569
  // When the ref moves to the regular props object this will implicitly
1543
1570
  // throw for functions. We could probably relax it to a DEV warning for other
1544
1571
  // cases.
1545
- // TODO: `ref` is now just a prop when `enableRefAsProp` is on. Should we
1546
- // do what the above comment says?
1547
1572
  throw new Error('Refs cannot be used in Server Components, nor passed to Client Components.');
1548
1573
  }
1549
1574
 
1550
1575
  if (typeof type === 'function') {
1551
1576
  if (isClientReference(type)) {
1552
1577
  // This is a reference to a Client Component.
1553
- return renderClientElement(task, type, key, props);
1554
- } // This is a Server Component.
1578
+ return [REACT_ELEMENT_TYPE, type, key, props];
1579
+ } // This is a server-side component.
1580
+
1581
+
1582
+ prepareToUseHooksForComponent(prevThenableState);
1583
+ const result = type(props);
1584
+
1585
+ if (typeof result === 'object' && result !== null && typeof result.then === 'function') {
1586
+ // When the return value is in children position we can resolve it immediately,
1587
+ // to its value without a wrapper if it's synchronously available.
1588
+ const thenable = result;
1555
1589
 
1590
+ if (thenable.status === 'fulfilled') {
1591
+ return thenable.value;
1592
+ } // TODO: Once we accept Promises as children on the client, we can just return
1593
+ // the thenable here.
1594
+
1595
+
1596
+ return createLazyWrapperAroundWakeable(result);
1597
+ }
1556
1598
 
1557
- return renderFunctionComponent(request, task, key, type, props);
1599
+ return result;
1558
1600
  } else if (typeof type === 'string') {
1559
1601
  // This is a host element. E.g. HTML.
1560
- return renderClientElement(task, type, key, props);
1602
+ return [REACT_ELEMENT_TYPE, type, key, props];
1561
1603
  } else if (typeof type === 'symbol') {
1562
- if (type === REACT_FRAGMENT_TYPE && key === null) {
1604
+ if (type === REACT_FRAGMENT_TYPE) {
1563
1605
  // For key-less fragments, we add a small optimization to avoid serializing
1564
1606
  // it as a wrapper.
1565
- const prevImplicitSlot = task.implicitSlot;
1566
-
1567
- if (task.keyPath === null) {
1568
- task.implicitSlot = true;
1569
- }
1570
-
1571
- const json = renderModelDestructive(request, task, emptyRoot, '', props.children);
1572
- task.implicitSlot = prevImplicitSlot;
1573
- return json;
1607
+ // TODO: If a key is specified, we should propagate its key to any children.
1608
+ // Same as if a Server Component has a key.
1609
+ return props.children;
1574
1610
  } // This might be a built-in React component. We'll let the client decide.
1575
1611
  // Any built-in works as long as its props are serializable.
1576
1612
 
1577
1613
 
1578
- return renderClientElement(task, type, key, props);
1614
+ return [REACT_ELEMENT_TYPE, type, key, props];
1579
1615
  } else if (type != null && typeof type === 'object') {
1580
1616
  if (isClientReference(type)) {
1581
1617
  // This is a reference to a Client Component.
1582
- return renderClientElement(task, type, key, props);
1618
+ return [REACT_ELEMENT_TYPE, type, key, props];
1583
1619
  }
1584
1620
 
1585
1621
  switch (type.$$typeof) {
@@ -1588,17 +1624,19 @@ function renderElement(request, task, type, key, ref, props) {
1588
1624
  const payload = type._payload;
1589
1625
  const init = type._init;
1590
1626
  const wrappedType = init(payload);
1591
- return renderElement(request, task, wrappedType, key, ref, props);
1627
+ return attemptResolveElement(request, wrappedType, key, ref, props, prevThenableState);
1592
1628
  }
1593
1629
 
1594
1630
  case REACT_FORWARD_REF_TYPE:
1595
1631
  {
1596
- return renderFunctionComponent(request, task, key, type.render, props);
1632
+ const render = type.render;
1633
+ prepareToUseHooksForComponent(prevThenableState);
1634
+ return render(props, undefined);
1597
1635
  }
1598
1636
 
1599
1637
  case REACT_MEMO_TYPE:
1600
1638
  {
1601
- return renderElement(request, task, type.type, key, ref, props);
1639
+ return attemptResolveElement(request, type.type, key, ref, props, prevThenableState);
1602
1640
  }
1603
1641
  }
1604
1642
  }
@@ -1616,30 +1654,14 @@ function pingTask(request, task) {
1616
1654
  }
1617
1655
  }
1618
1656
 
1619
- function createTask(request, model, keyPath, implicitSlot, abortSet) {
1620
- request.pendingChunks++;
1657
+ function createTask(request, model, context, abortSet) {
1621
1658
  const id = request.nextChunkId++;
1622
-
1623
- if (typeof model === 'object' && model !== null) {
1624
- // If we're about to write this into a new task we can assign it an ID early so that
1625
- // any other references can refer to the value we're about to write.
1626
- {
1627
- request.writtenObjects.set(model, id);
1628
- }
1629
- }
1630
-
1631
1659
  const task = {
1632
1660
  id,
1633
1661
  status: PENDING$1,
1634
1662
  model,
1635
- keyPath,
1636
- implicitSlot,
1663
+ context,
1637
1664
  ping: () => pingTask(request, task),
1638
- toJSON: function (parentPropertyName, value) {
1639
- const parent = this; // Make sure that `parent[parentPropertyName]` wasn't JSONified before `value` was passed to us
1640
-
1641
- return renderModel(request, task, parent, parentPropertyName, value);
1642
- },
1643
1665
  thenableState: null
1644
1666
  };
1645
1667
  abortSet.add(task);
@@ -1708,13 +1730,13 @@ function encodeReferenceChunk(request, id, reference) {
1708
1730
  return stringToChunk(row);
1709
1731
  }
1710
1732
 
1711
- function serializeClientReference(request, parent, parentPropertyName, clientReference) {
1733
+ function serializeClientReference(request, parent, key, clientReference) {
1712
1734
  const clientReferenceKey = getClientReferenceKey(clientReference);
1713
1735
  const writtenClientReferences = request.writtenClientReferences;
1714
1736
  const existingId = writtenClientReferences.get(clientReferenceKey);
1715
1737
 
1716
1738
  if (existingId !== undefined) {
1717
- if (parent[0] === REACT_ELEMENT_TYPE && parentPropertyName === '1') {
1739
+ if (parent[0] === REACT_ELEMENT_TYPE && key === '1') {
1718
1740
  // If we're encoding the "type" of an element, we can refer
1719
1741
  // to that by a lazy reference instead of directly since React
1720
1742
  // knows how to deal with lazy values. This lets us suspend
@@ -1733,7 +1755,7 @@ function serializeClientReference(request, parent, parentPropertyName, clientRef
1733
1755
  emitImportChunk(request, importId, clientReferenceMetadata);
1734
1756
  writtenClientReferences.set(clientReferenceKey, importId);
1735
1757
 
1736
- if (parent[0] === REACT_ELEMENT_TYPE && parentPropertyName === '1') {
1758
+ if (parent[0] === REACT_ELEMENT_TYPE && key === '1') {
1737
1759
  // If we're encoding the "type" of an element, we can refer
1738
1760
  // to that by a lazy reference instead of directly since React
1739
1761
  // knows how to deal with lazy values. This lets us suspend
@@ -1753,14 +1775,13 @@ function serializeClientReference(request, parent, parentPropertyName, clientRef
1753
1775
  }
1754
1776
 
1755
1777
  function outlineModel(request, value) {
1756
- const newTask = createTask(request, value, null, // The way we use outlining is for reusing an object.
1757
- false, // It makes no sense for that use case to be contextual.
1758
- request.abortableTasks);
1778
+ request.pendingChunks++;
1779
+ const newTask = createTask(request, value, getActiveContext(), request.abortableTasks);
1759
1780
  retryTask(request, newTask);
1760
1781
  return newTask.id;
1761
1782
  }
1762
1783
 
1763
- function serializeServerReference(request, serverReference) {
1784
+ function serializeServerReference(request, parent, key, serverReference) {
1764
1785
  const writtenServerReferences = request.writtenServerReferences;
1765
1786
  const existingId = writtenServerReferences.get(serverReference);
1766
1787
 
@@ -1840,77 +1861,91 @@ function escapeStringValue(value) {
1840
1861
  return value;
1841
1862
  }
1842
1863
  }
1843
-
1844
1864
  let modelRoot = false;
1845
1865
 
1846
- function renderModel(request, task, parent, key, value) {
1847
- const prevKeyPath = task.keyPath;
1848
- const prevImplicitSlot = task.implicitSlot;
1866
+ function resolveModelToJSON(request, parent, key, value) {
1849
1867
 
1850
- try {
1851
- return renderModelDestructive(request, task, parent, key, value);
1852
- } catch (thrownValue) {
1853
- const x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical
1854
- // reasons, the rest of the Suspense implementation expects the thrown
1855
- // value to be a thenable, because before `use` existed that was the
1856
- // (unstable) API for suspending. This implementation detail can change
1857
- // later, once we deprecate the old API in favor of `use`.
1858
- getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced
1859
- // to a lazy reference, so that it doesn't error the parent.
1860
1868
 
1861
- const model = task.model;
1862
- const wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE);
1869
+ switch (value) {
1870
+ case REACT_ELEMENT_TYPE:
1871
+ return '$';
1872
+ }
1863
1873
 
1864
- if (typeof x === 'object' && x !== null) {
1865
- // $FlowFixMe[method-unbinding]
1866
- if (typeof x.then === 'function') {
1867
- // Something suspended, we'll need to create a new task and resolve it later.
1868
- const newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks);
1869
- const ping = newTask.ping;
1870
- x.then(ping, ping);
1871
- newTask.thenableState = getThenableStateAfterSuspending(); // Restore the context. We assume that this will be restored by the inner
1872
- // functions in case nothing throws so we don't use "finally" here.
1873
1874
 
1874
- task.keyPath = prevKeyPath;
1875
- task.implicitSlot = prevImplicitSlot;
1875
+ while (typeof value === 'object' && value !== null && (value.$$typeof === REACT_ELEMENT_TYPE || value.$$typeof === REACT_LAZY_TYPE)) {
1876
1876
 
1877
- if (wasReactNode) {
1878
- return serializeLazyID(newTask.id);
1879
- }
1877
+ try {
1878
+ switch (value.$$typeof) {
1879
+ case REACT_ELEMENT_TYPE:
1880
+ {
1881
+ const writtenObjects = request.writtenObjects;
1882
+ const existingId = writtenObjects.get(value);
1883
+
1884
+ if (existingId !== undefined) {
1885
+ if (existingId === -1) {
1886
+ // Seen but not yet outlined.
1887
+ const newId = outlineModel(request, value);
1888
+ return serializeByValueID(newId);
1889
+ } else if (modelRoot === value) {
1890
+ // This is the ID we're currently emitting so we need to write it
1891
+ // once but if we discover it again, we refer to it by id.
1892
+ modelRoot = null;
1893
+ } else {
1894
+ // We've already emitted this as an outlined object, so we can
1895
+ // just refer to that by its existing ID.
1896
+ return serializeByValueID(existingId);
1897
+ }
1898
+ } else {
1899
+ // This is the first time we've seen this object. We may never see it again
1900
+ // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
1901
+ writtenObjects.set(value, -1);
1902
+ } // TODO: Concatenate keys of parents onto children.
1880
1903
 
1881
- return serializeByValueID(newTask.id);
1882
- }
1883
- } // Restore the context. We assume that this will be restored by the inner
1884
- // functions in case nothing throws so we don't use "finally" here.
1885
1904
 
1905
+ const element = value; // Attempt to render the Server Component.
1886
1906
 
1887
- task.keyPath = prevKeyPath;
1888
- task.implicitSlot = prevImplicitSlot;
1907
+ value = attemptResolveElement(request, element.type, element.key, element.ref, element.props, null);
1908
+ break;
1909
+ }
1889
1910
 
1890
- if (wasReactNode) {
1891
- // Something errored. We'll still send everything we have up until this point.
1911
+ case REACT_LAZY_TYPE:
1912
+ {
1913
+ const payload = value._payload;
1914
+ const init = value._init;
1915
+ value = init(payload);
1916
+ break;
1917
+ }
1918
+ }
1919
+ } catch (thrownValue) {
1920
+ const x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical
1921
+ // reasons, the rest of the Suspense implementation expects the thrown
1922
+ // value to be a thenable, because before `use` existed that was the
1923
+ // (unstable) API for suspending. This implementation detail can change
1924
+ // later, once we deprecate the old API in favor of `use`.
1925
+ getSuspendedThenable() : thrownValue;
1926
+
1927
+ if (typeof x === 'object' && x !== null) {
1928
+ // $FlowFixMe[method-unbinding]
1929
+ if (typeof x.then === 'function') {
1930
+ // Something suspended, we'll need to create a new task and resolve it later.
1931
+ request.pendingChunks++;
1932
+ const newTask = createTask(request, value, getActiveContext(), request.abortableTasks);
1933
+ const ping = newTask.ping;
1934
+ x.then(ping, ping);
1935
+ newTask.thenableState = getThenableStateAfterSuspending();
1936
+ return serializeLazyID(newTask.id);
1937
+ }
1938
+ } // Something errored. We'll still send everything we have up until this point.
1892
1939
  // We'll replace this element with a lazy reference that throws on the client
1893
1940
  // once it gets rendered.
1941
+
1942
+
1894
1943
  request.pendingChunks++;
1895
1944
  const errorId = request.nextChunkId++;
1896
1945
  const digest = logRecoverableError(request, x);
1897
1946
  emitErrorChunk(request, errorId, digest);
1898
1947
  return serializeLazyID(errorId);
1899
- } // Something errored but it was not in a React Node. There's no need to serialize
1900
- // it by value because it'll just error the whole parent row anyway so we can
1901
- // just stop any siblings and error the whole parent row.
1902
-
1903
-
1904
- throw x;
1905
- }
1906
- }
1907
-
1908
- function renderModelDestructive(request, task, parent, parentPropertyName, value) {
1909
- // Set the currently rendering model
1910
- task.model = value; // Special Symbol, that's very common.
1911
-
1912
- if (value === REACT_ELEMENT_TYPE) {
1913
- return '$';
1948
+ }
1914
1949
  }
1915
1950
 
1916
1951
  if (value === null) {
@@ -1918,70 +1953,9 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
1918
1953
  }
1919
1954
 
1920
1955
  if (typeof value === 'object') {
1921
- switch (value.$$typeof) {
1922
- case REACT_ELEMENT_TYPE:
1923
- {
1924
- const writtenObjects = request.writtenObjects;
1925
- const existingId = writtenObjects.get(value);
1926
-
1927
- if (existingId !== undefined) {
1928
- if (modelRoot === value) {
1929
- // This is the ID we're currently emitting so we need to write it
1930
- // once but if we discover it again, we refer to it by id.
1931
- modelRoot = null;
1932
- } else if (existingId === -1) {
1933
- // Seen but not yet outlined.
1934
- // TODO: If we throw here we can treat this as suspending which causes an outline
1935
- // but that is able to reuse the same task if we're already in one but then that
1936
- // will be a lazy future value rather than guaranteed to exist but maybe that's good.
1937
- const newId = outlineModel(request, value);
1938
- return serializeByValueID(newId);
1939
- } else {
1940
- // We've already emitted this as an outlined object, so we can refer to that by its
1941
- // existing ID. TODO: We should use a lazy reference since, unlike plain objects,
1942
- // elements might suspend so it might not have emitted yet even if we have the ID for
1943
- // it. However, this creates an extra wrapper when it's not needed. We should really
1944
- // detect whether this already was emitted and synchronously available. In that
1945
- // case we can refer to it synchronously and only make it lazy otherwise.
1946
- // We currently don't have a data structure that lets us see that though.
1947
- return serializeByValueID(existingId);
1948
- }
1949
- } else {
1950
- // This is the first time we've seen this object. We may never see it again
1951
- // so we'll inline it. Mark it as seen. If we see it again, we'll outline.
1952
- writtenObjects.set(value, -1);
1953
- }
1954
-
1955
- const element = value;
1956
-
1957
- const props = element.props;
1958
- let ref;
1959
-
1960
- {
1961
- ref = element.ref;
1962
- } // Attempt to render the Server Component.
1963
-
1964
-
1965
- return renderElement(request, task, element.type, // $FlowFixMe[incompatible-call] the key of an element is null | string
1966
- element.key, ref, props);
1967
- }
1968
-
1969
- case REACT_LAZY_TYPE:
1970
- {
1971
- // Reset the task's thenable state before continuing. If there was one, it was
1972
- // from suspending the lazy before.
1973
- task.thenableState = null;
1974
- const lazy = value;
1975
- const payload = lazy._payload;
1976
- const init = lazy._init;
1977
- const resolvedModel = init(payload);
1978
-
1979
- return renderModelDestructive(request, task, emptyRoot, '', resolvedModel);
1980
- }
1981
- }
1982
1956
 
1983
1957
  if (isClientReference(value)) {
1984
- return serializeClientReference(request, parent, parentPropertyName, value);
1958
+ return serializeClientReference(request, parent, key, value);
1985
1959
  }
1986
1960
 
1987
1961
  const writtenObjects = request.writtenObjects;
@@ -2001,20 +1975,20 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2001
1975
  // or a Promise type. Either of which can be represented by a Promise.
2002
1976
 
2003
1977
 
2004
- const promiseId = serializeThenable(request, task, value);
1978
+ const promiseId = serializeThenable(request, value);
2005
1979
  writtenObjects.set(value, promiseId);
2006
1980
  return serializePromiseID(promiseId);
2007
1981
  }
2008
1982
 
2009
1983
  if (existingId !== undefined) {
2010
- if (modelRoot === value) {
2011
- // This is the ID we're currently emitting so we need to write it
2012
- // once but if we discover it again, we refer to it by id.
2013
- modelRoot = null;
2014
- } else if (existingId === -1) {
1984
+ if (existingId === -1) {
2015
1985
  // Seen but not yet outlined.
2016
1986
  const newId = outlineModel(request, value);
2017
1987
  return serializeByValueID(newId);
1988
+ } else if (modelRoot === value) {
1989
+ // This is the ID we're currently emitting so we need to write it
1990
+ // once but if we discover it again, we refer to it by id.
1991
+ modelRoot = null;
2018
1992
  } else {
2019
1993
  // We've already emitted this as an outlined object, so we can
2020
1994
  // just refer to that by its existing ID.
@@ -2027,7 +2001,8 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2027
2001
  }
2028
2002
 
2029
2003
  if (isArray(value)) {
2030
- return renderFragment(request, task, value);
2004
+ // $FlowFixMe[incompatible-return]
2005
+ return value;
2031
2006
  }
2032
2007
 
2033
2008
  if (value instanceof Map) {
@@ -2041,7 +2016,7 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2041
2016
  const iteratorFn = getIteratorFn(value);
2042
2017
 
2043
2018
  if (iteratorFn) {
2044
- return renderFragment(request, task, Array.from(value));
2019
+ return Array.from(value);
2045
2020
  } // Verify that this is a simple plain object.
2046
2021
 
2047
2022
 
@@ -2061,7 +2036,7 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2061
2036
  if (value[value.length - 1] === 'Z') {
2062
2037
  // Possibly a Date, whose toJSON automatically calls toISOString
2063
2038
  // $FlowFixMe[incompatible-use]
2064
- const originalValue = parent[parentPropertyName];
2039
+ const originalValue = parent[key];
2065
2040
 
2066
2041
  if (originalValue instanceof Date) {
2067
2042
  return serializeDateFromDateJSON(value);
@@ -2091,18 +2066,19 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2091
2066
  }
2092
2067
 
2093
2068
  if (typeof value === 'function') {
2069
+
2094
2070
  if (isClientReference(value)) {
2095
- return serializeClientReference(request, parent, parentPropertyName, value);
2071
+ return serializeClientReference(request, parent, key, value);
2096
2072
  }
2097
2073
 
2098
2074
  if (isServerReference(value)) {
2099
- return serializeServerReference(request, value);
2075
+ return serializeServerReference(request, parent, key, value);
2100
2076
  }
2101
2077
 
2102
- if (/^on[A-Z]/.test(parentPropertyName)) {
2103
- throw new Error('Event handlers cannot be passed to Client Component props.' + describeObjectForErrorMessage(parent, parentPropertyName) + '\nIf you need interactivity, consider converting part of this to a Client Component.');
2078
+ if (/^on[A-Z]/.test(key)) {
2079
+ throw new Error('Event handlers cannot be passed to Client Component props.' + describeObjectForErrorMessage(parent, key) + '\nIf you need interactivity, consider converting part of this to a Client Component.');
2104
2080
  } else {
2105
- throw new Error('Functions cannot be passed directly to Client Components ' + 'unless you explicitly expose it by marking it with "use server". ' + 'Or maybe you meant to call this function rather than return it.' + describeObjectForErrorMessage(parent, parentPropertyName));
2081
+ throw new Error('Functions cannot be passed directly to Client Components ' + 'unless you explicitly expose it by marking it with "use server".' + describeObjectForErrorMessage(parent, key));
2106
2082
  }
2107
2083
  }
2108
2084
 
@@ -2119,7 +2095,7 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2119
2095
 
2120
2096
  if (Symbol.for(name) !== value) {
2121
2097
  throw new Error('Only global symbols received from Symbol.for(...) can be passed to Client Components. ' + ("The symbol Symbol.for(" + // $FlowFixMe[incompatible-type] `description` might be undefined
2122
- value.description + ") cannot be found among global symbols.") + describeObjectForErrorMessage(parent, parentPropertyName));
2098
+ value.description + ") cannot be found among global symbols.") + describeObjectForErrorMessage(parent, key));
2123
2099
  }
2124
2100
 
2125
2101
  request.pendingChunks++;
@@ -2134,40 +2110,17 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value
2134
2110
  return serializeBigInt(value);
2135
2111
  }
2136
2112
 
2137
- throw new Error("Type " + typeof value + " is not supported in Client Component props." + describeObjectForErrorMessage(parent, parentPropertyName));
2113
+ throw new Error("Type " + typeof value + " is not supported in Client Component props." + describeObjectForErrorMessage(parent, key));
2138
2114
  }
2139
2115
 
2140
2116
  function logPostpone(request, reason) {
2141
- const prevRequest = currentRequest;
2142
- currentRequest = null;
2143
-
2144
- try {
2145
- const onPostpone = request.onPostpone;
2146
-
2147
- if (supportsRequestStorage) {
2148
- // Exit the request context while running callbacks.
2149
- requestStorage.run(undefined, onPostpone, reason);
2150
- }
2151
- } finally {
2152
- currentRequest = prevRequest;
2153
- }
2117
+ const onPostpone = request.onPostpone;
2118
+ onPostpone(reason);
2154
2119
  }
2155
2120
 
2156
2121
  function logRecoverableError(request, error) {
2157
- const prevRequest = currentRequest;
2158
- currentRequest = null;
2159
- let errorDigest;
2160
-
2161
- try {
2162
- const onError = request.onError;
2163
-
2164
- if (supportsRequestStorage) {
2165
- // Exit the request context while running callbacks.
2166
- errorDigest = requestStorage.run(undefined, onError, error);
2167
- }
2168
- } finally {
2169
- currentRequest = prevRequest;
2170
- }
2122
+ const onError = request.onError;
2123
+ const errorDigest = onError(error);
2171
2124
 
2172
2125
  if (errorDigest != null && typeof errorDigest !== 'string') {
2173
2126
  // eslint-disable-next-line react-internal/prod-error-codes
@@ -2237,54 +2190,62 @@ function emitSymbolChunk(request, id, name) {
2237
2190
  request.completedImportChunks.push(processedChunk);
2238
2191
  }
2239
2192
 
2240
- function emitModelChunk(request, id, json) {
2193
+ function emitModelChunk(request, id, model) {
2194
+ // Track the root so we know that we have to emit this object even though it
2195
+ // already has an ID. This is needed because we might see this object twice
2196
+ // in the same toJSON if it is cyclic.
2197
+ modelRoot = model; // $FlowFixMe[incompatible-type] stringify can return null
2198
+
2199
+ const json = stringify(model, request.toJSON);
2241
2200
  const row = id.toString(16) + ':' + json + '\n';
2242
2201
  const processedChunk = stringToChunk(row);
2243
2202
  request.completedRegularChunks.push(processedChunk);
2244
2203
  }
2245
2204
 
2246
- const emptyRoot = {};
2247
-
2248
2205
  function retryTask(request, task) {
2249
2206
  if (task.status !== PENDING$1) {
2250
2207
  // We completed this by other means before we had a chance to retry it.
2251
2208
  return;
2252
2209
  }
2253
2210
 
2211
+ switchContext(task.context);
2212
+
2254
2213
  try {
2255
- // Track the root so we know that we have to emit this object even though it
2256
- // already has an ID. This is needed because we might see this object twice
2257
- // in the same toJSON if it is cyclic.
2258
- modelRoot = task.model;
2214
+ let value = task.model;
2259
2215
 
2260
- if (false) ; // We call the destructive form that mutates this task. That way if something
2261
- // suspends again, we can reuse the same task instead of spawning a new one.
2216
+ if (typeof value === 'object' && value !== null && value.$$typeof === REACT_ELEMENT_TYPE) {
2217
+ request.writtenObjects.set(value, task.id); // TODO: Concatenate keys of parents onto children.
2262
2218
 
2219
+ const element = value; // When retrying a component, reuse the thenableState from the
2220
+ // previous attempt.
2263
2221
 
2264
- const resolvedModel = renderModelDestructive(request, task, emptyRoot, '', task.model);
2222
+ const prevThenableState = task.thenableState; // Attempt to render the Server Component.
2223
+ // Doing this here lets us reuse this same task if the next component
2224
+ // also suspends.
2265
2225
 
2266
- if (false) ; // Track the root again for the resolved object.
2226
+ task.model = value;
2227
+ value = attemptResolveElement(request, element.type, element.key, element.ref, element.props, prevThenableState); // Successfully finished this component. We're going to keep rendering
2228
+ // using the same task, but we reset its thenable state before continuing.
2267
2229
 
2230
+ task.thenableState = null; // Keep rendering and reuse the same task. This inner loop is separate
2231
+ // from the render above because we don't need to reset the thenable state
2232
+ // until the next time something suspends and retries.
2268
2233
 
2269
- modelRoot = resolvedModel; // The keyPath resets at any terminal child node.
2234
+ while (typeof value === 'object' && value !== null && value.$$typeof === REACT_ELEMENT_TYPE) {
2235
+ request.writtenObjects.set(value, task.id); // TODO: Concatenate keys of parents onto children.
2270
2236
 
2271
- task.keyPath = null;
2272
- task.implicitSlot = false;
2273
- let json;
2237
+ const nextElement = value;
2238
+ task.model = value;
2239
+ value = attemptResolveElement(request, nextElement.type, nextElement.key, nextElement.ref, nextElement.props, null);
2240
+ }
2241
+ } // Track that this object is outlined and has an id.
2274
2242
 
2275
- if (typeof resolvedModel === 'object' && resolvedModel !== null) {
2276
- // Object might contain unresolved values like additional elements.
2277
- // This is simulating what the JSON loop would do if this was part of it.
2278
- // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
2279
- json = stringify(resolvedModel, task.toJSON);
2280
- } else {
2281
- // If the value is a string, it means it's a terminal value and we already escaped it
2282
- // We don't need to escape it again so it's not passed the toJSON replacer.
2283
- // $FlowFixMe[incompatible-type] stringify can return null for undefined but we never do
2284
- json = stringify(resolvedModel);
2243
+
2244
+ if (typeof value === 'object' && value !== null) {
2245
+ request.writtenObjects.set(value, task.id);
2285
2246
  }
2286
2247
 
2287
- emitModelChunk(request, task.id, json);
2248
+ emitModelChunk(request, task.id, value);
2288
2249
  request.abortableTasks.delete(task);
2289
2250
  task.status = COMPLETED;
2290
2251
  } catch (thrownValue) {
@@ -2310,7 +2271,6 @@ function retryTask(request, task) {
2310
2271
  task.status = ERRORED$1;
2311
2272
  const digest = logRecoverableError(request, x);
2312
2273
  emitErrorChunk(request, task.id, digest);
2313
- } finally {
2314
2274
  }
2315
2275
  }
2316
2276
 
@@ -2516,6 +2476,11 @@ function abort(request, reason) {
2516
2476
  }
2517
2477
  }
2518
2478
 
2479
+ function importServerContexts(contexts) {
2480
+
2481
+ return rootContextSnapshot;
2482
+ }
2483
+
2519
2484
  function resolveServerReference(bundlerConfig, id) {
2520
2485
  const idx = id.lastIndexOf('#');
2521
2486
  const specifier = id.slice(0, idx);
@@ -3222,7 +3187,7 @@ function createCancelHandler(request, reason) {
3222
3187
  }
3223
3188
 
3224
3189
  function renderToPipeableStream(model, webpackMap, options) {
3225
- const request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined);
3190
+ const request = createRequest(model, webpackMap, options ? options.onError : undefined, options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined);
3226
3191
  let hasStartedFlowing = false;
3227
3192
  startWork(request);
3228
3193
  return {