2016-05-04 05:37:13 +08:00
|
|
|
/**
|
2022-10-18 23:19:24 +08:00
|
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
2016-05-04 05:37:13 +08:00
|
|
|
*
|
2017-09-25 04:48:13 +08:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2016-05-04 05:37:13 +08:00
|
|
|
*
|
|
|
|
|
* @flow
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* eslint-disable */
|
|
|
|
|
|
2018-06-12 04:16:27 +08:00
|
|
|
declare var __PROFILE__: boolean;
|
2018-09-02 03:00:00 +08:00
|
|
|
declare var __UMD__: boolean;
|
Set up experimental builds (#17071)
* Don't bother including `unstable_` in error
The method names don't get stripped out of the production bundles
because they are passed as arguments to the error decoder.
Let's just always use the unprefixed APIs in the messages.
* Set up experimental builds
The experimental builds are packaged exactly like builds in the stable
release channel: same file structure, entry points, and npm package
names. The goal is to match what will eventually be released in stable
as closely as possible, but with additional features turned on.
Versioning and Releasing
------------------------
The experimental builds will be published to the same registry and
package names as the stable ones. However, they will be versioned using
a separate scheme. Instead of semver versions, experimental releases
will receive arbitrary version strings based on their content hashes.
The motivation is to thwart attempts to use a version range to match
against future experimental releases. The only way to install or depend
on an experimental release is to refer to the specific version number.
Building
--------
I did not use the existing feature flag infra to configure the
experimental builds. The reason is because feature flags are designed
to configure a single package. They're not designed to generate multiple
forks of the same package; for each set of feature flags, you must
create a separate package configuration.
Instead, I've added a new build dimension called the **release
channel**. By default, builds use the **stable** channel. There's
also an **experimental** release channel. We have the option to add more
in the future.
There are now two dimensions per artifact: build type (production,
development, or profiling), and release channel (stable or
experimental). These are separate dimensions because they are
combinatorial: there are stable and experimental production builds,
stable and experimental developmenet builds, and so on.
You can add something to an experimental build by gating on
`__EXPERIMENTAL__`, similar to how we use `__DEV__`. Anything inside
these branches will be excluded from the stable builds.
This gives us a low effort way to add experimental behavior in any
package without setting up feature flags or configuring a new package.
2019-10-15 01:46:42 +08:00
|
|
|
declare var __EXPERIMENTAL__: boolean;
|
Add test run that uses www feature flags (#18234)
In CI, we run our test suite against multiple build configurations. For
example, we run our tests in both dev and prod, and in both the
experimental and stable release channels. This is to prevent accidental
deviations in behavior between the different builds. If there's an
intentional deviation in behavior, the test author must account
for them.
However, we currently don't run tests against the www builds. That's
a problem, because it's common for features to land in www before they
land anywhere else, including the experimental release channel.
Typically we do this so we can gradually roll out the feature behind
a flag before deciding to enable it.
The way we test those features today is by mutating the
`shared/ReactFeatureFlags` module. There are a few downsides to this
approach, though. The flag is only overridden for the specific tests or
test suites where you apply the override. But usually what you want is
to run *all* tests with the flag enabled, to protect against unexpected
regressions.
Also, mutating the feature flags module only works when running the
tests against source, not against the final build artifacts, because the
ReactFeatureFlags module is inlined by the build script.
Instead, we should run the test suite against the www configuration,
just like we do for prod, experimental, and so on. I've added a new
command, `yarn test-www`. It automatically runs in CI.
Some of the www feature flags are dynamic; that is, they depend on
a runtime condition (i.e. a GK). These flags are imported from an
external module that lives in www. Those flags will be enabled for some
clients and disabled for others, so we should run the tests against
*both* modes.
So I've added a new global `__VARIANT__`, and a new test command `yarn
test-www-variant`. `__VARIANT__` is set to false by default; when
running `test-www-variant`, it's set to true.
If we were going for *really* comprehensive coverage, we would run the
tests against every possible configuration of feature flags: 2 ^
numberOfFlags total combinations. That's not practical, though, so
instead we only run against two combinations: once with `__VARIANT__`
set to `true`, and once with it set to `false`. We generally assume that
flags can be toggled independently, so in practice this should
be enough.
You can also refer to `__VARIANT__` in tests to detect which mode you're
running in. Or, you can import `shared/ReactFeatureFlags` and read the
specific flag you can about. However, we should stop mutating that
module going forward. Treat it as read-only.
In this commit, I have only setup the www tests to run against source.
I'll leave running against build for a follow up.
Many of our tests currently assume they run only in the default
configuration, and break when certain flags are toggled. Rather than fix
these all up front, I've hard-coded the relevant flags to the default
values. We can incrementally migrate those tests later.
2020-03-07 01:29:05 +08:00
|
|
|
declare var __VARIANT__: boolean;
|
2018-06-12 04:16:27 +08:00
|
|
|
|
2016-05-04 05:37:13 +08:00
|
|
|
declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: any; /*?{
|
|
|
|
|
inject: ?((stuff: Object) => void)
|
2017-10-17 21:20:00 +08:00
|
|
|
};*/
|
2017-11-06 22:14:48 +08:00
|
|
|
|
2022-10-27 14:43:17 +08:00
|
|
|
declare var globalThis: Object;
|
|
|
|
|
|
2021-02-06 01:13:42 +08:00
|
|
|
declare var queueMicrotask: (fn: Function) => void;
|
Add onRecoverableError option to hydrateRoot, createRoot (#23207)
* [RFC] Add onHydrationError option to hydrateRoot
This is not the final API but I'm pushing it for discussion purposes.
When an error is thrown during hydration, we fallback to client
rendering, without triggering an error boundary. This is good because,
in many cases, the UI will recover and the user won't even notice that
something has gone wrong behind the scenes.
However, we shouldn't recover from these errors silently, because the
underlying cause might be pretty serious. Server-client mismatches are
not supposed to happen, even if UI doesn't break from the users
perspective. Ignoring them could lead to worse problems later. De-opting
from server to client rendering could also be a significant performance
regression, depending on the scope of the UI it affects.
So we need a way to log when hydration errors occur.
This adds a new option for `hydrateRoot` called `onHydrationError`. It's
symmetrical to the server renderer's `onError` option, and serves the
same purpose.
When no option is provided, the default behavior is to schedule a
browser task and rethrow the error. This will trigger the normal browser
behavior for errors, including dispatching an error event. If the app
already has error monitoring, this likely will just work as expected
without additional configuration.
However, we can also expose additional metadata about these errors, like
which Suspense boundaries were affected by the de-opt to client
rendering. (I have not exposed any metadata in this commit; API needs
more design work.)
There are other situations besides hydration where we recover from an
error without surfacing it to the user, or notifying an error boundary.
For example, if an error occurs during a concurrent render, it could be
due to a data race, so we try again synchronously in case that fixes it.
We should probably expose a way to log these types of errors, too. (Also
not implemented in this commit.)
* Log all recoverable errors
This expands the scope of onHydrationError to include all errors that
are not surfaced to the UI (an error boundary). In addition to errors
that occur during hydration, this also includes errors that recoverable
by de-opting to synchronous rendering. Typically (or really, by
definition) these errors are the result of a concurrent data race;
blocking the main thread fixes them by prevents subsequent races.
The logic for de-opting to synchronous rendering already existed. The
only thing that has changed is that we now log the errors instead of
silently proceeding.
The logging API has been renamed from onHydrationError
to onRecoverableError.
* Don't log recoverable errors until commit phase
If the render is interrupted and restarts, we don't want to log the
errors multiple times.
This change only affects errors that are recovered by de-opting to
synchronous rendering; we'll have to do something else for errors
during hydration, since they use a different recovery path.
* Only log hydration error if client render succeeds
Similar to previous step.
When an error occurs during hydration, we only want to log it if falling
back to client rendering _succeeds_. If client rendering fails,
the error will get reported to the nearest error boundary, so there's
no need for a duplicate log.
To implement this, I added a list of errors to the hydration context.
If the Suspense boundary successfully completes, they are added to
the main recoverable errors queue (the one I added in the
previous step.)
* Log error with queueMicrotask instead of Scheduler
If onRecoverableError is not provided, we default to rethrowing the
error in a separate task. Originally, I scheduled the task with
idle priority, but @sebmarkbage made the good point that if there are
multiple errors logs, we want to preserve the original order. So I've
switched it to a microtask. The priority can be lowered in userspace
by scheduling an additional task inside onRecoverableError.
* Only use host config method for default behavior
Redefines the contract of the host config's logRecoverableError method
to be a default implementation for onRecoverableError if a user-provided
one is not provided when the root is created.
* Log with reportError instead of rethrowing
In modern browsers, reportError will dispatch an error event, emulating
an uncaught JavaScript error. We can do this instead of rethrowing
recoverable errors in a microtask, which is nice because it avoids any
subtle ordering issues.
In older browsers and test environments, we'll fall back
to console.error.
* Naming nits
queueRecoverableHydrationErrors -> upgradeHydrationErrorsToRecoverable
2022-02-04 23:57:33 +08:00
|
|
|
declare var reportError: (error: mixed) => void;
|
2021-02-06 01:13:42 +08:00
|
|
|
|
2020-01-23 02:02:30 +08:00
|
|
|
declare module 'create-react-class' {
|
|
|
|
|
declare var exports: React$CreateClass;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-10 04:03:48 +08:00
|
|
|
declare var trustedTypes: {
|
2019-09-17 23:06:26 +08:00
|
|
|
isHTML: (value: any) => boolean,
|
|
|
|
|
isScript: (value: any) => boolean,
|
|
|
|
|
isScriptURL: (value: any) => boolean,
|
|
|
|
|
// TrustedURLs are deprecated and will be removed soon: https://github.com/WICG/trusted-types/pull/204
|
|
|
|
|
isURL?: (value: any) => boolean,
|
2022-09-10 04:03:48 +08:00
|
|
|
};
|
2019-09-17 23:06:26 +08:00
|
|
|
|
2017-12-01 01:57:13 +08:00
|
|
|
// ReactFeatureFlags www fork
|
2017-11-06 22:14:48 +08:00
|
|
|
declare module 'ReactFeatureFlags' {
|
|
|
|
|
declare module.exports: any;
|
|
|
|
|
}
|
2017-12-01 01:57:13 +08:00
|
|
|
|
|
|
|
|
// ReactFiberErrorDialog www fork
|
|
|
|
|
declare module 'ReactFiberErrorDialog' {
|
2020-01-09 22:50:44 +08:00
|
|
|
declare module.exports: {showErrorDialog: (error: mixed) => boolean, ...};
|
2017-12-01 01:57:13 +08:00
|
|
|
}
|
2017-12-08 06:28:59 +08:00
|
|
|
|
|
|
|
|
// EventListener www fork
|
|
|
|
|
declare module 'EventListener' {
|
|
|
|
|
declare module.exports: {
|
2019-03-15 17:39:43 +08:00
|
|
|
listen: (
|
2020-03-12 17:12:06 +08:00
|
|
|
target: EventTarget,
|
2019-03-15 17:39:43 +08:00
|
|
|
type: string,
|
|
|
|
|
callback: Function,
|
|
|
|
|
priority?: number,
|
2020-01-09 22:50:44 +08:00
|
|
|
options?: {passive: boolean, ...},
|
2019-03-15 17:39:43 +08:00
|
|
|
) => mixed,
|
2020-03-12 17:12:06 +08:00
|
|
|
capture: (target: EventTarget, type: string, callback: Function) => mixed,
|
2019-04-30 18:40:45 +08:00
|
|
|
captureWithPassiveFlag: (
|
2020-03-12 17:12:06 +08:00
|
|
|
target: EventTarget,
|
|
|
|
|
type: string,
|
|
|
|
|
callback: Function,
|
|
|
|
|
passive: boolean,
|
|
|
|
|
) => mixed,
|
|
|
|
|
bubbleWithPassiveFlag: (
|
|
|
|
|
target: EventTarget,
|
2019-04-30 18:40:45 +08:00
|
|
|
type: string,
|
|
|
|
|
callback: Function,
|
|
|
|
|
passive: boolean,
|
|
|
|
|
) => mixed,
|
2020-01-09 22:50:44 +08:00
|
|
|
...
|
2017-12-08 06:28:59 +08:00
|
|
|
};
|
|
|
|
|
}
|
2020-03-19 03:18:34 +08:00
|
|
|
|
2020-03-26 07:49:37 +08:00
|
|
|
declare function __webpack_chunk_load__(id: string): Promise<mixed>;
|
2020-12-01 06:37:27 +08:00
|
|
|
declare function __webpack_require__(id: string): any;
|
2020-12-05 01:27:33 +08:00
|
|
|
|
2020-12-09 10:37:29 +08:00
|
|
|
declare module 'fs/promises' {
|
2020-12-10 05:46:50 +08:00
|
|
|
declare var access: (path: string, mode?: number) => Promise<void>;
|
|
|
|
|
declare var lstat: (
|
|
|
|
|
path: string,
|
2022-09-10 04:03:48 +08:00
|
|
|
options?: ?{bigint?: boolean},
|
2020-12-10 05:46:50 +08:00
|
|
|
) => Promise<mixed>;
|
|
|
|
|
declare var readdir: (
|
|
|
|
|
path: string,
|
|
|
|
|
options?:
|
|
|
|
|
| ?string
|
2022-09-10 04:03:48 +08:00
|
|
|
| {
|
2020-12-10 05:46:50 +08:00
|
|
|
encoding?: ?string,
|
|
|
|
|
withFileTypes?: ?boolean,
|
2022-09-10 04:03:48 +08:00
|
|
|
},
|
2020-12-10 05:46:50 +08:00
|
|
|
) => Promise<Buffer>;
|
2020-12-09 10:37:29 +08:00
|
|
|
declare var readFile: (
|
|
|
|
|
path: string,
|
|
|
|
|
options?:
|
|
|
|
|
| ?string
|
2022-09-10 04:03:48 +08:00
|
|
|
| {
|
2020-12-09 10:37:29 +08:00
|
|
|
encoding?: ?string,
|
2022-09-10 04:03:48 +08:00
|
|
|
},
|
2020-12-09 10:37:29 +08:00
|
|
|
) => Promise<Buffer>;
|
2020-12-10 05:46:50 +08:00
|
|
|
declare var readlink: (
|
|
|
|
|
path: string,
|
|
|
|
|
options?:
|
|
|
|
|
| ?string
|
2022-09-10 04:03:48 +08:00
|
|
|
| {
|
2020-12-10 05:46:50 +08:00
|
|
|
encoding?: ?string,
|
2022-09-10 04:03:48 +08:00
|
|
|
},
|
2020-12-10 05:46:50 +08:00
|
|
|
) => Promise<mixed>;
|
|
|
|
|
declare var realpath: (
|
|
|
|
|
path: string,
|
|
|
|
|
options?:
|
|
|
|
|
| ?string
|
2022-09-10 04:03:48 +08:00
|
|
|
| {
|
2020-12-10 05:46:50 +08:00
|
|
|
encoding?: ?string,
|
2022-09-10 04:03:48 +08:00
|
|
|
},
|
2020-12-10 05:46:50 +08:00
|
|
|
) => Promise<mixed>;
|
|
|
|
|
declare var stat: (
|
|
|
|
|
path: string,
|
2022-09-10 04:03:48 +08:00
|
|
|
options?: ?{bigint?: boolean},
|
2020-12-10 05:46:50 +08:00
|
|
|
) => Promise<mixed>;
|
2020-12-09 10:37:29 +08:00
|
|
|
}
|
2020-12-05 01:27:33 +08:00
|
|
|
declare module 'pg' {
|
|
|
|
|
declare var Pool: (
|
|
|
|
|
options: mixed,
|
2022-09-10 04:03:48 +08:00
|
|
|
) => {
|
2020-12-05 01:27:33 +08:00
|
|
|
query: (query: string, values?: Array<mixed>) => void,
|
2022-09-10 04:03:48 +08:00
|
|
|
};
|
2020-12-05 01:27:33 +08:00
|
|
|
}
|
|
|
|
|
|
2022-04-12 00:13:44 +08:00
|
|
|
declare module 'util' {
|
|
|
|
|
declare function debuglog(section: string): (data: any, ...args: any) => void;
|
|
|
|
|
declare function format(format: string, ...placeholders: any): string;
|
|
|
|
|
declare function log(string: string): void;
|
|
|
|
|
declare function inspect(object: any, options?: util$InspectOptions): string;
|
|
|
|
|
declare function isArray(object: any): boolean;
|
|
|
|
|
declare function isRegExp(object: any): boolean;
|
|
|
|
|
declare function isDate(object: any): boolean;
|
|
|
|
|
declare function isError(object: any): boolean;
|
|
|
|
|
declare function inherits(
|
|
|
|
|
constructor: Function,
|
|
|
|
|
superConstructor: Function,
|
|
|
|
|
): void;
|
|
|
|
|
declare function deprecate(f: Function, string: string): Function;
|
|
|
|
|
declare function promisify(f: Function): Function;
|
|
|
|
|
declare function callbackify(f: Function): Function;
|
|
|
|
|
declare class TextEncoder {
|
|
|
|
|
constructor(encoding?: string): TextEncoder;
|
|
|
|
|
encode(buffer: string): Uint8Array;
|
|
|
|
|
encodeInto(
|
|
|
|
|
buffer: string,
|
|
|
|
|
dest: Uint8Array,
|
2022-09-10 04:03:48 +08:00
|
|
|
): {read: number, written: number};
|
2022-04-12 00:13:44 +08:00
|
|
|
encoding: string;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-05 01:27:33 +08:00
|
|
|
declare module 'pg/lib/utils' {
|
2022-09-10 04:03:48 +08:00
|
|
|
declare module.exports: {
|
2020-12-05 01:27:33 +08:00
|
|
|
prepareValue(val: any): mixed,
|
2022-09-10 04:03:48 +08:00
|
|
|
};
|
2020-12-05 01:27:33 +08:00
|
|
|
}
|
2022-10-23 13:06:58 +08:00
|
|
|
|
|
|
|
|
declare class AsyncLocalStorage<T> {
|
|
|
|
|
disable(): void;
|
|
|
|
|
getStore(): T | void;
|
|
|
|
|
run(store: T, callback: (...args: any[]) => void, ...args: any[]): void;
|
|
|
|
|
enterWith(store: T): void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
declare module 'async_hooks' {
|
|
|
|
|
declare class AsyncLocalStorage<T> {
|
|
|
|
|
disable(): void;
|
|
|
|
|
getStore(): T | void;
|
|
|
|
|
run(store: T, callback: (...args: any[]) => void, ...args: any[]): void;
|
|
|
|
|
enterWith(store: T): void;
|
|
|
|
|
}
|
|
|
|
|
}
|