react/packages/react-devtools-shared/src/inspectedElementCache.js

217 lines
5.4 KiB
JavaScript
Raw Normal View History

Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {
unstable_getCacheForType as getCacheForType,
startTransition,
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
} from 'react';
import Store from './devtools/store';
import {inspectElement as inspectElementMutableSource} from './inspectedElementMutableSource';
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
import type {Wakeable} from 'shared/ReactTypes';
import type {
Element,
InspectedElement as InspectedElementFrontend,
InspectedElementResponseType,
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
} from 'react-devtools-shared/src/devtools/views/Components/types';
const Pending = 0;
const Resolved = 1;
const Rejected = 2;
type PendingRecord = {
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
status: 0,
value: Wakeable,
};
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
type ResolvedRecord<T> = {
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
status: 1,
value: T,
};
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
type RejectedRecord = {
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
status: 2,
value: Error | string,
};
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
type Record<T> = PendingRecord | ResolvedRecord<T> | RejectedRecord;
function readRecord<T>(record: Record<T>): ResolvedRecord<T> {
if (record.status === Resolved) {
// This is just a type refinement.
return record;
} else {
throw record.value;
}
}
type InspectedElementMap = WeakMap<Element, Record<InspectedElementFrontend>>;
type CacheSeedKey = () => InspectedElementMap;
function createMap(): InspectedElementMap {
return new WeakMap();
}
function getRecordMap(): WeakMap<Element, Record<InspectedElementFrontend>> {
return getCacheForType(createMap);
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
}
function createCacheSeed(
element: Element,
inspectedElement: InspectedElementFrontend,
): [CacheSeedKey, InspectedElementMap] {
const newRecord: Record<InspectedElementFrontend> = {
status: Resolved,
value: inspectedElement,
};
const map = createMap();
map.set(element, newRecord);
return [createMap, map];
}
/**
* Fetches element props and state from the backend for inspection.
* This method should be called during render; it will suspend if data has not yet been fetched.
*/
export function inspectElement(
element: Element,
path: Array<string | number> | null,
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
store: Store,
bridge: FrontendBridge,
): InspectedElementFrontend | null {
const map = getRecordMap();
let record = map.get(element);
if (!record) {
const callbacks = new Set();
const wakeable: Wakeable = {
then(callback) {
callbacks.add(callback);
},
// Optional property used by Timeline:
displayName: `Inspecting ${element.displayName || 'Unknown'}`,
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
};
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
const wake = () => {
// This assumes they won't throw.
callbacks.forEach(callback => callback());
callbacks.clear();
};
const newRecord: Record<InspectedElementFrontend> = (record = {
status: Pending,
value: wakeable,
});
const rendererID = store.getRendererIDForElement(element.id);
if (rendererID == null) {
const rejectedRecord = ((newRecord: any): RejectedRecord);
rejectedRecord.status = Rejected;
rejectedRecord.value = new Error(
`Could not inspect element with id "${element.id}". No renderer found.`,
);
map.set(element, record);
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
return null;
}
inspectElementMutableSource({
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
bridge,
element,
path,
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
rendererID: ((rendererID: any): number),
}).then(
([inspectedElement]: [
InspectedElementFrontend,
InspectedElementResponseType,
]) => {
const resolvedRecord =
((newRecord: any): ResolvedRecord<InspectedElementFrontend>);
resolvedRecord.status = Resolved;
resolvedRecord.value = inspectedElement;
wake();
},
error => {
console.error(error);
const rejectedRecord = ((newRecord: any): RejectedRecord);
rejectedRecord.status = Rejected;
rejectedRecord.value = error;
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
wake();
},
);
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
map.set(element, record);
}
const response = readRecord(record).value;
return response;
}
type RefreshFunction = (
seedKey: CacheSeedKey,
cacheMap: InspectedElementMap,
) => void;
/**
* Asks the backend for updated props and state from an expected element.
* This method should never be called during render; call it from an effect or event handler.
* This method will schedule an update if updated information is returned.
*/
export function checkForUpdate({
bridge,
element,
refresh,
store,
}: {
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
bridge: FrontendBridge,
element: Element,
refresh: RefreshFunction,
store: Store,
}): void {
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
const {id} = element;
const rendererID = store.getRendererIDForElement(id);
if (rendererID != null) {
inspectElementMutableSource({
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
bridge,
element,
path: null,
rendererID: ((rendererID: any): number),
}).then(
([inspectedElement, responseType]: [
InspectedElementFrontend,
InspectedElementResponseType,
]) => {
if (responseType === 'full-data') {
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
startTransition(() => {
const [key, value] = createCacheSeed(element, inspectedElement);
refresh(key, value);
});
}
},
// There isn't much to do about errors in this case,
// but we should at least log them so they aren't silent.
error => {
console.error(error);
},
);
Update DevTools to use getCacheForType API (#20548) DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs. ### Messaging changes I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it. The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.) _Initial inspection..._ ``` front | | back | -- "inspect" (id:1, paths:[], force:true) ---------> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes with no updates..._ ``` | -- "inspect" (id:1, paths:[], force:false) --------> | | <------------------------ "inspected" (no-change) -- | ``` _User clicks to expand a path, aka hydrate..._ ``` | -- "inspect" (id:1, paths:['foo'], force:true) ----> | | <------------------------ "inspected" (full-data) -- | ``` _1 second passes during which there is an update..._ ``` | -- "inspect" (id:1, paths:['foo'], force:false) ---> | | <----------------- "inspectedElement" (full-data) -- | ``` ### Clear errors/warnings transition Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved. ### Hydrating paths transition I also added a transition to hydration (expanding "dehyrated" paths). ### Better error boundaries I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element. ### Improved snapshot tests I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 22:51:32 +08:00
}
}
export function clearCacheBecauseOfError(refresh: RefreshFunction): void {
startTransition(() => {
const map = createMap();
refresh(createMap, map);
});
}