react-dom 16.8.1 → 16.8.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 (34) hide show
  1. package/build-info.json +6 -6
  2. package/cjs/react-dom-server.browser.development.js +55 -34
  3. package/cjs/react-dom-server.browser.production.min.js +3 -3
  4. package/cjs/react-dom-server.node.development.js +55 -34
  5. package/cjs/react-dom-server.node.production.min.js +3 -3
  6. package/cjs/react-dom-test-utils.development.js +2 -2
  7. package/cjs/react-dom-test-utils.production.min.js +1 -1
  8. package/cjs/react-dom-unstable-fire.development.js +464 -139
  9. package/cjs/react-dom-unstable-fire.production.min.js +252 -251
  10. package/cjs/react-dom-unstable-fire.profiling.min.js +175 -173
  11. package/cjs/react-dom-unstable-fizz.browser.development.js +1 -1
  12. package/cjs/react-dom-unstable-fizz.browser.production.min.js +1 -1
  13. package/cjs/react-dom-unstable-fizz.node.development.js +1 -1
  14. package/cjs/react-dom-unstable-fizz.node.production.min.js +1 -1
  15. package/cjs/react-dom-unstable-native-dependencies.development.js +2 -2
  16. package/cjs/react-dom-unstable-native-dependencies.production.min.js +1 -1
  17. package/cjs/react-dom.development.js +464 -139
  18. package/cjs/react-dom.production.min.js +252 -251
  19. package/cjs/react-dom.profiling.min.js +175 -173
  20. package/package.json +2 -2
  21. package/umd/react-dom-server.browser.development.js +55 -34
  22. package/umd/react-dom-server.browser.production.min.js +20 -20
  23. package/umd/react-dom-test-utils.development.js +2 -2
  24. package/umd/react-dom-test-utils.production.min.js +1 -1
  25. package/umd/react-dom-unstable-fire.development.js +472 -139
  26. package/umd/react-dom-unstable-fire.production.min.js +208 -207
  27. package/umd/react-dom-unstable-fire.profiling.min.js +208 -208
  28. package/umd/react-dom-unstable-fizz.browser.development.js +1 -1
  29. package/umd/react-dom-unstable-fizz.browser.production.min.js +1 -1
  30. package/umd/react-dom-unstable-native-dependencies.development.js +2 -2
  31. package/umd/react-dom-unstable-native-dependencies.production.min.js +1 -1
  32. package/umd/react-dom.development.js +472 -139
  33. package/umd/react-dom.production.min.js +208 -207
  34. package/umd/react-dom.profiling.min.js +208 -208
@@ -1,4 +1,4 @@
1
- /** @license React v16.8.1
1
+ /** @license React v16.8.2
2
2
  * react-dom.development.js
3
3
  *
4
4
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -79,7 +79,7 @@ var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f)
79
79
  // invokeGuardedCallback uses a try-catch, all user exceptions are treated
80
80
  // like caught exceptions, and the DevTools won't pause unless the developer
81
81
  // takes the extra step of enabling pause on caught exceptions. This is
82
- // untintuitive, though, because even though React has caught the error, from
82
+ // unintuitive, though, because even though React has caught the error, from
83
83
  // the developer's perspective, the error is uncaught.
84
84
  //
85
85
  // To preserve the expected "Pause on exceptions" behavior, we don't use a
@@ -836,6 +836,7 @@ var MemoComponent = 14;
836
836
  var SimpleMemoComponent = 15;
837
837
  var LazyComponent = 16;
838
838
  var IncompleteClassComponent = 17;
839
+ var DehydratedSuspenseComponent = 18;
839
840
 
840
841
  var randomKey = Math.random().toString(36).slice(2);
841
842
  var internalInstanceKey = '__reactInternalInstance$' + randomKey;
@@ -2901,12 +2902,15 @@ var capitalize = function (token) {
2901
2902
  attributeName, 'http://www.w3.org/XML/1998/namespace');
2902
2903
  });
2903
2904
 
2904
- // Special case: this attribute exists both in HTML and SVG.
2905
- // Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2906
- // its React `tabIndex` name, like we do for attributes that exist only in HTML.
2907
- properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2908
- 'tabindex', // attributeName
2909
- null);
2905
+ // These attribute exists both in HTML and SVG.
2906
+ // The attribute name is case-sensitive in SVG so we can't just use
2907
+ // the React name like we do for attributes that exist only in HTML.
2908
+ ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
2909
+ properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
2910
+ attributeName.toLowerCase(), // attributeName
2911
+ null);
2912
+ } // attributeNamespace
2913
+ );
2910
2914
 
2911
2915
  /**
2912
2916
  * Get the value for a property on a node. Only used in DEV for SSR validation.
@@ -3250,7 +3254,7 @@ var enableProfilerTimer = true;
3250
3254
  var enableSchedulerTracing = true;
3251
3255
 
3252
3256
  // Only used in www builds.
3253
- // TODO: true? Here it might just be false.
3257
+ var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
3254
3258
 
3255
3259
  // Only used in www builds.
3256
3260
 
@@ -8710,8 +8714,16 @@ var unstable_now = _ReactInternals$Sched.unstable_now;
8710
8714
  var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
8711
8715
  var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
8712
8716
  var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
8717
+ var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
8718
+ var unstable_next = _ReactInternals$Sched.unstable_next;
8713
8719
  var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
8714
8720
  var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
8721
+ var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
8722
+ var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
8723
+ var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
8724
+ var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
8725
+ var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
8726
+ var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
8715
8727
 
8716
8728
  // Renderers that don't support persistence
8717
8729
  // can re-export everything from this module.
@@ -8736,6 +8748,9 @@ var SUPPRESS_HYDRATION_WARNING = void 0;
8736
8748
  SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8737
8749
  }
8738
8750
 
8751
+ var SUSPENSE_START_DATA = '$';
8752
+ var SUSPENSE_END_DATA = '/$';
8753
+
8739
8754
  var STYLE = 'style';
8740
8755
 
8741
8756
  var eventsEnabled = null;
@@ -8964,6 +8979,43 @@ function removeChildFromContainer(container, child) {
8964
8979
  }
8965
8980
  }
8966
8981
 
8982
+ function clearSuspenseBoundary(parentInstance, suspenseInstance) {
8983
+ var node = suspenseInstance;
8984
+ // Delete all nodes within this suspense boundary.
8985
+ // There might be nested nodes so we need to keep track of how
8986
+ // deep we are and only break out when we're back on top.
8987
+ var depth = 0;
8988
+ do {
8989
+ var nextNode = node.nextSibling;
8990
+ parentInstance.removeChild(node);
8991
+ if (nextNode && nextNode.nodeType === COMMENT_NODE) {
8992
+ var data = nextNode.data;
8993
+ if (data === SUSPENSE_END_DATA) {
8994
+ if (depth === 0) {
8995
+ parentInstance.removeChild(nextNode);
8996
+ return;
8997
+ } else {
8998
+ depth--;
8999
+ }
9000
+ } else if (data === SUSPENSE_START_DATA) {
9001
+ depth++;
9002
+ }
9003
+ }
9004
+ node = nextNode;
9005
+ } while (node);
9006
+ // TODO: Warn, we didn't find the end comment boundary.
9007
+ }
9008
+
9009
+ function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
9010
+ if (container.nodeType === COMMENT_NODE) {
9011
+ clearSuspenseBoundary(container.parentNode, suspenseInstance);
9012
+ } else if (container.nodeType === ELEMENT_NODE) {
9013
+ clearSuspenseBoundary(container, suspenseInstance);
9014
+ } else {
9015
+ // Document nodes should never contain suspense boundaries.
9016
+ }
9017
+ }
9018
+
8967
9019
  function hideInstance(instance) {
8968
9020
  // TODO: Does this work for all element types? What about MathML? Should we
8969
9021
  // pass host context to this method?
@@ -9009,10 +9061,19 @@ function canHydrateTextInstance(instance, text) {
9009
9061
  return instance;
9010
9062
  }
9011
9063
 
9064
+ function canHydrateSuspenseInstance(instance) {
9065
+ if (instance.nodeType !== COMMENT_NODE) {
9066
+ // Empty strings are not parsed by HTML so there won't be a correct match here.
9067
+ return null;
9068
+ }
9069
+ // This has now been refined to a suspense node.
9070
+ return instance;
9071
+ }
9072
+
9012
9073
  function getNextHydratableSibling(instance) {
9013
9074
  var node = instance.nextSibling;
9014
9075
  // Skip non-hydratable nodes.
9015
- while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
9076
+ while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) {
9016
9077
  node = node.nextSibling;
9017
9078
  }
9018
9079
  return node;
@@ -9021,7 +9082,7 @@ function getNextHydratableSibling(instance) {
9021
9082
  function getFirstHydratableChild(parentInstance) {
9022
9083
  var next = parentInstance.firstChild;
9023
9084
  // Skip non-hydratable nodes.
9024
- while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
9085
+ while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) {
9025
9086
  next = next.nextSibling;
9026
9087
  }
9027
9088
  return next;
@@ -9045,6 +9106,31 @@ function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9045
9106
  return diffHydratedText(textInstance, text);
9046
9107
  }
9047
9108
 
9109
+ function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
9110
+ var node = suspenseInstance.nextSibling;
9111
+ // Skip past all nodes within this suspense boundary.
9112
+ // There might be nested nodes so we need to keep track of how
9113
+ // deep we are and only break out when we're back on top.
9114
+ var depth = 0;
9115
+ while (node) {
9116
+ if (node.nodeType === COMMENT_NODE) {
9117
+ var data = node.data;
9118
+ if (data === SUSPENSE_END_DATA) {
9119
+ if (depth === 0) {
9120
+ return getNextHydratableSibling(node);
9121
+ } else {
9122
+ depth--;
9123
+ }
9124
+ } else if (data === SUSPENSE_START_DATA) {
9125
+ depth++;
9126
+ }
9127
+ }
9128
+ node = node.nextSibling;
9129
+ }
9130
+ // TODO: Warn, we didn't find the end comment boundary.
9131
+ return null;
9132
+ }
9133
+
9048
9134
  function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9049
9135
  {
9050
9136
  warnForUnmatchedText(textInstance, text);
@@ -9061,6 +9147,8 @@ function didNotHydrateContainerInstance(parentContainer, instance) {
9061
9147
  {
9062
9148
  if (instance.nodeType === ELEMENT_NODE) {
9063
9149
  warnForDeletedHydratableElement(parentContainer, instance);
9150
+ } else if (instance.nodeType === COMMENT_NODE) {
9151
+ // TODO: warnForDeletedHydratableSuspenseBoundary
9064
9152
  } else {
9065
9153
  warnForDeletedHydratableText(parentContainer, instance);
9066
9154
  }
@@ -9071,6 +9159,8 @@ function didNotHydrateInstance(parentType, parentProps, parentInstance, instance
9071
9159
  if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9072
9160
  if (instance.nodeType === ELEMENT_NODE) {
9073
9161
  warnForDeletedHydratableElement(parentInstance, instance);
9162
+ } else if (instance.nodeType === COMMENT_NODE) {
9163
+ // TODO: warnForDeletedHydratableSuspenseBoundary
9074
9164
  } else {
9075
9165
  warnForDeletedHydratableText(parentInstance, instance);
9076
9166
  }
@@ -9089,6 +9179,8 @@ function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9089
9179
  }
9090
9180
  }
9091
9181
 
9182
+
9183
+
9092
9184
  function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9093
9185
  if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9094
9186
  warnForInsertedHydratedElement(parentInstance, type, props);
@@ -9101,6 +9193,12 @@ function didNotFindHydratableTextInstance(parentType, parentProps, parentInstanc
9101
9193
  }
9102
9194
  }
9103
9195
 
9196
+ function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
9197
+ if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9198
+ // TODO: warnForInsertedHydratedSuspense(parentInstance);
9199
+ }
9200
+ }
9201
+
9104
9202
  // Prefix measurements so that it's possible to filter them.
9105
9203
  // Longer prefixes are hard to read in DevTools.
9106
9204
  var reactEmoji = '\u269B';
@@ -9356,7 +9454,7 @@ function stopFailedWorkTimer(fiber) {
9356
9454
  return;
9357
9455
  }
9358
9456
  fiber._debugIsCurrentlyTiming = false;
9359
- var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9457
+ var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9360
9458
  endFiberMark(fiber, null, warning);
9361
9459
  }
9362
9460
  }
@@ -12176,7 +12274,7 @@ function ChildReconciler(shouldTrackSideEffects) {
12176
12274
  }
12177
12275
 
12178
12276
  function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12179
- // This algorithm can't optimize by searching from boths ends since we
12277
+ // This algorithm can't optimize by searching from both ends since we
12180
12278
  // don't have backpointers on fibers. I'm trying to see how far we can get
12181
12279
  // with that model. If it ends up not being worth the tradeoffs, we can
12182
12280
  // add it later.
@@ -12990,9 +13088,6 @@ function mountWorkInProgressHook() {
12990
13088
 
12991
13089
  {
12992
13090
  hook._debugType = currentHookNameInDev;
12993
- if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
12994
- warning$1(false, '%s: Rendered more hooks than during the previous render. This is ' + 'not currently supported and may lead to unexpected behavior.', getComponentName(currentlyRenderingFiber$1.type));
12995
- }
12996
13091
  }
12997
13092
  if (workInProgressHook === null) {
12998
13093
  // This is the first hook in the list
@@ -13355,7 +13450,7 @@ function mountImperativeHandle(ref, create, deps) {
13355
13450
  }
13356
13451
 
13357
13452
  // TODO: If deps are provided, should we skip comparing the ref itself?
13358
- var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13453
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13359
13454
 
13360
13455
  return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13361
13456
  }
@@ -13366,7 +13461,7 @@ function updateImperativeHandle(ref, create, deps) {
13366
13461
  }
13367
13462
 
13368
13463
  // TODO: If deps are provided, should we skip comparing the ref itself?
13369
- var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13464
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13370
13465
 
13371
13466
  return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13372
13467
  }
@@ -13433,7 +13528,7 @@ function updateMemo(nextCreate, deps) {
13433
13528
  var shouldWarnForUnbatchedSetState = false;
13434
13529
 
13435
13530
  {
13436
- // jest isnt' a 'global', it's just exposed to tests via a wrapped function
13531
+ // jest isn't a 'global', it's just exposed to tests via a wrapped function
13437
13532
  // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13438
13533
  // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13439
13534
  if ('undefined' !== typeof jest) {
@@ -13923,6 +14018,18 @@ function enterHydrationState(fiber) {
13923
14018
  return true;
13924
14019
  }
13925
14020
 
14021
+ function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
14022
+ if (!supportsHydration) {
14023
+ return false;
14024
+ }
14025
+
14026
+ var suspenseInstance = fiber.stateNode;
14027
+ nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
14028
+ popToNextHostParent(fiber);
14029
+ isHydrating = true;
14030
+ return true;
14031
+ }
14032
+
13926
14033
  function deleteHydratableInstance(returnFiber, instance) {
13927
14034
  {
13928
14035
  switch (returnFiber.tag) {
@@ -13969,6 +14076,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
13969
14076
  case HostText:
13970
14077
  var text = fiber.pendingProps;
13971
14078
  didNotFindHydratableContainerTextInstance(parentContainer, text);
14079
+ break;
14080
+ case SuspenseComponent:
14081
+
13972
14082
  break;
13973
14083
  }
13974
14084
  break;
@@ -13988,6 +14098,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
13988
14098
  var _text = fiber.pendingProps;
13989
14099
  didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
13990
14100
  break;
14101
+ case SuspenseComponent:
14102
+ didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
14103
+ break;
13991
14104
  }
13992
14105
  break;
13993
14106
  }
@@ -14020,6 +14133,19 @@ function tryHydrate(fiber, nextInstance) {
14020
14133
  }
14021
14134
  return false;
14022
14135
  }
14136
+ case SuspenseComponent:
14137
+ {
14138
+ if (enableSuspenseServerRenderer) {
14139
+ var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14140
+ if (suspenseInstance !== null) {
14141
+ // Downgrade the tag to a dehydrated component until we've hydrated it.
14142
+ fiber.tag = DehydratedSuspenseComponent;
14143
+ fiber.stateNode = suspenseInstance;
14144
+ return true;
14145
+ }
14146
+ }
14147
+ return false;
14148
+ }
14023
14149
  default:
14024
14150
  return false;
14025
14151
  }
@@ -14113,9 +14239,18 @@ function prepareToHydrateHostTextInstance(fiber) {
14113
14239
  return shouldUpdate;
14114
14240
  }
14115
14241
 
14242
+ function skipPastDehydratedSuspenseInstance(fiber) {
14243
+ if (!supportsHydration) {
14244
+ invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14245
+ }
14246
+ var suspenseInstance = fiber.stateNode;
14247
+ !suspenseInstance ? invariant(false, 'Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.') : void 0;
14248
+ nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14249
+ }
14250
+
14116
14251
  function popToNextHostParent(fiber) {
14117
14252
  var parent = fiber.return;
14118
- while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
14253
+ while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14119
14254
  parent = parent.return;
14120
14255
  }
14121
14256
  hydrationParentFiber = parent;
@@ -14223,6 +14358,10 @@ function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildre
14223
14358
  }
14224
14359
 
14225
14360
  function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14361
+ // TODO: current can be non-null here even if the component
14362
+ // hasn't yet mounted. This happens after the first render suspends.
14363
+ // We'll need to figure out if this is fine or can cause issues.
14364
+
14226
14365
  {
14227
14366
  if (workInProgress.type !== workInProgress.elementType) {
14228
14367
  // Lazy component props can't be validated in createElement
@@ -14328,6 +14467,10 @@ function updateMemoComponent(current$$1, workInProgress, Component, nextProps, u
14328
14467
  }
14329
14468
 
14330
14469
  function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14470
+ // TODO: current can be non-null here even if the component
14471
+ // hasn't yet mounted. This happens when the inner render suspends.
14472
+ // We'll need to figure out if this is fine or can cause issues.
14473
+
14331
14474
  {
14332
14475
  if (workInProgress.type !== workInProgress.elementType) {
14333
14476
  // Lazy component props can't be validated in createElement
@@ -14951,6 +15094,18 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
14951
15094
  // children -- we skip over the primary children entirely.
14952
15095
  var next = void 0;
14953
15096
  if (current$$1 === null) {
15097
+ if (enableSuspenseServerRenderer) {
15098
+ // If we're currently hydrating, try to hydrate this boundary.
15099
+ // But only if this has a fallback.
15100
+ if (nextProps.fallback !== undefined) {
15101
+ tryToClaimNextHydratableInstance(workInProgress);
15102
+ // This could've changed the tag if this was a dehydrated suspense component.
15103
+ if (workInProgress.tag === DehydratedSuspenseComponent) {
15104
+ return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
15105
+ }
15106
+ }
15107
+ }
15108
+
14954
15109
  // This is the initial mount. This branch is pretty simple because there's
14955
15110
  // no previous state that needs to be preserved.
14956
15111
  if (nextDidTimeout) {
@@ -15102,6 +15257,65 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
15102
15257
  return next;
15103
15258
  }
15104
15259
 
15260
+ function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15261
+ if (current$$1 === null) {
15262
+ // During the first pass, we'll bail out and not drill into the children.
15263
+ // Instead, we'll leave the content in place and try to hydrate it later.
15264
+ workInProgress.expirationTime = Never;
15265
+ return null;
15266
+ }
15267
+ // We use childExpirationTime to indicate that a child might depend on context, so if
15268
+ // any context has changed, we need to treat is as if the input might have changed.
15269
+ var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15270
+ if (didReceiveUpdate || hasContextChanged$$1) {
15271
+ // This boundary has changed since the first render. This means that we are now unable to
15272
+ // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15273
+ // during this render we can't. Instead, we're going to delete the whole subtree and
15274
+ // instead inject a new real Suspense boundary to take its place, which may render content
15275
+ // or fallback. The real Suspense boundary will suspend for a while so we have some time
15276
+ // to ensure it can produce real content, but all state and pending events will be lost.
15277
+
15278
+ // Detach from the current dehydrated boundary.
15279
+ current$$1.alternate = null;
15280
+ workInProgress.alternate = null;
15281
+
15282
+ // Insert a deletion in the effect list.
15283
+ var returnFiber = workInProgress.return;
15284
+ !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15285
+ var last = returnFiber.lastEffect;
15286
+ if (last !== null) {
15287
+ last.nextEffect = current$$1;
15288
+ returnFiber.lastEffect = current$$1;
15289
+ } else {
15290
+ returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15291
+ }
15292
+ current$$1.nextEffect = null;
15293
+ current$$1.effectTag = Deletion;
15294
+
15295
+ // Upgrade this work in progress to a real Suspense component.
15296
+ workInProgress.tag = SuspenseComponent;
15297
+ workInProgress.stateNode = null;
15298
+ workInProgress.memoizedState = null;
15299
+ // This is now an insertion.
15300
+ workInProgress.effectTag |= Placement;
15301
+ // Retry as a real Suspense component.
15302
+ return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15303
+ }
15304
+ if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15305
+ // This is the first attempt.
15306
+ reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15307
+ var nextProps = workInProgress.pendingProps;
15308
+ var nextChildren = nextProps.children;
15309
+ workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15310
+ return workInProgress.child;
15311
+ } else {
15312
+ // Something suspended. Leave the existing children in place.
15313
+ // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15314
+ workInProgress.child = null;
15315
+ return null;
15316
+ }
15317
+ }
15318
+
15105
15319
  function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15106
15320
  pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15107
15321
  var nextChildren = workInProgress.pendingProps;
@@ -15313,6 +15527,16 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
15313
15527
  }
15314
15528
  break;
15315
15529
  }
15530
+ case DehydratedSuspenseComponent:
15531
+ {
15532
+ if (enableSuspenseServerRenderer) {
15533
+ // We know that this component will suspend again because if it has
15534
+ // been unsuspended it has committed as a regular Suspense component.
15535
+ // If it needs to be retried, it should have work scheduled on it.
15536
+ workInProgress.effectTag |= DidCapture;
15537
+ break;
15538
+ }
15539
+ }
15316
15540
  }
15317
15541
  return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15318
15542
  }
@@ -15404,9 +15628,15 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
15404
15628
  var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15405
15629
  return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15406
15630
  }
15407
- default:
15408
- invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15631
+ case DehydratedSuspenseComponent:
15632
+ {
15633
+ if (enableSuspenseServerRenderer) {
15634
+ return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15635
+ }
15636
+ break;
15637
+ }
15409
15638
  }
15639
+ invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15410
15640
  }
15411
15641
 
15412
15642
  var valueCursor = createCursor(null);
@@ -15495,6 +15725,28 @@ function calculateChangedBits(context, newValue, oldValue) {
15495
15725
  }
15496
15726
  }
15497
15727
 
15728
+ function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15729
+ // Update the child expiration time of all the ancestors, including
15730
+ // the alternates.
15731
+ var node = parent;
15732
+ while (node !== null) {
15733
+ var alternate = node.alternate;
15734
+ if (node.childExpirationTime < renderExpirationTime) {
15735
+ node.childExpirationTime = renderExpirationTime;
15736
+ if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15737
+ alternate.childExpirationTime = renderExpirationTime;
15738
+ }
15739
+ } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15740
+ alternate.childExpirationTime = renderExpirationTime;
15741
+ } else {
15742
+ // Neither alternate was updated, which means the rest of the
15743
+ // ancestor path already has sufficient priority.
15744
+ break;
15745
+ }
15746
+ node = node.return;
15747
+ }
15748
+ }
15749
+
15498
15750
  function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15499
15751
  var fiber = workInProgress.child;
15500
15752
  if (fiber !== null) {
@@ -15533,25 +15785,8 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
15533
15785
  if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15534
15786
  alternate.expirationTime = renderExpirationTime;
15535
15787
  }
15536
- // Update the child expiration time of all the ancestors, including
15537
- // the alternates.
15538
- var node = fiber.return;
15539
- while (node !== null) {
15540
- alternate = node.alternate;
15541
- if (node.childExpirationTime < renderExpirationTime) {
15542
- node.childExpirationTime = renderExpirationTime;
15543
- if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15544
- alternate.childExpirationTime = renderExpirationTime;
15545
- }
15546
- } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15547
- alternate.childExpirationTime = renderExpirationTime;
15548
- } else {
15549
- // Neither alternate was updated, which means the rest of the
15550
- // ancestor path already has sufficient priority.
15551
- break;
15552
- }
15553
- node = node.return;
15554
- }
15788
+
15789
+ scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15555
15790
 
15556
15791
  // Mark the expiration time on the list, too.
15557
15792
  if (list.expirationTime < renderExpirationTime) {
@@ -15567,6 +15802,23 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
15567
15802
  } else if (fiber.tag === ContextProvider) {
15568
15803
  // Don't scan deeper if this is a matching provider
15569
15804
  nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15805
+ } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15806
+ // If a dehydrated suspense component is in this subtree, we don't know
15807
+ // if it will have any context consumers in it. The best we can do is
15808
+ // mark it as having updates on its children.
15809
+ if (fiber.expirationTime < renderExpirationTime) {
15810
+ fiber.expirationTime = renderExpirationTime;
15811
+ }
15812
+ var _alternate = fiber.alternate;
15813
+ if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15814
+ _alternate.expirationTime = renderExpirationTime;
15815
+ }
15816
+ // This is intentionally passing this fiber as the parent
15817
+ // because we want to schedule this fiber as having work
15818
+ // on its children. We'll use the childExpirationTime on
15819
+ // this fiber to indicate that a context has changed.
15820
+ scheduleWorkOnParentPath(fiber, renderExpirationTime);
15821
+ nextFiber = fiber.sibling;
15570
15822
  } else {
15571
15823
  // Traverse down.
15572
15824
  nextFiber = fiber.child;
@@ -16690,6 +16942,26 @@ function completeWork(current, workInProgress, renderExpirationTime) {
16690
16942
  }
16691
16943
  break;
16692
16944
  }
16945
+ case DehydratedSuspenseComponent:
16946
+ {
16947
+ if (enableSuspenseServerRenderer) {
16948
+ if (current === null) {
16949
+ var _wasHydrated2 = popHydrationState(workInProgress);
16950
+ !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
16951
+ skipPastDehydratedSuspenseInstance(workInProgress);
16952
+ } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
16953
+ // This boundary did not suspend so it's now hydrated.
16954
+ // To handle any future suspense cases, we're going to now upgrade it
16955
+ // to a Suspense component. We detach it from the existing current fiber.
16956
+ current.alternate = null;
16957
+ workInProgress.alternate = null;
16958
+ workInProgress.tag = SuspenseComponent;
16959
+ workInProgress.memoizedState = null;
16960
+ workInProgress.stateNode = null;
16961
+ }
16962
+ }
16963
+ break;
16964
+ }
16693
16965
  default:
16694
16966
  invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16695
16967
  }
@@ -16780,7 +17052,7 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16780
17052
  didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16781
17053
  }
16782
17054
 
16783
- var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17055
+ var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
16784
17056
 
16785
17057
  function logError(boundary, errorInfo) {
16786
17058
  var source = errorInfo.source;
@@ -17093,7 +17365,7 @@ function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpir
17093
17365
 
17094
17366
  function hideOrUnhideAllChildren(finishedWork, isHidden) {
17095
17367
  if (supportsMutation) {
17096
- // We only have the top Fiber that was inserted but we need recurse down its
17368
+ // We only have the top Fiber that was inserted but we need to recurse down its
17097
17369
  var node = finishedWork;
17098
17370
  while (true) {
17099
17371
  if (node.tag === HostComponent) {
@@ -17361,7 +17633,7 @@ function getHostSibling(fiber) {
17361
17633
  }
17362
17634
  node.sibling.return = node.return;
17363
17635
  node = node.sibling;
17364
- while (node.tag !== HostComponent && node.tag !== HostText) {
17636
+ while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17365
17637
  // If it is not host node and, we might have a host node inside it.
17366
17638
  // Try to search down until we find one.
17367
17639
  if (node.effectTag & Placement) {
@@ -17421,7 +17693,7 @@ function commitPlacement(finishedWork) {
17421
17693
  }
17422
17694
 
17423
17695
  var before = getHostSibling(finishedWork);
17424
- // We only have the top Fiber that was inserted but we need recurse down its
17696
+ // We only have the top Fiber that was inserted but we need to recurse down its
17425
17697
  // children to find all the terminal nodes.
17426
17698
  var node = finishedWork;
17427
17699
  while (true) {
@@ -17463,7 +17735,7 @@ function commitPlacement(finishedWork) {
17463
17735
  }
17464
17736
 
17465
17737
  function unmountHostComponents(current$$1) {
17466
- // We only have the top Fiber that was deleted but we need recurse down its
17738
+ // We only have the top Fiber that was deleted but we need to recurse down its
17467
17739
  var node = current$$1;
17468
17740
 
17469
17741
  // Each iteration, currentParent is populated with node's host parent if not
@@ -17508,13 +17780,20 @@ function unmountHostComponents(current$$1) {
17508
17780
  removeChild(currentParent, node.stateNode);
17509
17781
  }
17510
17782
  // Don't visit children because we already visited them.
17783
+ } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17784
+ // Delete the dehydrated suspense boundary and all of its content.
17785
+ if (currentParentIsContainer) {
17786
+ clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17787
+ } else {
17788
+ clearSuspenseBoundary(currentParent, node.stateNode);
17789
+ }
17511
17790
  } else if (node.tag === HostPortal) {
17512
- // When we go into a portal, it becomes the parent to remove from.
17513
- // We will reassign it back when we pop the portal on the way up.
17514
- currentParent = node.stateNode.containerInfo;
17515
- currentParentIsContainer = true;
17516
- // Visit children because portals might contain host components.
17517
17791
  if (node.child !== null) {
17792
+ // When we go into a portal, it becomes the parent to remove from.
17793
+ // We will reassign it back when we pop the portal on the way up.
17794
+ currentParent = node.stateNode.containerInfo;
17795
+ currentParentIsContainer = true;
17796
+ // Visit children because portals might contain host components.
17518
17797
  node.child.return = node;
17519
17798
  node = node.child;
17520
17799
  continue;
@@ -17664,7 +17943,7 @@ function commitWork(current$$1, finishedWork) {
17664
17943
  finishedWork.updateQueue = null;
17665
17944
  var retryCache = finishedWork.stateNode;
17666
17945
  if (retryCache === null) {
17667
- retryCache = finishedWork.stateNode = new PossiblyWeakSet();
17946
+ retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
17668
17947
  }
17669
17948
  thenables.forEach(function (thenable) {
17670
17949
  // Memoize using the boundary fiber to prevent redundant listeners.
@@ -17699,6 +17978,7 @@ function commitResetTextContent(current$$1) {
17699
17978
  resetTextContent(current$$1.stateNode);
17700
17979
  }
17701
17980
 
17981
+ var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17702
17982
  var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17703
17983
 
17704
17984
  function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
@@ -17757,6 +18037,34 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17757
18037
  return update;
17758
18038
  }
17759
18039
 
18040
+ function attachPingListener(root, renderExpirationTime, thenable) {
18041
+ // Attach a listener to the promise to "ping" the root and retry. But
18042
+ // only if one does not already exist for the current render expiration
18043
+ // time (which acts like a "thread ID" here).
18044
+ var pingCache = root.pingCache;
18045
+ var threadIDs = void 0;
18046
+ if (pingCache === null) {
18047
+ pingCache = root.pingCache = new PossiblyWeakMap();
18048
+ threadIDs = new Set();
18049
+ pingCache.set(thenable, threadIDs);
18050
+ } else {
18051
+ threadIDs = pingCache.get(thenable);
18052
+ if (threadIDs === undefined) {
18053
+ threadIDs = new Set();
18054
+ pingCache.set(thenable, threadIDs);
18055
+ }
18056
+ }
18057
+ if (!threadIDs.has(renderExpirationTime)) {
18058
+ // Memoize using the thread ID to prevent redundant listeners.
18059
+ threadIDs.add(renderExpirationTime);
18060
+ var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
18061
+ if (enableSchedulerTracing) {
18062
+ ping = unstable_wrap(ping);
18063
+ }
18064
+ thenable.then(ping, ping);
18065
+ }
18066
+ }
18067
+
17760
18068
  function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17761
18069
  // The source fiber did not complete.
17762
18070
  sourceFiber.effectTag |= Incomplete;
@@ -17798,6 +18106,9 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17798
18106
  }
17799
18107
  }
17800
18108
  }
18109
+ // If there is a DehydratedSuspenseComponent we don't have to do anything because
18110
+ // if something suspends inside it, we will simply leave that as dehydrated. It
18111
+ // will never timeout.
17801
18112
  _workInProgress = _workInProgress.return;
17802
18113
  } while (_workInProgress !== null);
17803
18114
 
@@ -17861,31 +18172,7 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17861
18172
  // Confirmed that the boundary is in a concurrent mode tree. Continue
17862
18173
  // with the normal suspend path.
17863
18174
 
17864
- // Attach a listener to the promise to "ping" the root and retry. But
17865
- // only if one does not already exist for the current render expiration
17866
- // time (which acts like a "thread ID" here).
17867
- var pingCache = root.pingCache;
17868
- var threadIDs = void 0;
17869
- if (pingCache === null) {
17870
- pingCache = root.pingCache = new PossiblyWeakMap();
17871
- threadIDs = new Set();
17872
- pingCache.set(thenable, threadIDs);
17873
- } else {
17874
- threadIDs = pingCache.get(thenable);
17875
- if (threadIDs === undefined) {
17876
- threadIDs = new Set();
17877
- pingCache.set(thenable, threadIDs);
17878
- }
17879
- }
17880
- if (!threadIDs.has(renderExpirationTime)) {
17881
- // Memoize using the thread ID to prevent redundant listeners.
17882
- threadIDs.add(renderExpirationTime);
17883
- var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17884
- if (enableSchedulerTracing) {
17885
- ping = unstable_wrap(ping);
17886
- }
17887
- thenable.then(ping, ping);
17888
- }
18175
+ attachPingListener(root, renderExpirationTime, thenable);
17889
18176
 
17890
18177
  var absoluteTimeoutMs = void 0;
17891
18178
  if (earliestTimeoutMs === -1) {
@@ -17917,6 +18204,29 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17917
18204
  // whole tree.
17918
18205
  renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
17919
18206
 
18207
+ _workInProgress.effectTag |= ShouldCapture;
18208
+ _workInProgress.expirationTime = renderExpirationTime;
18209
+ return;
18210
+ } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18211
+ attachPingListener(root, renderExpirationTime, thenable);
18212
+
18213
+ // Since we already have a current fiber, we can eagerly add a retry listener.
18214
+ var retryCache = _workInProgress.memoizedState;
18215
+ if (retryCache === null) {
18216
+ retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18217
+ var _current = _workInProgress.alternate;
18218
+ !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18219
+ _current.memoizedState = retryCache;
18220
+ }
18221
+ // Memoize using the boundary fiber to prevent redundant listeners.
18222
+ if (!retryCache.has(thenable)) {
18223
+ retryCache.add(thenable);
18224
+ var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18225
+ if (enableSchedulerTracing) {
18226
+ retry = unstable_wrap(retry);
18227
+ }
18228
+ thenable.then(retry, retry);
18229
+ }
17920
18230
  _workInProgress.effectTag |= ShouldCapture;
17921
18231
  _workInProgress.expirationTime = renderExpirationTime;
17922
18232
  return;
@@ -17994,6 +18304,7 @@ function unwindWork(workInProgress, renderExpirationTime) {
17994
18304
  }
17995
18305
  case HostComponent:
17996
18306
  {
18307
+ // TODO: popHydrationState
17997
18308
  popHostContext(workInProgress);
17998
18309
  return null;
17999
18310
  }
@@ -18007,6 +18318,19 @@ function unwindWork(workInProgress, renderExpirationTime) {
18007
18318
  }
18008
18319
  return null;
18009
18320
  }
18321
+ case DehydratedSuspenseComponent:
18322
+ {
18323
+ if (enableSuspenseServerRenderer) {
18324
+ // TODO: popHydrationState
18325
+ var _effectTag3 = workInProgress.effectTag;
18326
+ if (_effectTag3 & ShouldCapture) {
18327
+ workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18328
+ // Captured a suspense effect. Re-render the boundary.
18329
+ return workInProgress;
18330
+ }
18331
+ }
18332
+ return null;
18333
+ }
18010
18334
  case HostPortal:
18011
18335
  popHostContainer(workInProgress);
18012
18336
  return null;
@@ -18104,11 +18428,6 @@ if (enableSchedulerTracing) {
18104
18428
  // Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18105
18429
  var lastUniqueAsyncExpiration = Sync - 1;
18106
18430
 
18107
- // Represents the expiration time that incoming updates should use. (If this
18108
- // is NoWork, use the default strategy: async updates in async mode, sync
18109
- // updates in sync mode.)
18110
- var expirationContext = NoWork;
18111
-
18112
18431
  var isWorking = false;
18113
18432
 
18114
18433
  // The next work in progress fiber that we're currently working on.
@@ -18404,6 +18723,10 @@ function commitPassiveEffects(root, firstEffect) {
18404
18723
  if (rootExpirationTime !== NoWork) {
18405
18724
  requestWork(root, rootExpirationTime);
18406
18725
  }
18726
+ // Flush any sync work that was scheduled by effects
18727
+ if (!isBatchingUpdates && !isRendering) {
18728
+ performSyncWork();
18729
+ }
18407
18730
  }
18408
18731
 
18409
18732
  function isAlreadyFailedLegacyErrorBoundary(instance) {
@@ -18578,7 +18901,9 @@ function commitRoot(root, finishedWork) {
18578
18901
  // here because that code is still in flux.
18579
18902
  callback = unstable_wrap(callback);
18580
18903
  }
18581
- passiveEffectCallbackHandle = schedulePassiveEffects(callback);
18904
+ passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () {
18905
+ return schedulePassiveEffects(callback);
18906
+ });
18582
18907
  passiveEffectCallback = callback;
18583
18908
  }
18584
18909
 
@@ -19167,7 +19492,7 @@ function renderRoot(root, isYieldy) {
19167
19492
  return;
19168
19493
  } else if (
19169
19494
  // There's no lower priority work, but we're rendering asynchronously.
19170
- // Synchronsouly attempt to render the same level one more time. This is
19495
+ // Synchronously attempt to render the same level one more time. This is
19171
19496
  // similar to a suspend, but without a timeout because we're not waiting
19172
19497
  // for a promise to resolve.
19173
19498
  !root.didError && isYieldy) {
@@ -19272,49 +19597,50 @@ function computeUniqueAsyncExpiration() {
19272
19597
  }
19273
19598
 
19274
19599
  function computeExpirationForFiber(currentTime, fiber) {
19600
+ var priorityLevel = unstable_getCurrentPriorityLevel();
19601
+
19275
19602
  var expirationTime = void 0;
19276
- if (expirationContext !== NoWork) {
19277
- // An explicit expiration context was set;
19278
- expirationTime = expirationContext;
19279
- } else if (isWorking) {
19280
- if (isCommitting$1) {
19281
- // Updates that occur during the commit phase should have sync priority
19282
- // by default.
19283
- expirationTime = Sync;
19284
- } else {
19285
- // Updates during the render phase should expire at the same time as
19286
- // the work that is being rendered.
19287
- expirationTime = nextRenderExpirationTime;
19288
- }
19603
+ if ((fiber.mode & ConcurrentMode) === NoContext) {
19604
+ // Outside of concurrent mode, updates are always synchronous.
19605
+ expirationTime = Sync;
19606
+ } else if (isWorking && !isCommitting$1) {
19607
+ // During render phase, updates expire during as the current render.
19608
+ expirationTime = nextRenderExpirationTime;
19289
19609
  } else {
19290
- // No explicit expiration context was set, and we're not currently
19291
- // performing work. Calculate a new expiration time.
19292
- if (fiber.mode & ConcurrentMode) {
19293
- if (isBatchingInteractiveUpdates) {
19294
- // This is an interactive update
19610
+ switch (priorityLevel) {
19611
+ case unstable_ImmediatePriority:
19612
+ expirationTime = Sync;
19613
+ break;
19614
+ case unstable_UserBlockingPriority:
19295
19615
  expirationTime = computeInteractiveExpiration(currentTime);
19296
- } else {
19297
- // This is an async update
19616
+ break;
19617
+ case unstable_NormalPriority:
19618
+ // This is a normal, concurrent update
19298
19619
  expirationTime = computeAsyncExpiration(currentTime);
19299
- }
19300
- // If we're in the middle of rendering a tree, do not update at the same
19301
- // expiration time that is already rendering.
19302
- if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19303
- expirationTime -= 1;
19304
- }
19305
- } else {
19306
- // This is a sync update
19307
- expirationTime = Sync;
19620
+ break;
19621
+ case unstable_LowPriority:
19622
+ case unstable_IdlePriority:
19623
+ expirationTime = Never;
19624
+ break;
19625
+ default:
19626
+ invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19308
19627
  }
19309
- }
19310
- if (isBatchingInteractiveUpdates) {
19311
- // This is an interactive update. Keep track of the lowest pending
19312
- // interactive expiration time. This allows us to synchronously flush
19313
- // all interactive updates when needed.
19314
- if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
19315
- lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19628
+
19629
+ // If we're in the middle of rendering a tree, do not update at the same
19630
+ // expiration time that is already rendering.
19631
+ if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19632
+ expirationTime -= 1;
19316
19633
  }
19317
19634
  }
19635
+
19636
+ // Keep track of the lowest pending interactive expiration time. This
19637
+ // allows us to synchronously flush all interactive updates
19638
+ // when needed.
19639
+ // TODO: Move this to renderer?
19640
+ if (priorityLevel === unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19641
+ lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19642
+ }
19643
+
19318
19644
  return expirationTime;
19319
19645
  }
19320
19646
 
@@ -19361,7 +19687,21 @@ function retryTimedOutBoundary(boundaryFiber, thenable) {
19361
19687
  // The boundary fiber (a Suspense component) previously timed out and was
19362
19688
  // rendered in its fallback state. One of the promises that suspended it has
19363
19689
  // resolved, which means at least part of the tree was likely unblocked. Try
19364
- var retryCache = boundaryFiber.stateNode;
19690
+ var retryCache = void 0;
19691
+ if (enableSuspenseServerRenderer) {
19692
+ switch (boundaryFiber.tag) {
19693
+ case SuspenseComponent:
19694
+ retryCache = boundaryFiber.stateNode;
19695
+ break;
19696
+ case DehydratedSuspenseComponent:
19697
+ retryCache = boundaryFiber.memoizedState;
19698
+ break;
19699
+ default:
19700
+ invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19701
+ }
19702
+ } else {
19703
+ retryCache = boundaryFiber.stateNode;
19704
+ }
19365
19705
  if (retryCache !== null) {
19366
19706
  // The thenable resolved, so we no longer need to memoize, because it will
19367
19707
  // never be thrown again.
@@ -19460,7 +19800,7 @@ function scheduleWorkToRoot(fiber, expirationTime) {
19460
19800
  function warnIfNotCurrentlyBatchingInDev(fiber) {
19461
19801
  {
19462
19802
  if (isRendering === false && isBatchingUpdates === false) {
19463
- warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act', getComponentName(fiber.type));
19803
+ warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
19464
19804
  }
19465
19805
  }
19466
19806
  }
@@ -19507,13 +19847,9 @@ function scheduleWork(fiber, expirationTime) {
19507
19847
  }
19508
19848
 
19509
19849
  function syncUpdates(fn, a, b, c, d) {
19510
- var previousExpirationContext = expirationContext;
19511
- expirationContext = Sync;
19512
- try {
19850
+ return unstable_runWithPriority(unstable_ImmediatePriority, function () {
19513
19851
  return fn(a, b, c, d);
19514
- } finally {
19515
- expirationContext = previousExpirationContext;
19516
- }
19852
+ });
19517
19853
  }
19518
19854
 
19519
19855
  // TODO: Everything below this is written as if it has been lifted to the
@@ -19534,7 +19870,6 @@ var unhandledError = null;
19534
19870
 
19535
19871
  var isBatchingUpdates = false;
19536
19872
  var isUnbatchingUpdates = false;
19537
- var isBatchingInteractiveUpdates = false;
19538
19873
 
19539
19874
  var completedBatches = null;
19540
19875
 
@@ -20008,7 +20343,9 @@ function completeRoot(root, finishedWork, expirationTime) {
20008
20343
  lastCommittedRootDuringThisBatch = root;
20009
20344
  nestedUpdateCount = 0;
20010
20345
  }
20011
- commitRoot(root, finishedWork);
20346
+ unstable_runWithPriority(unstable_ImmediatePriority, function () {
20347
+ commitRoot(root, finishedWork);
20348
+ });
20012
20349
  }
20013
20350
 
20014
20351
  function onUncaughtError(error) {
@@ -20066,9 +20403,6 @@ function flushSync(fn, a) {
20066
20403
  }
20067
20404
 
20068
20405
  function interactiveUpdates$1(fn, a, b) {
20069
- if (isBatchingInteractiveUpdates) {
20070
- return fn(a, b);
20071
- }
20072
20406
  // If there are any pending interactive updates, synchronously flush them.
20073
20407
  // This needs to happen before we read any handlers, because the effect of
20074
20408
  // the previous event may influence which handlers are called during
@@ -20078,14 +20412,13 @@ function interactiveUpdates$1(fn, a, b) {
20078
20412
  performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20079
20413
  lowestPriorityPendingInteractiveExpirationTime = NoWork;
20080
20414
  }
20081
- var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
20082
20415
  var previousIsBatchingUpdates = isBatchingUpdates;
20083
- isBatchingInteractiveUpdates = true;
20084
20416
  isBatchingUpdates = true;
20085
20417
  try {
20086
- return fn(a, b);
20418
+ return unstable_runWithPriority(unstable_UserBlockingPriority, function () {
20419
+ return fn(a, b);
20420
+ });
20087
20421
  } finally {
20088
- isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
20089
20422
  isBatchingUpdates = previousIsBatchingUpdates;
20090
20423
  if (!isBatchingUpdates && !isRendering) {
20091
20424
  performSyncWork();
@@ -20348,7 +20681,7 @@ implementation) {
20348
20681
 
20349
20682
  // TODO: this is special because it gets imported during build.
20350
20683
 
20351
- var ReactVersion = '16.8.1';
20684
+ var ReactVersion = '16.8.2';
20352
20685
 
20353
20686
  // TODO: This type is shared between the reconciler and ReactDOM, but will
20354
20687
  // eventually be lifted out to the renderer.
@@ -20738,7 +21071,7 @@ var ReactDOM = {
20738
21071
  hydrate: function (element, container, callback) {
20739
21072
  !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20740
21073
  {
20741
- !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call root.render(element, {hydrate: true})?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
21074
+ !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
20742
21075
  }
20743
21076
  // TODO: throw or warn if we couldn't hydrate?
20744
21077
  return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);