mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
This is an initial, partial implementation of a cleanup mechanism for the experimental Cache API. The idea is that consumers of the Cache API can register to be informed when a given Cache instance is no longer needed so that they can perform associated cleanup tasks to free resources stored in the cache. A canonical example would be cancelling pending network requests. An overview of the high-level changes: * Changes the `Cache` type from a Map of cache instances to be an object with the original Map of instances, a reference count (to count roughly "active references" to the cache instances - more below), and an AbortController. * Adds a new public API, `unstable_getCacheSignal(): AbortSignal`, which is callable during render. It returns an AbortSignal tied to the lifetime of the cache - developers can listen for the 'abort' event on the signal, which React now triggers when a given cache instance is no longer referenced. * Note that `AbortSignal` is a web standard that is supported by other platform APIs; for example a signal can be passed to `fetch()` to trigger cancellation of an HTTP request. * Implements the above - triggering the 'abort' event - by handling passive mount/unmount for HostRoot and CacheComponent fiber nodes. Cases handled: * Aborted transitions: we clean up a new cache created for an aborted transition * Suspense: we retain a fresh cache instance until a suspended tree resolves For follow-ups: * When a subsequent cache refresh is issued before a previous refresh completes, the refreshes are queued. Fresh cache instances for previous refreshes in the queue should be cleared, retaining only the most recent cache. I plan to address this in a follow-up PR. * If a refresh is cancelled, the fresh cache should be cleaned up.
43 lines
1.1 KiB
JavaScript
43 lines
1.1 KiB
JavaScript
/* eslint-disable */
|
|
|
|
const AbortController = require('abort-controller');
|
|
|
|
const NODE_ENV = process.env.NODE_ENV;
|
|
if (NODE_ENV !== 'development' && NODE_ENV !== 'production') {
|
|
throw new Error('NODE_ENV must either be set to development or production.');
|
|
}
|
|
global.__DEV__ = NODE_ENV === 'development';
|
|
global.__EXTENSION__ = false;
|
|
global.__TEST__ = NODE_ENV === 'test';
|
|
global.__PROFILE__ = NODE_ENV === 'development';
|
|
global.__UMD__ = false;
|
|
|
|
const RELEASE_CHANNEL = process.env.RELEASE_CHANNEL;
|
|
|
|
// Default to running tests in experimental mode. If the release channel is
|
|
// set via an environment variable, then check if it's "experimental".
|
|
global.__EXPERIMENTAL__ =
|
|
typeof RELEASE_CHANNEL === 'string'
|
|
? RELEASE_CHANNEL === 'experimental'
|
|
: true;
|
|
|
|
global.__VARIANT__ = !!process.env.VARIANT;
|
|
|
|
global.AbortController = AbortController;
|
|
|
|
if (typeof window !== 'undefined') {
|
|
global.requestIdleCallback = function(callback) {
|
|
return setTimeout(() => {
|
|
callback({
|
|
timeRemaining() {
|
|
return Infinity;
|
|
},
|
|
});
|
|
});
|
|
};
|
|
|
|
global.cancelIdleCallback = function(callbackID) {
|
|
clearTimeout(callbackID);
|
|
};
|
|
}
|