diff --git a/.github/workflows/runtime_commit_artifacts.yml b/.github/workflows/runtime_commit_artifacts.yml index 9f786b9b5ecc..073c289843fe 100644 --- a/.github/workflows/runtime_commit_artifacts.yml +++ b/.github/workflows/runtime_commit_artifacts.yml @@ -85,6 +85,11 @@ jobs: sed -i -e 's/ @license React*//' \ build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \ build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js + - name: Insert @headers into eslint plugin and react-refresh + run: | + sed -i -e 's/ LICENSE file in the root directory of this source tree./ LICENSE file in the root directory of this source tree.\n * \n * @noformat\n * @nolint\n * @lightSyntaxTransform\n * @preventMunge\n * @oncall react_core/' \ + build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \ + build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js - name: Move relevant files for React in www into compiled run: | # Move the facebook-www folder into compiled diff --git a/compiler/apps/playground/components/Editor/EditorImpl.tsx b/compiler/apps/playground/components/Editor/EditorImpl.tsx index ebac65dc4b9f..7b1214b4600c 100644 --- a/compiler/apps/playground/components/Editor/EditorImpl.tsx +++ b/compiler/apps/playground/components/Editor/EditorImpl.tsx @@ -66,14 +66,14 @@ function parseFunctions( source: string, language: 'flow' | 'typescript', ): Array< - NodePath< - t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression - > + | NodePath + | NodePath + | NodePath > { const items: Array< - NodePath< - t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression - > + | NodePath + | NodePath + | NodePath > = []; try { const ast = parseInput(source, language); @@ -155,22 +155,33 @@ function isHookName(s: string): boolean { return /^use[A-Z0-9]/.test(s); } -function getReactFunctionType( - id: NodePath, -): ReactFunctionType { - if (id && id.node && id.isIdentifier()) { - if (isHookName(id.node.name)) { +function getReactFunctionType(id: t.Identifier | null): ReactFunctionType { + if (id != null) { + if (isHookName(id.name)) { return 'Hook'; } const isPascalCaseNameSpace = /^[A-Z].*/; - if (isPascalCaseNameSpace.test(id.node.name)) { + if (isPascalCaseNameSpace.test(id.name)) { return 'Component'; } } return 'Other'; } +function getFunctionIdentifier( + fn: + | NodePath + | NodePath + | NodePath, +): t.Identifier | null { + if (fn.isArrowFunctionExpression()) { + return null; + } + const id = fn.get('id'); + return Array.isArray(id) === false && id.isIdentifier() ? id.node : null; +} + function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { const results = new Map(); const error = new CompilerError(); @@ -188,27 +199,21 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { } else { language = 'typescript'; } + let count = 0; + const withIdentifier = (id: t.Identifier | null): t.Identifier => { + if (id != null && id.name != null) { + return id; + } else { + return t.identifier(`anonymous_${count++}`); + } + }; try { // Extract the first line to quickly check for custom test directives const pragma = source.substring(0, source.indexOf('\n')); const config = parseConfigPragma(pragma); for (const fn of parseFunctions(source, language)) { - if (!fn.isFunctionDeclaration()) { - error.pushErrorDetail( - new CompilerErrorDetail({ - reason: `Unexpected function type ${fn.node.type}`, - description: - 'Playground only supports parsing function declarations', - severity: ErrorSeverity.Todo, - loc: fn.node.loc ?? null, - suggestions: null, - }), - ); - continue; - } - - const id = fn.get('id'); + const id = withIdentifier(getFunctionIdentifier(fn)); for (const result of run( fn, { @@ -221,7 +226,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { null, null, )) { - const fnName = fn.node.id?.name ?? null; + const fnName = id.name; switch (result.kind) { case 'ast': { upsert({ @@ -230,7 +235,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { name: result.name, value: { type: 'FunctionDeclaration', - id: result.value.id, + id, async: result.value.async, generator: result.value.generator, body: result.value.body, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts index 722c62461d81..e96649725651 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts @@ -7,8 +7,12 @@ import * as t from '@babel/types'; import {z} from 'zod'; -import {CompilerErrorDetailOptions} from '../CompilerError'; -import {ExternalFunction, PartialEnvironmentConfig} from '../HIR/Environment'; +import {CompilerError, CompilerErrorDetailOptions} from '../CompilerError'; +import { + EnvironmentConfig, + ExternalFunction, + parseEnvironmentConfig, +} from '../HIR/Environment'; import {hasOwnProperty} from '../Utils/utils'; const PanicThresholdOptionsSchema = z.enum([ @@ -32,7 +36,7 @@ const PanicThresholdOptionsSchema = z.enum([ export type PanicThresholdOptions = z.infer; export type PluginOptions = { - environment: PartialEnvironmentConfig | null; + environment: EnvironmentConfig; logger: Logger | null; @@ -165,6 +169,12 @@ export type LoggerEvent = fnLoc: t.SourceLocation | null; detail: Omit, 'suggestions'>; } + | { + kind: 'CompileSkip'; + fnLoc: t.SourceLocation | null; + reason: string; + loc: t.SourceLocation | null; + } | { kind: 'CompileSuccess'; fnLoc: t.SourceLocation | null; @@ -188,7 +198,7 @@ export type Logger = { export const defaultOptions: PluginOptions = { compilationMode: 'infer', panicThreshold: 'none', - environment: {}, + environment: parseEnvironmentConfig({}).unwrap(), logger: null, gating: null, noEmit: false, @@ -212,7 +222,19 @@ export function parsePluginOptions(obj: unknown): PluginOptions { // normalize string configs to be case insensitive value = value.toLowerCase(); } - if (isCompilerFlag(key)) { + if (key === 'environment') { + const environmentResult = parseEnvironmentConfig(value); + if (environmentResult.isErr()) { + CompilerError.throwInvalidConfig({ + reason: + 'Error in validating environment config. This is an advanced setting and not meant to be used directly', + description: environmentResult.unwrapErr().toString(), + suggestions: null, + loc: null, + }); + } + parsedOptions[key] = environmentResult.unwrap(); + } else if (isCompilerFlag(key)) { parsedOptions[key] = value; } } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts index 590aba2fdc0c..8307e8817b4f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts @@ -105,6 +105,7 @@ import {outlineFunctions} from '../Optimization/OutlineFunctions'; import {propagatePhiTypes} from '../TypeInference/PropagatePhiTypes'; import {lowerContextAccess} from '../Optimization/LowerContextAccess'; import {validateNoSetStateInPassiveEffects} from '../Validation/ValidateNoSetStateInPassiveEffects'; +import {validateNoJSXInTryStatement} from '../Validation/ValidateNoJSXInTryStatement'; export type CompilerPipelineValue = | {kind: 'ast'; name: string; value: CodegenFunction} @@ -249,6 +250,10 @@ function* runWithEnvironment( validateNoSetStateInPassiveEffects(hir); } + if (env.config.validateNoJSXInTryStatements) { + validateNoJSXInTryStatement(hir); + } + inferReactivePlaces(hir); yield log({kind: 'hir', name: 'InferReactivePlaces', value: hir}); diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts index 499a4d124ea6..979e9f88d1b5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts @@ -16,7 +16,6 @@ import { EnvironmentConfig, ExternalFunction, ReactFunctionType, - parseEnvironmentConfig, tryParseExternalFunction, } from '../HIR/Environment'; import {CodegenFunction} from '../ReactiveScopes'; @@ -43,34 +42,23 @@ export type CompilerPass = { comments: Array; code: string | null; }; +const OPT_IN_DIRECTIVES = new Set(['use forget', 'use memo']); +export const OPT_OUT_DIRECTIVES = new Set(['use no forget', 'use no memo']); function findDirectiveEnablingMemoization( directives: Array, -): t.Directive | null { - for (const directive of directives) { - const directiveValue = directive.value.value; - if (directiveValue === 'use forget' || directiveValue === 'use memo') { - return directive; - } - } - return null; +): Array { + return directives.filter(directive => + OPT_IN_DIRECTIVES.has(directive.value.value), + ); } function findDirectiveDisablingMemoization( directives: Array, - options: PluginOptions, -): t.Directive | null { - for (const directive of directives) { - const directiveValue = directive.value.value; - if ( - (directiveValue === 'use no forget' || - directiveValue === 'use no memo') && - !options.ignoreUseNoForget - ) { - return directive; - } - } - return null; +): Array { + return directives.filter(directive => + OPT_OUT_DIRECTIVES.has(directive.value.value), + ); } function isCriticalError(err: unknown): boolean { @@ -102,7 +90,7 @@ export type CompileResult = { compiledFn: CodegenFunction; }; -function handleError( +function logError( err: unknown, pass: CompilerPass, fnLoc: t.SourceLocation | null, @@ -131,6 +119,13 @@ function handleError( }); } } +} +function handleError( + err: unknown, + pass: CompilerPass, + fnLoc: t.SourceLocation | null, +): void { + logError(err, pass, fnLoc); if ( pass.opts.panicThreshold === 'all_errors' || (pass.opts.panicThreshold === 'critical_errors' && isCriticalError(err)) || @@ -296,21 +291,7 @@ export function compileProgram( return; } - /* - * TODO(lauren): Remove pass.opts.environment nullcheck once PluginOptions - * is validated - */ - const environmentResult = parseEnvironmentConfig(pass.opts.environment ?? {}); - if (environmentResult.isErr()) { - CompilerError.throwInvalidConfig({ - reason: - 'Error in validating environment config. This is an advanced setting and not meant to be used directly', - description: environmentResult.unwrapErr().toString(), - suggestions: null, - loc: null, - }); - } - const environment = environmentResult.unwrap(); + const environment = pass.opts.environment; const restrictedImportsErr = validateRestrictedImports(program, environment); if (restrictedImportsErr) { handleError(restrictedImportsErr, pass, null); @@ -393,6 +374,17 @@ export function compileProgram( fn: BabelFn, fnType: ReactFunctionType, ): null | CodegenFunction => { + let optInDirectives: Array = []; + let optOutDirectives: Array = []; + if (fn.node.body.type === 'BlockStatement') { + optInDirectives = findDirectiveEnablingMemoization( + fn.node.body.directives, + ); + optOutDirectives = findDirectiveDisablingMemoization( + fn.node.body.directives, + ); + } + if (lintError != null) { /** * Note that Babel does not attach comment nodes to nodes; they are dangling off of the @@ -404,7 +396,11 @@ export function compileProgram( fn, ); if (suppressionsInFunction.length > 0) { - handleError(lintError, pass, fn.node.loc ?? null); + if (optOutDirectives.length > 0) { + logError(lintError, pass, fn.node.loc ?? null); + } else { + handleError(lintError, pass, fn.node.loc ?? null); + } } } @@ -430,11 +426,50 @@ export function compileProgram( prunedMemoValues: compiledFn.prunedMemoValues, }); } catch (err) { + /** + * If an opt out directive is present, log only instead of throwing and don't mark as + * containing a critical error. + */ + if (fn.node.body.type === 'BlockStatement') { + if (optOutDirectives.length > 0) { + logError(err, pass, fn.node.loc ?? null); + return null; + } + } hasCriticalError ||= isCriticalError(err); handleError(err, pass, fn.node.loc ?? null); return null; } + /** + * Always compile functions with opt in directives. + */ + if (optInDirectives.length > 0) { + return compiledFn; + } else if (pass.opts.compilationMode === 'annotation') { + /** + * No opt-in directive in annotation mode, so don't insert the compiled function. + */ + return null; + } + + /** + * Otherwise if 'use no forget/memo' is present, we still run the code through the compiler + * for validation but we don't mutate the babel AST. This allows us to flag if there is an + * unused 'use no forget/memo' directive. + */ + if (pass.opts.ignoreUseNoForget === false && optOutDirectives.length > 0) { + for (const directive of optOutDirectives) { + pass.opts.logger?.logEvent(pass.filename, { + kind: 'CompileSkip', + fnLoc: fn.node.body.loc ?? null, + reason: `Skipped due to '${directive.value.value}' directive.`, + loc: directive.loc ?? null, + }); + } + return null; + } + if (!pass.opts.noEmit && !hasCriticalError) { return compiledFn; } @@ -481,6 +516,16 @@ export function compileProgram( }); } + /** + * Do not modify source if there is a module scope level opt out directive. + */ + const moduleScopeOptOutDirectives = findDirectiveDisablingMemoization( + program.node.directives, + ); + if (moduleScopeOptOutDirectives.length > 0) { + return; + } + if (pass.opts.gating != null) { const error = checkFunctionReferencedBeforeDeclarationAtTopLevel( program, @@ -596,24 +641,6 @@ function shouldSkipCompilation( } } - // Top level "use no forget", skip this file entirely - const useNoForget = findDirectiveDisablingMemoization( - program.node.directives, - pass.opts, - ); - if (useNoForget != null) { - pass.opts.logger?.logEvent(pass.filename, { - kind: 'CompileError', - fnLoc: null, - detail: { - severity: ErrorSeverity.Todo, - reason: 'Skipped due to "use no forget" directive.', - loc: useNoForget.loc ?? null, - suggestions: null, - }, - }); - return true; - } const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime'; if (hasMemoCacheFunctionImport(program, moduleName)) { return true; @@ -631,28 +658,8 @@ function getReactFunctionType( ): ReactFunctionType | null { const hookPattern = environment.hookPattern; if (fn.node.body.type === 'BlockStatement') { - // Opt-outs disable compilation regardless of mode - const useNoForget = findDirectiveDisablingMemoization( - fn.node.body.directives, - pass.opts, - ); - if (useNoForget != null) { - pass.opts.logger?.logEvent(pass.filename, { - kind: 'CompileError', - fnLoc: fn.node.body.loc ?? null, - detail: { - severity: ErrorSeverity.Todo, - reason: 'Skipped due to "use no forget" directive.', - loc: useNoForget.loc ?? null, - suggestions: null, - }, - }); - return null; - } - // Otherwise opt-ins enable compilation regardless of mode - if (findDirectiveEnablingMemoization(fn.node.body.directives) != null) { + if (findDirectiveEnablingMemoization(fn.node.body.directives).length > 0) return getComponentOrHookLike(fn, hookPattern) ?? 'Other'; - } } // Component and hook declarations are known components/hooks diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts index ca03b8a7b1e3..a5614ac244a1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts @@ -237,6 +237,12 @@ const EnvironmentConfigSchema = z.object({ */ validateNoSetStateInPassiveEffects: z.boolean().default(false), + /** + * Validates against creating JSX within a try block and recommends using an error boundary + * instead. + */ + validateNoJSXInTryStatements: z.boolean().default(false), + /** * Validates that the dependencies of all effect hooks are memoized. This helps ensure * that Forget does not introduce infinite renders caused by a dependency changing, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoJSXInTryStatement.ts b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoJSXInTryStatement.ts new file mode 100644 index 000000000000..b92a89d76430 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoJSXInTryStatement.ts @@ -0,0 +1,52 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {CompilerError, ErrorSeverity} from '..'; +import {BlockId, HIRFunction} from '../HIR'; +import {retainWhere} from '../Utils/utils'; + +/** + * Developers may not be aware of error boundaries and lazy evaluation of JSX, leading them + * to use patterns such as `let el; try { el = } catch { ... }` to attempt to + * catch rendering errors. Such code will fail to catch errors in rendering, but developers + * may not realize this right away. + * + * This validation pass validates against this pattern: specifically, it errors for JSX + * created within a try block. JSX is allowed within a catch statement, unless that catch + * is itself nested inside an outer try. + */ +export function validateNoJSXInTryStatement(fn: HIRFunction): void { + const activeTryBlocks: Array = []; + const errors = new CompilerError(); + for (const [, block] of fn.body.blocks) { + retainWhere(activeTryBlocks, id => id !== block.id); + + if (activeTryBlocks.length !== 0) { + for (const instr of block.instructions) { + const {value} = instr; + switch (value.kind) { + case 'JsxExpression': + case 'JsxFragment': { + errors.push({ + severity: ErrorSeverity.InvalidReact, + reason: `Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)`, + loc: value.loc, + }); + break; + } + } + } + } + + if (block.terminal.kind === 'try') { + activeTryBlocks.push(block.terminal.handler); + } + } + if (errors.hasErrors()) { + throw errors; + } +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-catch-in-outer-try-with-catch.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-catch-in-outer-try-with-catch.expect.md new file mode 100644 index 000000000000..40cebff89a75 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-catch-in-outer-try-with-catch.expect.md @@ -0,0 +1,38 @@ + +## Input + +```javascript +// @validateNoJSXInTryStatements +import {identity} from 'shared-runtime'; + +function Component(props) { + let el; + try { + let value; + try { + value = identity(props.foo); + } catch { + el =
; + } + } catch { + return null; + } + return el; +} + +``` + + +## Error + +``` + 9 | value = identity(props.foo); + 10 | } catch { +> 11 | el =
; + | ^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) (11:11) + 12 | } + 13 | } catch { + 14 | return null; +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-catch-in-outer-try-with-catch.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-catch-in-outer-try-with-catch.js new file mode 100644 index 000000000000..0935a1a63cd8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-catch-in-outer-try-with-catch.js @@ -0,0 +1,17 @@ +// @validateNoJSXInTryStatements +import {identity} from 'shared-runtime'; + +function Component(props) { + let el; + try { + let value; + try { + value = identity(props.foo); + } catch { + el =
; + } + } catch { + return null; + } + return el; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-try-with-catch.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-try-with-catch.expect.md new file mode 100644 index 000000000000..ee1f5335ef62 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-try-with-catch.expect.md @@ -0,0 +1,31 @@ + +## Input + +```javascript +// @validateNoJSXInTryStatements +function Component(props) { + let el; + try { + el =
; + } catch { + return null; + } + return el; +} + +``` + + +## Error + +``` + 3 | let el; + 4 | try { +> 5 | el =
; + | ^^^^^^^ InvalidReact: Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) (5:5) + 6 | } catch { + 7 | return null; + 8 | } +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-try-with-catch.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-try-with-catch.js new file mode 100644 index 000000000000..3e7747c875b3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-jsx-in-try-with-catch.js @@ -0,0 +1,10 @@ +// @validateNoJSXInTryStatements +function Component(props) { + let el; + try { + el =
; + } catch { + return null; + } + return el; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md new file mode 100644 index 000000000000..a7ea7b7739c6 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.expect.md @@ -0,0 +1,56 @@ + +## Input + +```javascript +// @validateNoJSXInTryStatements +import {identity} from 'shared-runtime'; + +function Component(props) { + let el; + try { + let value; + try { + value = identity(props.foo); + } catch { + el =
; + } + } finally { + console.log(el); + } + return el; +} + +``` + + +## Error + +``` + 4 | function Component(props) { + 5 | let el; +> 6 | try { + | ^^^^^ +> 7 | let value; + | ^^^^^^^^^^^^^^ +> 8 | try { + | ^^^^^^^^^^^^^^ +> 9 | value = identity(props.foo); + | ^^^^^^^^^^^^^^ +> 10 | } catch { + | ^^^^^^^^^^^^^^ +> 11 | el =
; + | ^^^^^^^^^^^^^^ +> 12 | } + | ^^^^^^^^^^^^^^ +> 13 | } finally { + | ^^^^^^^^^^^^^^ +> 14 | console.log(el); + | ^^^^^^^^^^^^^^ +> 15 | } + | ^^^^ Todo: (BuildHIR::lowerStatement) Handle TryStatement without a catch clause (6:15) + 16 | return el; + 17 | } + 18 | +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js new file mode 100644 index 000000000000..9db091a2fb7e --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-catch-in-outer-try-with-finally.js @@ -0,0 +1,17 @@ +// @validateNoJSXInTryStatements +import {identity} from 'shared-runtime'; + +function Component(props) { + let el; + try { + let value; + try { + value = identity(props.foo); + } catch { + el =
; + } + } finally { + console.log(el); + } + return el; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md new file mode 100644 index 000000000000..a6a85d4519bc --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.expect.md @@ -0,0 +1,39 @@ + +## Input + +```javascript +// @validateNoJSXInTryStatements +function Component(props) { + let el; + try { + el =
; + } finally { + console.log(el); + } + return el; +} + +``` + + +## Error + +``` + 2 | function Component(props) { + 3 | let el; +> 4 | try { + | ^^^^^ +> 5 | el =
; + | ^^^^^^^^^^^^^^^^^ +> 6 | } finally { + | ^^^^^^^^^^^^^^^^^ +> 7 | console.log(el); + | ^^^^^^^^^^^^^^^^^ +> 8 | } + | ^^^^ Todo: (BuildHIR::lowerStatement) Handle TryStatement without a catch clause (4:8) + 9 | return el; + 10 | } + 11 | +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js new file mode 100644 index 000000000000..f0a17391c0ee --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-invalid-jsx-in-try-with-finally.js @@ -0,0 +1,10 @@ +// @validateNoJSXInTryStatements +function Component(props) { + let el; + try { + el =
; + } finally { + console.log(el); + } + return el; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-no-forget-with-no-errors.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-no-forget-with-no-errors.expect.md new file mode 100644 index 000000000000..20acbe015313 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-no-forget-with-no-errors.expect.md @@ -0,0 +1,35 @@ + +## Input + +```javascript +function Component() { + 'use no forget'; + return
Hello World
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, +}; + +``` + +## Code + +```javascript +function Component() { + "use no forget"; + return
Hello World
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, +}; + +``` + +### Eval output +(kind: ok)
Hello World
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-no-forget-with-no-errors.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-no-forget-with-no-errors.js new file mode 100644 index 000000000000..934487160d55 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-no-forget-with-no-errors.js @@ -0,0 +1,10 @@ +function Component() { + 'use no forget'; + return
Hello World
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/index.ts b/compiler/packages/babel-plugin-react-compiler/src/index.ts index f038246a4f1e..aac65331a0ff 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/index.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/index.ts @@ -18,6 +18,7 @@ export { compileProgram, parsePluginOptions, run, + OPT_OUT_DIRECTIVES, type CompilerPipelineValue, type PluginOptions, } from './Entrypoint'; diff --git a/compiler/packages/eslint-plugin-react-compiler/__tests__/ReactCompilerRule-test.ts b/compiler/packages/eslint-plugin-react-compiler/__tests__/ReactCompilerRule-test.ts index c1aba9f4c840..71be6b6622eb 100644 --- a/compiler/packages/eslint-plugin-react-compiler/__tests__/ReactCompilerRule-test.ts +++ b/compiler/packages/eslint-plugin-react-compiler/__tests__/ReactCompilerRule-test.ts @@ -215,6 +215,65 @@ const tests: CompilerTestCases = { }, ], }, + { + name: "'use no forget' does not disable eslint rule", + code: normalizeIndent` + let count = 0; + function Component() { + 'use no forget'; + count = count + 1; + return
Hello world {count}
+ } + `, + errors: [ + { + message: + 'Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)', + }, + ], + }, + { + name: "Unused 'use no forget' directive is reported when no errors are present on components", + code: normalizeIndent` + function Component() { + 'use no forget'; + return
Hello world
+ } + `, + errors: [ + { + message: "Unused 'use no forget' directive", + suggestions: [ + { + output: + // yuck + '\nfunction Component() {\n \n return
Hello world
\n}\n', + }, + ], + }, + ], + }, + { + name: "Unused 'use no forget' directive is reported when no errors are present on non-components or hooks", + code: normalizeIndent` + function notacomponent() { + 'use no forget'; + return 1 + 1; + } + `, + errors: [ + { + message: "Unused 'use no forget' directive", + suggestions: [ + { + output: + // yuck + '\nfunction notacomponent() {\n \n return 1 + 1;\n}\n', + }, + ], + }, + ], + }, ], }; diff --git a/compiler/packages/eslint-plugin-react-compiler/src/rules/ReactCompilerRule.ts b/compiler/packages/eslint-plugin-react-compiler/src/rules/ReactCompilerRule.ts index 7b6525842c4d..0a0956ebe1db 100644 --- a/compiler/packages/eslint-plugin-react-compiler/src/rules/ReactCompilerRule.ts +++ b/compiler/packages/eslint-plugin-react-compiler/src/rules/ReactCompilerRule.ts @@ -15,10 +15,12 @@ import BabelPluginReactCompiler, { ErrorSeverity, parsePluginOptions, validateEnvironmentConfig, + OPT_OUT_DIRECTIVES, type PluginOptions, } from 'babel-plugin-react-compiler/src'; import {Logger} from 'babel-plugin-react-compiler/src/Entrypoint'; import type {Rule} from 'eslint'; +import {Statement} from 'estree'; import * as HermesParser from 'hermes-parser'; type CompilerErrorDetailWithLoc = Omit & { @@ -146,6 +148,7 @@ const rule: Rule.RuleModule = { userOpts['__unstable_donotuse_reportAllBailouts']; } + let shouldReportUnusedOptOutDirective = true; const options: PluginOptions = { ...parsePluginOptions(userOpts), ...COMPILER_OPTIONS, @@ -155,6 +158,7 @@ const rule: Rule.RuleModule = { logEvent: (filename, event): void => { userLogger?.logEvent(filename, event); if (event.kind === 'CompileError') { + shouldReportUnusedOptOutDirective = false; const detail = event.detail; const suggest = makeSuggestions(detail); if (__unstable_donotuse_reportAllBailouts && event.fnLoc != null) { @@ -272,7 +276,52 @@ const rule: Rule.RuleModule = { /* errors handled by injected logger */ } } - return {}; + + function reportUnusedOptOutDirective(stmt: Statement) { + if ( + stmt.type === 'ExpressionStatement' && + stmt.expression.type === 'Literal' && + typeof stmt.expression.value === 'string' && + OPT_OUT_DIRECTIVES.has(stmt.expression.value) && + stmt.loc != null + ) { + context.report({ + message: `Unused '${stmt.expression.value}' directive`, + loc: stmt.loc, + suggest: [ + { + desc: 'Remove the directive', + fix(fixer) { + return fixer.remove(stmt); + }, + }, + ], + }); + } + } + if (shouldReportUnusedOptOutDirective) { + return { + FunctionDeclaration(fnDecl) { + for (const stmt of fnDecl.body.body) { + reportUnusedOptOutDirective(stmt); + } + }, + ArrowFunctionExpression(fnExpr) { + if (fnExpr.body.type === 'BlockStatement') { + for (const stmt of fnExpr.body.body) { + reportUnusedOptOutDirective(stmt); + } + } + }, + FunctionExpression(fnExpr) { + for (const stmt of fnExpr.body.body) { + reportUnusedOptOutDirective(stmt); + } + }, + }; + } else { + return {}; + } }, }; diff --git a/fixtures/flight/package.json b/fixtures/flight/package.json index a0505629baac..f9b8a752d4f8 100644 --- a/fixtures/flight/package.json +++ b/fixtures/flight/package.json @@ -49,6 +49,7 @@ "react-dev-utils": "^12.0.1", "react-dom": "experimental", "react-refresh": "^0.11.0", + "react-server-dom-webpack": "experimental", "resolve": "^1.20.0", "resolve-url-loader": "^4.0.0", "sass-loader": "^12.3.0", diff --git a/fixtures/flight/yarn.lock b/fixtures/flight/yarn.lock index 927f680a6ca1..36e16f18a998 100644 --- a/fixtures/flight/yarn.lock +++ b/fixtures/flight/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + "@ampproject/remapping@^2.1.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" @@ -2379,6 +2384,23 @@ resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -2620,7 +2642,7 @@ "@jridgewell/set-array" "^1.0.0" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== @@ -2629,36 +2651,52 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" "@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== "@jridgewell/trace-mapping@^0.3.17": version "0.3.18" @@ -2668,6 +2706,22 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -2689,6 +2743,11 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@playwright/test@^1.41.2": version "1.41.2" resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.41.2.tgz#bd9db40177f8fd442e16e14e0389d23751cdfc54" @@ -2960,10 +3019,10 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/graceful-fs@^4.1.2": version "4.1.4" @@ -3092,125 +3151,125 @@ dependencies: "@types/yargs-parser" "*" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== + dependencies: + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -3231,11 +3290,6 @@ abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - accepts@~1.3.5: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -3252,31 +3306,34 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== -acorn-node@^1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" - integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== +acorn-loose@^8.3.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/acorn-loose/-/acorn-loose-8.4.0.tgz#26d3e219756d1e180d006f5bcc8d261a28530f55" + integrity sha512-M0EUka6rb+QC4l9Z3T0nJEzNOO7JcoJlYMrBlyBCiFSXRyxjLKayd4TbQs2FDRWQU1h9FR7QVNHt+PEaoNL5rQ== dependencies: - acorn "^7.0.0" - acorn-walk "^7.0.0" - xtend "^4.0.2" + acorn "^8.11.0" -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.0.0, acorn@^7.1.1: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1: +acorn@^8.11.0, acorn@^8.8.2: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + +acorn@^8.2.4, acorn@^8.7.1: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -3321,7 +3378,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0, ajv-keywords@^5.1.0: +ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== @@ -3338,7 +3395,7 @@ ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.0: +ajv@^8.0.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== @@ -3381,15 +3438,6 @@ ansi-html@^0.0.9: resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.9.tgz#6512d02342ae2cc68131952644a129cb734cd3f0" integrity sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg== -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -3418,6 +3466,16 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" @@ -3450,11 +3508,46 @@ aria-query@^5.0.0: resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array.prototype.reduce@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz#6aadc2f995af29cb887eb866d981dc85ab6f7dc7" + integrity sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-array-method-boxes-properly "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + is-string "^1.0.7" + +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== + dependencies: + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -3476,6 +3569,13 @@ autoprefixer@^10.4.8: picocolors "^1.0.0" postcss-value-parser "^4.2.0" +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + babel-jest@^27.4.2, babel-jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" @@ -3686,7 +3786,14 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.2, braces@~3.0.2: +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== @@ -3706,17 +3813,6 @@ browserslist@^4.0.0: electron-to-chromium "^1.3.73" node-releases "^1.0.0-alpha.12" -browserslist@^4.14.5: - version "4.15.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.15.0.tgz#3d48bbca6a3f378e86102ffd017d9a03f122bdb0" - integrity sha512-IJ1iysdMkGmjjYeRlDU8PQejVwxvVO5QOfXH7ylW31GO6LwNRSmm/SgRXtNsEXqMLl2e+2H5eEJ7sfynF8TCaQ== - dependencies: - caniuse-lite "^1.0.30001164" - colorette "^1.2.1" - electron-to-chromium "^1.3.612" - escalade "^3.1.1" - node-releases "^1.1.67" - browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.20.2, browserslist@^4.20.3, browserslist@^4.21.3: version "4.21.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" @@ -3727,6 +3823,16 @@ browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.20.2, browserslist@^ node-releases "^2.0.6" update-browserslist-db "^1.0.5" +browserslist@^4.21.10, browserslist@^4.21.4: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + browserslist@^4.21.5: version "4.21.9" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" @@ -3772,6 +3878,17 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.0" +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -3813,7 +3930,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000888, caniuse-lite@^1.0.30001164, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000888, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373: version "1.0.30001457" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz" integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== @@ -3823,6 +3940,11 @@ caniuse-lite@^1.0.30001503: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001505.tgz#10a343e49d31cbbfdae298ef73cb0a9f46670dc5" integrity sha512-jaAOR5zVtxHfL0NjZyflVTtXm3D3J9P15zSJ7HmQF8dSKGA6tqzQq+0ZI3xkjyQj46I4/M0K2GbMpcAFOcbr3A== +caniuse-lite@^1.0.30001646: + version "1.0.30001651" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138" + integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== + case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" @@ -3917,6 +4039,15 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -3951,7 +4082,7 @@ color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -color-name@^1.1.4, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -3960,11 +4091,6 @@ colord@^2.9.1: resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== -colorette@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" - integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== - colorette@^2.0.10: version "2.0.19" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" @@ -3981,6 +4107,11 @@ commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" @@ -4092,7 +4223,7 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4307,6 +4438,33 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + date-fns@^2.16.1: version "2.29.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.1.tgz#9667c2615525e552b5135a3116b95b1961456e60" @@ -4358,6 +4516,15 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -4369,10 +4536,14 @@ define-properties@^1.1.2, define-properties@^1.1.3: dependencies: object-keys "^1.0.12" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ== +define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" delayed-stream@~1.0.0: version "1.0.0" @@ -4401,15 +4572,6 @@ detect-port-alt@^1.1.6: address "^1.0.1" debug "^2.6.0" -detective@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034" - integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw== - dependencies: - acorn-node "^1.8.2" - defined "^1.0.0" - minimist "^1.2.6" - didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" @@ -4531,15 +4693,15 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-to-chromium@^1.3.612: - version "1.3.617" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.617.tgz#4192fa4db846c6ad51fffe3a06e71727e9699a74" - integrity sha512-yHXyI0fHnU0oLxdu21otLYpW3qwkbo8EBTpqeS9w14fwNjFy65SG6unrS3Gg+wX1JKWlAFCcNt13fG0nsCo/1A== - electron-to-chromium@^1.3.73: version "1.3.73" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.73.tgz#aa67787067d58cc3920089368b3b8d6fe0fc12f6" @@ -4554,6 +4716,11 @@ electron-to-chromium@^1.4.431: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.435.tgz#761c34300603b9f1234f0b6155870d3002435db6" integrity sha512-B0CBWVFhvoQCW/XtjRzgrmqcgVWg6RXOEM/dK59+wFV93BFGR6AeNKc4OyhM+T3IhJaOOG8o/V+33Y2mwJWtzw== +electron-to-chromium@^1.5.4: + version "1.5.12" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.12.tgz#ee31756eaa2e06f2aa606f170b7ad06dd402b4e4" + integrity sha512-tIhPkdlEoCL1Y+PToq3zRNehUaKp3wBX/sr7aclAWdIWjvqAe/Im/H0SiCM4c1Q8BLPHCdoJTol+ZblflydehA== + emittery@^0.10.2: version "0.10.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" @@ -4568,15 +4735,20 @@ emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== +enhanced-resolve@^5.17.0: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -4618,22 +4790,97 @@ es-abstract@^1.12.0: string.prototype.trimleft "^2.1.0" string.prototype.trimright "^2.1.0" -es-abstract@^1.5.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" +es-abstract@^1.17.2, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: + version "1.23.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" + is-callable "^1.2.7" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.3" + is-string "^1.0.7" + is-typed-array "^1.1.13" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.15" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" + get-intrinsic "^1.2.4" + +es-errors@^1.2.1, es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.5.4" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== -es-to-primitive@^1.1.1, es-to-primitive@^1.2.0: +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + +es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" dependencies: @@ -4641,11 +4888,25 @@ es-to-primitive@^1.1.1, es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -4754,7 +5015,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.2.9: +fast-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== @@ -4765,6 +5026,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -4839,6 +5111,21 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.2" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" @@ -4909,6 +5196,26 @@ function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -4928,14 +5235,16 @@ get-intrinsic@^1.0.0: has "^1.0.3" has-symbols "^1.0.1" -get-intrinsic@^1.0.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" - integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" get-package-type@^0.1.0: version "0.1.0" @@ -4947,6 +5256,15 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== + dependencies: + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -4966,6 +5284,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@^10.3.10: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + glob@^7.1.1, glob@^7.1.2: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" @@ -5007,6 +5337,14 @@ globals@^11.1.0: version "11.8.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" +globalthis@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== + dependencies: + define-properties "^1.2.1" + gopd "^1.0.1" + globby@^11.0.4: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -5019,6 +5357,13 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -5027,6 +5372,11 @@ graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" +graceful-fs@^4.2.11: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + graceful-fs@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" @@ -5048,6 +5398,11 @@ harmony-reflect@^1.4.6: version "1.6.1" resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -5057,6 +5412,18 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -5066,17 +5433,31 @@ has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" dependencies: function-bind "^1.1.1" +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -5255,10 +5636,34 @@ ini@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -5266,30 +5671,36 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" -is-core-module@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" +is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.11.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" - integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== +is-core-module@^2.13.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.0.tgz#71c72ec5442ace7e76b306e9d48db361f22699ea" + integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA== dependencies: - has "^1.0.3" + hasown "^2.0.2" -is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== dependencies: - has "^1.0.3" + is-typed-array "^1.1.13" is-date-object@^1.0.1: version "1.0.1" @@ -5330,6 +5741,18 @@ is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -5346,27 +5769,70 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-root@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== + dependencies: + call-bind "^1.0.7" + is-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" dependencies: has-symbols "^1.0.0" +is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -5374,6 +5840,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -5425,6 +5896,15 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jest-changed-files@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" @@ -5914,7 +6394,12 @@ jest@^27.4.3: import-local "^3.0.2" jest-cli "^27.5.1" -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + +js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -6024,11 +6509,21 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.0.6: +lilconfig@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -6083,10 +6578,6 @@ lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -6109,12 +6600,6 @@ lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - lower-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" @@ -6122,6 +6607,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -6129,13 +6619,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - lz-string@^1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" @@ -6148,11 +6631,12 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: - tmpl "1.0.x" + tmpl "1.0.5" mdn-data@2.0.14: version "2.0.14" @@ -6191,6 +6675,14 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +micromatch@^4.0.5: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -6219,20 +6711,34 @@ mini-css-extract-plugin@^2.4.5: dependencies: schema-utils "^4.0.0" -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: brace-expansion "^1.1.7" +minimatch@^3.0.5: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== mkdirp@~0.5.1: version "0.5.1" @@ -6253,11 +6759,25 @@ ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -6267,7 +6787,7 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.6.2: +neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -6290,16 +6810,16 @@ node-releases@^1.0.0-alpha.12: dependencies: semver "^5.3.0" -node-releases@^1.1.67: - version "1.1.67" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" - integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== - node-releases@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" @@ -6321,13 +6841,6 @@ nodemon@^2.0.19: touch "^3.1.0" undefsafe "^2.0.5" -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -6366,20 +6879,25 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-hash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + object-inspect@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - object-keys@^1.0.11, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -6397,12 +6915,28 @@ object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" +object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz#2f1fe0606ec1a7658154ccd4f728504f69667923" + integrity sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A== + dependencies: + array.prototype.reduce "^1.0.6" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + gopd "^1.0.1" + safe-array-concat "^1.1.2" object.values@^1.1.0: version "1.1.0" @@ -6502,6 +7036,11 @@ p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" +package-json-from-dist@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" + integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -6567,15 +7106,19 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.5, path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -6591,6 +7134,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -6606,6 +7154,11 @@ pify@^2.3.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -6639,6 +7192,11 @@ playwright@1.41.2: optionalDependencies: fsevents "2.3.2" +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + postcss-attribute-case-insensitive@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" @@ -6804,10 +7362,10 @@ postcss-image-set-function@^4.0.7: dependencies: postcss-value-parser "^4.2.0" -postcss-import@^14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" - integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== dependencies: postcss-value-parser "^4.0.0" read-cache "^1.0.0" @@ -6818,10 +7376,10 @@ postcss-initial@^4.0.1: resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== -postcss-js@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" - integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== dependencies: camelcase-css "^2.0.1" @@ -6833,13 +7391,13 @@ postcss-lab-function@^4.2.1: "@csstools/postcss-progressive-custom-properties" "^1.1.0" postcss-value-parser "^4.2.0" -postcss-load-config@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" - integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== dependencies: - lilconfig "^2.0.5" - yaml "^1.10.2" + lilconfig "^3.0.0" + yaml "^2.3.4" postcss-loader@^6.2.1: version "6.2.1" @@ -6938,12 +7496,12 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nested@5.0.6: - version "5.0.6" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc" - integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA== +postcss-nested@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" + integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ== dependencies: - postcss-selector-parser "^6.0.6" + postcss-selector-parser "^6.1.1" postcss-nesting@^10.1.10: version "10.1.10" @@ -7146,7 +7704,7 @@ postcss-selector-not@^6.0.1: dependencies: postcss-selector-parser "^6.0.10" -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.0.10" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== @@ -7154,6 +7712,14 @@ postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4, postcss-selecto cssesc "^3.0.0" util-deprecate "^1.0.2" +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + postcss-selector-parser@^6.0.2: version "6.0.4" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" @@ -7197,7 +7763,7 @@ postcss@^7.0.35: picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.3.5, postcss@^8.4.14, postcss@^8.4.4, postcss@^8.4.7: +postcss@^8.3.5, postcss@^8.4.4, postcss@^8.4.7: version "8.4.16" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== @@ -7206,6 +7772,15 @@ postcss@^8.3.5, postcss@^8.4.14, postcss@^8.4.4, postcss@^8.4.7: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.23: + version "8.4.41" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" + integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -7282,10 +7857,15 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== randombytes@^2.1.0: version "2.1.0" @@ -7339,12 +7919,11 @@ react-dev-utils@^12.0.1: text-table "^0.2.0" react-dom@experimental: - version "0.0.0-experimental-6ff1733e6-20230225" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-6ff1733e6-20230225.tgz#47c1e80f21230e6c650ba9e43d15fccd616441be" - integrity sha512-1vGCQDhmSOwBIb8QbTaSjBUysebPhl7WCcGuT6dW+HdlxFDvClL0M47K1e8kZWiuCkMUDjJaTlC4J32PgznbFw== + version "0.0.0-experimental-6ebfd5b0-20240818" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-6ebfd5b0-20240818.tgz#8a0b45fc4d54d45442e5194edee0114a8132bc82" + integrity sha512-G+RipTMyLYgSz4lST+8RFzP/Zdl8JaW0iWq5Yk9nG/rkdT7riWQrrMG9ZpRAxpRbBbaZ8WIgZqX5JFvRcJjyDQ== dependencies: - loose-envify "^1.1.0" - scheduler "0.0.0-experimental-6ff1733e6-20230225" + scheduler "0.0.0-experimental-6ebfd5b0-20240818" react-error-overlay@^6.0.11: version "6.0.11" @@ -7366,12 +7945,19 @@ react-refresh@^0.11.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== -react@experimental: - version "0.0.0-experimental-6ff1733e6-20230225" - resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-6ff1733e6-20230225.tgz#24bca9d60c6b3597f389e8bcd07e7b853dddc917" - integrity sha512-5syUtEwwbWzDHN84xNu9C9cciLW9sY4c19fG27EU5ApS1s+i7fFtS+KtyPMHU9S4eK0u65uQU3hWMqFvqzLHhw== +react-server-dom-webpack@experimental: + version "0.0.0-experimental-6ebfd5b0-20240818" + resolved "https://registry.yarnpkg.com/react-server-dom-webpack/-/react-server-dom-webpack-0.0.0-experimental-6ebfd5b0-20240818.tgz#56df6a7a406a033897f9bdd33b649e6e956adcef" + integrity sha512-kDPLVKaSKwDpuxGKxWS4w0VEY1O0IUJVksfA39H7nENjmFCuHybZ6rvi+hlXgJcwV3TvVeISLSmf27yvZWUriQ== dependencies: - loose-envify "^1.1.0" + acorn-loose "^8.3.0" + neo-async "^2.6.1" + webpack-sources "^3.2.3" + +react@experimental: + version "0.0.0-experimental-6ebfd5b0-20240818" + resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-6ebfd5b0-20240818.tgz#80ed47abae164ace0006ef5e5931383ddb8964ae" + integrity sha512-Wkw/YNSnolRlb4q2IF738W9zDLATEDe0TLnFZJBFgb3bXLQomxChEqFG1Z2upuh0nhdnlJylCN2Q8ammQsbQLg== read-cache@^1.0.0: version "1.0.0" @@ -7388,11 +7974,11 @@ readdirp@~3.6.0: picomatch "^2.2.1" recursive-readdir@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" - integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + version "2.2.3" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== dependencies: - minimatch "3.0.4" + minimatch "^3.0.5" redent@^3.0.0: version "3.0.0" @@ -7402,88 +7988,65 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -regenerate-unicode-properties@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" - integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" - integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== dependencies: regenerate "^1.4.2" -regenerate-unicode-properties@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" +regenerate-unicode-properties@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" + integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + regenerate "^1.4.2" regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.11: +regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.4: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== - dependencies: - "@babel/runtime" "^7.8.4" - -regenerator-transform@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" - integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== +regenerator-transform@^0.15.0, regenerator-transform@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== dependencies: "@babel/runtime" "^7.8.4" regex-parser@^2.2.11: - version "2.2.11" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" - integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + version "2.3.0" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.3.0.tgz#4bb61461b1a19b8b913f3960364bb57887f920ee" + integrity sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg== -regexpu-core@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" +regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.1.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" -regexpu-core@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" - integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== +regexpu-core@^4.6.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" + integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== dependencies: regenerate "^1.4.2" - regenerate-unicode-properties "^10.0.1" - regjsgen "^0.6.0" - regjsparser "^0.8.2" + regenerate-unicode-properties "^9.0.0" + regjsgen "^0.5.2" + regjsparser "^0.7.0" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -regexpu-core@^5.3.1: +regexpu-core@^5.1.0, regexpu-core@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== @@ -7495,25 +8058,15 @@ regexpu-core@^5.3.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" -regjsgen@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" - -regjsgen@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" - integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== - -regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - dependencies: - jsesc "~0.5.0" +regjsgen@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== -regjsparser@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" - integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== +regjsparser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" + integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== dependencies: jsesc "~0.5.0" @@ -7527,7 +8080,7 @@ regjsparser@^0.9.1: relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== renderkid@^3.0.0: version "3.0.0" @@ -7543,12 +8096,18 @@ renderkid@^3.0.0: require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -7559,6 +8118,7 @@ resolve-cwd@^3.0.0: resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" @@ -7577,42 +8137,19 @@ resolve-url-loader@^4.0.0: source-map "0.6.1" resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== - -resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.14.2: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== - dependencies: - is-core-module "^2.1.0" - path-parse "^1.0.6" + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== -resolve@^1.19.0: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== +resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.3.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.11.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.3.2: - version "1.8.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - dependencies: - path-parse "^1.0.5" - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -7626,24 +8163,52 @@ rimraf@^3.0.0: glob "^7.1.3" run-parallel@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" - integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" rxjs@^7.0.0: - version "7.5.6" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" - integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" -safe-buffer@5.1.2, safe-buffer@^5.1.0, safe-buffer@~5.1.1: +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-buffer@5.1.2, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-regex "^1.1.4" "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sanitize.css@*: version "13.0.0" @@ -7661,6 +8226,7 @@ sass-loader@^12.3.0: sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== saxes@^5.0.1: version "5.0.1" @@ -7669,12 +8235,10 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -scheduler@0.0.0-experimental-6ff1733e6-20230225: - version "0.0.0-experimental-6ff1733e6-20230225" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-experimental-6ff1733e6-20230225.tgz#9de04947f82afa784de799aa09aaad92ee67cb19" - integrity sha512-YDyRM4ohU6NmzsbiJ/UUdRB4ulz27n+3Su8LZ8cENrQDuu2us3sPN+y8CMGeqaNYJlS0GQTHNcLa2LZIK9BP5Q== - dependencies: - loose-envify "^1.1.0" +scheduler@0.0.0-experimental-6ebfd5b0-20240818: + version "0.0.0-experimental-6ebfd5b0-20240818" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-experimental-6ebfd5b0-20240818.tgz#583c91937f8fdde51726cf1735cdb323eb86adf2" + integrity sha512-/a4bME9pxUZOLPL8ktBU4JtqYXPk2lRslukGB93gWygXbSoNpdVfVFoSyiUlLk1bDXN0iV5NaKv3PWHOhmOn+w== schema-utils@2.7.0: version "2.7.0" @@ -7694,7 +8258,7 @@ schema-utils@^2.6.5: ajv "^6.12.4" ajv-keywords "^3.5.2" -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -7703,17 +8267,7 @@ schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -schema-utils@^4.2.0: +schema-utils@^4.0.0, schema-utils@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== @@ -7728,39 +8282,49 @@ semver@7.0.0, semver@~7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^5.3.0, semver@^5.4.1: - version "5.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" - -semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@^5.3.0, semver@^5.4.1, semver@^5.7.1: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== +semver@^7.3.2, semver@^7.3.5: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: - lru-cache "^6.0.0" + randombytes "^2.1.0" -semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== dependencies: - lru-cache "^6.0.0" + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +set-function-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: - randombytes "^2.1.0" + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" setprototypeof@1.2.0: version "1.2.0" @@ -7780,40 +8344,38 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" -signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -signal-exit@^3.0.3: +signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-update-notifier@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" - integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== + version "1.1.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== dependencies: semver "~7.0.0" -sisteransi@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" - -sisteransi@^1.0.5: +sisteransi@^1.0.3, sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== @@ -7821,6 +8383,7 @@ sisteransi@^1.0.5: slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slash@^4.0.0: version "4.0.0" @@ -7832,28 +8395,21 @@ source-list-map@^2.0.1: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-js@^1.0.1, source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== source-map-loader@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" - integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.2.tgz#af23192f9b344daa729f6772933194cc5fa54fee" + integrity sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg== dependencies: abab "^2.0.5" iconv-lite "^0.6.3" source-map-js "^1.0.1" -source-map-support@^0.5.6: - version "0.5.9" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@~0.5.20: +source-map-support@^0.5.6, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -7864,10 +8420,12 @@ source-map-support@~0.5.20: source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== source-map@^0.7.3: version "0.7.4" @@ -7875,22 +8433,24 @@ source-map@^0.7.3: integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== spawn-command@^0.0.2-1: - version "0.0.2-1" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" - integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== + version "0.0.2" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e" + integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ== sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" @@ -7910,9 +8470,9 @@ streamsearch@^1.1.0: integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== string-length@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" - integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" strip-ansi "^6.0.0" @@ -7925,24 +8485,7 @@ string-length@^5.0.1: char-regex "^2.0.0" strip-ansi "^7.0.1" -string-width@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff" - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^5.2.0" - -string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7951,34 +8494,62 @@ string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" + +string.prototype.trimend@^1.0.3, string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + string.prototype.trimleft@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + version "2.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.3.tgz#dee305118117d0a1843c1fc0d38d5d0754d83c60" + integrity sha512-699Ibssmj/awVzvdNk4g83/Iu8U9vDohzmA/ly2BrQWGhamuY4Tlvs5XKmKliDt3ky6SKbE1bzPhASKCFlx9Sg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - function-bind "^1.1.1" + string.prototype.trimstart "^1.0.3" string.prototype.trimright@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + version "2.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.3.tgz#dc16a21d7456cbc8b2c54d47fe01f06d9efe94eb" + integrity sha512-hoOq56oRFnnfDuXNy2lGHiwT77MehHv9d0zGfRZ8QdC+4zjrkFB9vd5i/zYTd/ymFBd4YxtbdgHt3U6ksGeuBw== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - function-bind "^1.1.1" - -strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - dependencies: - ansi-regex "^4.1.0" + string.prototype.trimend "^1.0.3" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +string.prototype.trimstart@^1.0.3, string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: - ansi-regex "^5.0.0" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -7986,9 +8557,9 @@ strip-ansi@^6.0.1: ansi-regex "^5.0.1" strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" @@ -8015,21 +8586,35 @@ strip-json-comments@^3.1.1: integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + version "3.3.4" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" + integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== stylehacks@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" - integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== + version "5.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" postcss-selector-parser "^6.0.4" +sucrase@^3.32.0: + version "3.35.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" @@ -8048,9 +8633,9 @@ supports-color@^8.0.0, supports-color@^8.1.0: has-flag "^4.0.0" supports-hyperlinks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" - integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== dependencies: has-flag "^4.0.0" supports-color "^7.0.0" @@ -8068,6 +8653,7 @@ svg-parser@^2.0.2: svgo@^1.2.2: version "1.3.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== dependencies: chalk "^2.4.1" coa "^2.0.2" @@ -8102,36 +8688,37 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== tailwindcss@^3.0.2: - version "3.1.8" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.8.tgz#4f8520550d67a835d32f2f4021580f9fddb7b741" - integrity sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g== + version "3.4.10" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.10.tgz#70442d9aeb78758d1f911af29af8255ecdb8ffef" + integrity sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w== dependencies: + "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" chokidar "^3.5.3" - color-name "^1.1.4" - detective "^5.2.1" didyoumean "^1.2.2" dlv "^1.1.3" - fast-glob "^3.2.11" + fast-glob "^3.3.0" glob-parent "^6.0.2" is-glob "^4.0.3" - lilconfig "^2.0.6" + jiti "^1.21.0" + lilconfig "^2.1.0" + micromatch "^4.0.5" normalize-path "^3.0.0" object-hash "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.14" - postcss-import "^14.1.0" - postcss-js "^4.0.0" - postcss-load-config "^3.1.4" - postcss-nested "5.0.6" - postcss-selector-parser "^6.0.10" - postcss-value-parser "^4.2.0" - quick-lru "^5.1.1" - resolve "^1.22.1" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" tapable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" @@ -8146,24 +8733,24 @@ terminal-link@^2.0.0: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" -terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5: - version "5.3.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz#f7d82286031f915a4f8fb81af4bd35d2e3c011bc" - integrity sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA== +terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.20" jest-worker "^27.4.5" schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" -terser@^5.10.0, terser@^5.14.1: - version "5.14.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" - integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== +terser@^5.10.0, terser@^5.26.0: + version "5.31.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" + integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" @@ -8179,19 +8766,36 @@ test-exclude@^6.0.0: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + version "6.0.2" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" + integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-regex-range@^5.0.1: version "5.0.1" @@ -8206,27 +8810,19 @@ toidentifier@1.0.1: integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" + version "3.1.1" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" + integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA== tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + version "4.1.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== dependencies: psl "^1.1.33" punycode "^2.1.1" - universalify "^0.1.2" - -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== - dependencies: - punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" tr46@^2.1.0: version "2.1.0" @@ -8240,23 +8836,25 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -tslib@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== -tslib@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" - integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== +tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@^2.0.3, tslib@^2.1.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: prelude-ls "~1.1.2" @@ -8273,6 +8871,7 @@ type-fest@^0.11.0: type-fest@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== type-is@~1.6.18: version "1.6.18" @@ -8282,6 +8881,50 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -8289,34 +8932,33 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== undici@^5.20.0: - version "5.20.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.20.0.tgz#6327462f5ce1d3646bcdac99da7317f455bcc263" - integrity sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g== + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== dependencies: - busboy "^1.6.0" - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + "@fastify/busboy" "^2.0.0" unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - unicode-match-property-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" @@ -8325,66 +8967,48 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== - -unicode-match-property-value-ecmascript@^2.1.0: +unicode-match-property-value-ecmascript@^2.0.0, unicode-match-property-value-ecmascript@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" - unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA== -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unquote@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== -update-browserslist-db@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -update-browserslist-db@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" - integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== +update-browserslist-db@^1.0.11, update-browserslist-db@^1.0.5, update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.1.2" + picocolors "^1.0.1" uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" @@ -8393,20 +9017,33 @@ uri-js@^4.2.2, uri-js@^4.4.1: dependencies: punycode "^2.1.0" +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util.promisify@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== v8-to-istanbul@^8.1.0: version "8.1.1" @@ -8437,15 +9074,16 @@ w3c-xmlserializer@^2.0.0: xml-name-validator "^3.0.0" walker@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - makeerror "1.0.x" + makeerror "1.0.12" -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -8472,9 +9110,9 @@ webpack-dev-middleware@^5.3.4: schema-utils "^4.0.0" webpack-hot-middleware@^2.25.3: - version "2.25.3" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz#be343ce2848022cfd854dd82820cd730998c6794" - integrity sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA== + version "2.26.1" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" + integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== dependencies: ansi-html-community "0.0.8" html-entities "^2.1.0" @@ -8502,55 +9140,48 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.64.4: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + version "5.93.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.93.0.tgz#2e89ec7035579bdfba9760d26c63ac5c3462a5e5" + integrity sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^8.0.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" - integrity sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^2.0.2" - webidl-conversions "^6.1.0" - -whatwg-url@^8.5.0: +whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== @@ -8559,9 +9190,32 @@ whatwg-url@^8.5.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-typed-array@^1.1.14, which-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" @@ -8575,8 +9229,9 @@ which@^2.0.1: wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -8585,9 +9240,19 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^3.0.0: version "3.0.3" @@ -8600,24 +9265,20 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -8628,27 +9289,22 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0, yaml@^1.7.2: - version "1.10.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" - integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== - -yaml@^1.10.2: +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" + integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.0.0: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -8667,17 +9323,17 @@ yargs@^16.2.0: yargs-parser "^20.2.2" yargs@^17.3.1: - version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^21.0.0" + yargs-parser "^21.1.1" yocto-queue@^0.1.0: version "0.1.0" diff --git a/package.json b/package.json index 4507b9b8e6c6..2bcbda538c96 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "publish-prereleases": "echo 'This command has been deprecated. Please refer to https://github.com/facebook/react/tree/main/scripts/release#trigger-an-automated-prerelease'", "download-build": "node ./scripts/release/download-experimental-build.js", "download-build-for-head": "node ./scripts/release/download-experimental-build.js --commit=$(git rev-parse HEAD)", - "download-build-in-codesandbox-ci": "yarn build --type=node react/index react-dom/index react-dom/src/server react-dom/test-utils scheduler/index react/jsx-runtime react/jsx-dev-runtime", + "download-build-in-codesandbox-ci": "yarn build --type=node react/index react-dom/index react-dom/client react-dom/src/server react-dom/test-utils scheduler/index react/jsx-runtime react/jsx-dev-runtime", "check-release-dependencies": "node ./scripts/release/check-release-dependencies", "generate-inline-fizz-runtime": "node ./scripts/rollup/generate-inline-fizz-runtime.js", "flags": "node ./scripts/flags/flags.js" diff --git a/packages/internal-test-utils/ReactInternalTestUtils.js b/packages/internal-test-utils/ReactInternalTestUtils.js index 4d2fa3789085..317a07262c5a 100644 --- a/packages/internal-test-utils/ReactInternalTestUtils.js +++ b/packages/internal-test-utils/ReactInternalTestUtils.js @@ -16,7 +16,7 @@ import { clearErrors, createLogAssertion, } from './consoleMock'; -export {act} from './internalAct'; +export {act, serverAct} from './internalAct'; const {assertConsoleLogsCleared} = require('internal-test-utils/consoleMock'); import {thrownErrors, actingUpdatesScopeDepth} from './internalAct'; diff --git a/packages/internal-test-utils/internalAct.js b/packages/internal-test-utils/internalAct.js index 22bb92c24fc2..66fa32498450 100644 --- a/packages/internal-test-utils/internalAct.js +++ b/packages/internal-test-utils/internalAct.js @@ -192,3 +192,90 @@ export async function act(scope: () => Thenable): Thenable { } } } + +export async function serverAct(scope: () => Thenable): Thenable { + // We require every `act` call to assert console logs + // with one of the assertion helpers. Fails if not empty. + assertConsoleLogsCleared(); + + // $FlowFixMe[cannot-resolve-name]: Flow doesn't know about global Jest object + if (!jest.isMockFunction(setTimeout)) { + throw Error( + "This version of `act` requires Jest's timer mocks " + + '(i.e. jest.useFakeTimers).', + ); + } + + // Create the error object before doing any async work, to get a better + // stack trace. + const error = new Error(); + Error.captureStackTrace(error, act); + + // Call the provided scope function after an async gap. This is an extra + // precaution to ensure that our tests do not accidentally rely on the act + // scope adding work to the queue synchronously. We don't do this in the + // public version of `act`, though we maybe should in the future. + await waitForMicrotasks(); + + const errorHandlerNode = function (err: mixed) { + thrownErrors.push(err); + }; + // We track errors that were logged globally as if they occurred in this scope and then rethrow them. + if (typeof process === 'object') { + // Node environment + process.on('uncaughtException', errorHandlerNode); + } else if ( + typeof window === 'object' && + typeof window.addEventListener === 'function' + ) { + throw new Error('serverAct is not supported in JSDOM environments'); + } + + try { + const result = await scope(); + + do { + // Wait until end of current task/microtask. + await waitForMicrotasks(); + + // $FlowFixMe[cannot-resolve-name]: Flow doesn't know about global Jest object + if (jest.isEnvironmentTornDown()) { + error.message = + 'The Jest environment was torn down before `act` completed. This ' + + 'probably means you forgot to `await` an `act` call.'; + throw error; + } + + // $FlowFixMe[cannot-resolve-name]: Flow doesn't know about global Jest object + const j = jest; + if (j.getTimerCount() > 0) { + // There's a pending timer. Flush it now. We only do this in order to + // force Suspense fallbacks to display; the fact that it's a timer + // is an implementation detail. If there are other timers scheduled, + // those will also fire now, too, which is not ideal. (The public + // version of `act` doesn't do this.) For this reason, we should try + // to avoid using timers in our internal tests. + j.runOnlyPendingTimers(); + // If a committing a fallback triggers another update, it might not + // get scheduled until a microtask. So wait one more time. + await waitForMicrotasks(); + } else { + break; + } + } while (true); + + if (thrownErrors.length > 0) { + // Rethrow any errors logged by the global error handling. + const thrownError = aggregateErrors(thrownErrors); + thrownErrors.length = 0; + throw thrownError; + } + + return result; + } finally { + if (typeof process === 'object') { + // Node environment + process.off('uncaughtException', errorHandlerNode); + } + } +} diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 564f4e859871..072df8108fcc 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -13,6 +13,7 @@ import type { ReactComponentInfo, ReactAsyncInfo, ReactStackTrace, + ReactCallSite, } from 'shared/ReactTypes'; import type {LazyComponent} from 'react/src/ReactLazy'; @@ -59,7 +60,7 @@ import { bindToConsole, } from './ReactFlightClientConfig'; -import {registerServerReference} from './ReactFlightReplyClient'; +import {createBoundServerReference} from './ReactFlightReplyClient'; import {readTemporaryReference} from './ReactFlightTemporaryReferences'; @@ -189,7 +190,12 @@ type SomeChunk = | ErroredChunk; // $FlowFixMe[missing-this-annot] -function Chunk(status: any, value: any, reason: any, response: Response) { +function ReactPromise( + status: any, + value: any, + reason: any, + response: Response, +) { this.status = status; this.value = value; this.reason = reason; @@ -199,9 +205,9 @@ function Chunk(status: any, value: any, reason: any, response: Response) { } } // We subclass Promise.prototype so that we get other methods like .catch -Chunk.prototype = (Object.create(Promise.prototype): any); +ReactPromise.prototype = (Object.create(Promise.prototype): any); // TODO: This doesn't return a new Promise chain unlike the real .then -Chunk.prototype.then = function ( +ReactPromise.prototype.then = function ( this: SomeChunk, resolve: (value: T) => mixed, reject?: (reason: mixed) => mixed, @@ -302,12 +308,12 @@ export function getRoot(response: Response): Thenable { function createPendingChunk(response: Response): PendingChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(PENDING, null, null, response); + return new ReactPromise(PENDING, null, null, response); } function createBlockedChunk(response: Response): BlockedChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(BLOCKED, null, null, response); + return new ReactPromise(BLOCKED, null, null, response); } function createErrorChunk( @@ -315,7 +321,7 @@ function createErrorChunk( error: Error | Postpone, ): ErroredChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(ERRORED, null, error, response); + return new ReactPromise(ERRORED, null, error, response); } function wakeChunk(listeners: Array<(T) => mixed>, value: T): void { @@ -389,7 +395,7 @@ function createResolvedModelChunk( value: UninitializedModel, ): ResolvedModelChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(RESOLVED_MODEL, value, null, response); + return new ReactPromise(RESOLVED_MODEL, value, null, response); } function createResolvedModuleChunk( @@ -397,7 +403,7 @@ function createResolvedModuleChunk( value: ClientReference, ): ResolvedModuleChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(RESOLVED_MODULE, value, null, response); + return new ReactPromise(RESOLVED_MODULE, value, null, response); } function createInitializedTextChunk( @@ -405,7 +411,7 @@ function createInitializedTextChunk( value: string, ): InitializedChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(INITIALIZED, value, null, response); + return new ReactPromise(INITIALIZED, value, null, response); } function createInitializedBufferChunk( @@ -413,7 +419,7 @@ function createInitializedBufferChunk( value: $ArrayBufferView | ArrayBuffer, ): InitializedChunk { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(INITIALIZED, value, null, response); + return new ReactPromise(INITIALIZED, value, null, response); } function createInitializedIteratorResultChunk( @@ -422,7 +428,12 @@ function createInitializedIteratorResultChunk( done: boolean, ): InitializedChunk> { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(INITIALIZED, {done: done, value: value}, null, response); + return new ReactPromise( + INITIALIZED, + {done: done, value: value}, + null, + response, + ); } function createInitializedStreamChunk< @@ -435,7 +446,7 @@ function createInitializedStreamChunk< // We use the reason field to stash the controller since we already have that // field. It's a bit of a hack but efficient. // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(INITIALIZED, value, controller, response); + return new ReactPromise(INITIALIZED, value, controller, response); } function createResolvedIteratorResultChunk( @@ -447,7 +458,7 @@ function createResolvedIteratorResultChunk( const iteratorResultJSON = (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + '}'; // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk(RESOLVED_MODEL, iteratorResultJSON, null, response); + return new ReactPromise(RESOLVED_MODEL, iteratorResultJSON, null, response); } function resolveIteratorResultChunk( @@ -1001,30 +1012,20 @@ function waitForReference( function createServerReferenceProxy, T>( response: Response, - metaData: {id: any, bound: null | Thenable>}, + metaData: { + id: any, + bound: null | Thenable>, + name?: string, // DEV-only + env?: string, // DEV-only + location?: ReactCallSite, // DEV-only + }, ): (...A) => Promise { - const callServer = response._callServer; - const proxy = function (): Promise { - // $FlowFixMe[method-unbinding] - const args = Array.prototype.slice.call(arguments); - const p = metaData.bound; - if (!p) { - return callServer(metaData.id, args); - } - if (p.status === INITIALIZED) { - const bound = p.value; - return callServer(metaData.id, bound.concat(args)); - } - // Since this is a fake Promise whose .then doesn't chain, we have to wrap it. - // TODO: Remove the wrapper once that's fixed. - return ((Promise.resolve(p): any): Promise>).then( - function (bound) { - return callServer(metaData.id, bound.concat(args)); - }, - ); - }; - registerServerReference(proxy, metaData, response._encodeFormAction); - return proxy; + return createBoundServerReference( + metaData, + response._callServer, + response._encodeFormAction, + __DEV__ ? response._debugFindSourceMapURL : undefined, + ); } function getOutlinedModel( @@ -1769,7 +1770,7 @@ function startAsyncIterable( if (nextReadIndex === buffer.length) { if (closed) { // $FlowFixMe[invalid-constructor] Flow doesn't support functions as constructors - return new Chunk( + return new ReactPromise( INITIALIZED, {done: true, value: undefined}, null, @@ -2677,6 +2678,7 @@ export function processBinaryChunk( i++; } else if ( (resolvedRowTag > 64 && resolvedRowTag < 91) /* "A"-"Z" */ || + resolvedRowTag === 35 /* "#" */ || resolvedRowTag === 114 /* "r" */ || resolvedRowTag === 120 /* "x" */ ) { diff --git a/packages/react-client/src/ReactFlightReplyClient.js b/packages/react-client/src/ReactFlightReplyClient.js index c4033a999d96..233f51844e2a 100644 --- a/packages/react-client/src/ReactFlightReplyClient.js +++ b/packages/react-client/src/ReactFlightReplyClient.js @@ -13,6 +13,7 @@ import type { FulfilledThenable, RejectedThenable, ReactCustomFormAction, + ReactCallSite, } from 'shared/ReactTypes'; import type {LazyComponent} from 'react/src/ReactLazy'; import type {TemporaryReferenceSet} from './ReactFlightTemporaryReferences'; @@ -1023,7 +1024,99 @@ function isSignatureEqual( } } -export function registerServerReference( +let fakeServerFunctionIdx = 0; + +function createFakeServerFunction, T>( + name: string, + filename: string, + sourceMap: null | string, + line: number, + col: number, + environmentName: string, + innerFunction: (...A) => Promise, +): (...A) => Promise { + // This creates a fake copy of a Server Module. It represents the Server Action on the server. + // We use an eval so we can source map it to the original location. + + const comment = + '/* This module is a proxy to a Server Action. Turn on Source Maps to see the server source. */'; + + if (!name) { + // An eval:ed function with no name gets the name "eval". We give it something more descriptive. + name = ''; + } + const encodedName = JSON.stringify(name); + // We generate code where both the beginning of the function and its parenthesis is at the line + // and column of the server executed code. We use a method form since that lets us name it + // anything we want and because the beginning of the function and its parenthesis is the same + // column. Because Chrome inspects the location of the parenthesis and Firefox inspects the + // location of the beginning of the function. By not using a function expression we avoid the + // ambiguity. + let code; + if (line <= 1) { + const minSize = encodedName.length + 7; + code = + 's=>({' + + encodedName + + ' '.repeat(col < minSize ? 0 : col - minSize) + + ':' + + '(...args) => s(...args)' + + '})\n' + + comment; + } else { + code = + comment + + '\n'.repeat(line - 2) + + 'server=>({' + + encodedName + + ':\n' + + ' '.repeat(col < 1 ? 0 : col - 1) + + // The function body can get printed so we make it look nice. + // This "calls the server with the arguments". + '(...args) => server(...args)' + + '})'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; + } + + if (sourceMap) { + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += + '\n//# sourceURL=rsc://React/' + + encodeURIComponent(environmentName) + + '/' + + filename + + '?s' + // We add an extra s here to distinguish from the fake stack frames + fakeServerFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; + } else if (filename) { + code += '\n//# sourceURL=' + filename; + } + + try { + // Eval a factory and then call it to create a closure over the inner function. + // eslint-disable-next-line no-eval + return (0, eval)(code)(innerFunction)[name]; + } catch (x) { + // If eval fails, such as if in an environment that doesn't support it, + // we fallback to just returning the inner function. + return innerFunction; + } +} + +function registerServerReference( proxy: any, reference: {id: ServerReferenceId, bound: null | Thenable>}, encodeFormAction: void | EncodeFormActionCallback, @@ -1098,16 +1191,163 @@ function bind(this: Function): Function { return newFn; } +export type FindSourceMapURLCallback = ( + fileName: string, + environmentName: string, +) => null | string; + +export function createBoundServerReference, T>( + metaData: { + id: ServerReferenceId, + bound: null | Thenable>, + name?: string, // DEV-only + env?: string, // DEV-only + location?: ReactCallSite, // DEV-only + }, + callServer: CallServerCallback, + encodeFormAction?: EncodeFormActionCallback, + findSourceMapURL?: FindSourceMapURLCallback, // DEV-only +): (...A) => Promise { + const id = metaData.id; + const bound = metaData.bound; + let action = function (): Promise { + // $FlowFixMe[method-unbinding] + const args = Array.prototype.slice.call(arguments); + const p = bound; + if (!p) { + return callServer(id, args); + } + if (p.status === 'fulfilled') { + const boundArgs = p.value; + return callServer(id, boundArgs.concat(args)); + } + // Since this is a fake Promise whose .then doesn't chain, we have to wrap it. + // TODO: Remove the wrapper once that's fixed. + return ((Promise.resolve(p): any): Promise>).then( + function (boundArgs) { + return callServer(id, boundArgs.concat(args)); + }, + ); + }; + if (__DEV__) { + const location = metaData.location; + if (location) { + const functionName = metaData.name || ''; + const [, filename, line, col] = location; + const env = metaData.env || 'Server'; + const sourceMap = + findSourceMapURL == null ? null : findSourceMapURL(filename, env); + action = createFakeServerFunction( + functionName, + filename, + sourceMap, + line, + col, + env, + action, + ); + } + } + registerServerReference(action, {id, bound}, encodeFormAction); + return action; +} + +// This matches either of these V8 formats. +// at name (filename:0:0) +// at filename:0:0 +// at async filename:0:0 +const v8FrameRegExp = + /^ {3} at (?:(.+) \((.+):(\d+):(\d+)\)|(?:async )?(.+):(\d+):(\d+))$/; +// This matches either of these JSC/SpiderMonkey formats. +// name@filename:0:0 +// filename:0:0 +const jscSpiderMonkeyFrameRegExp = /(?:(.*)@)?(.*):(\d+):(\d+)/; + +function parseStackLocation(error: Error): null | ReactCallSite { + // This parsing is special in that we know that the calling function will always + // be a module that initializes the server action. We also need this part to work + // cross-browser so not worth a Config. It's DEV only so not super code size + // sensitive but also a non-essential feature. + let stack = error.stack; + if (stack.startsWith('Error: react-stack-top-frame\n')) { + // V8's default formatting prefixes with the error message which we + // don't want/need. + stack = stack.slice(29); + } + const endOfFirst = stack.indexOf('\n'); + let secondFrame; + if (endOfFirst !== -1) { + // Skip the first frame. + const endOfSecond = stack.indexOf('\n', endOfFirst + 1); + if (endOfSecond === -1) { + secondFrame = stack.slice(endOfFirst + 1); + } else { + secondFrame = stack.slice(endOfFirst + 1, endOfSecond); + } + } else { + secondFrame = stack; + } + + let parsed = v8FrameRegExp.exec(secondFrame); + if (!parsed) { + parsed = jscSpiderMonkeyFrameRegExp.exec(secondFrame); + if (!parsed) { + return null; + } + } + + let name = parsed[1] || ''; + if (name === '') { + name = ''; + } + let filename = parsed[2] || parsed[5] || ''; + if (filename === '') { + filename = ''; + } + const line = +(parsed[3] || parsed[6]); + const col = +(parsed[4] || parsed[7]); + + return [name, filename, line, col]; +} + export function createServerReference, T>( id: ServerReferenceId, callServer: CallServerCallback, encodeFormAction?: EncodeFormActionCallback, + findSourceMapURL?: FindSourceMapURLCallback, // DEV-only + functionName?: string, ): (...A) => Promise { - const proxy = function (): Promise { + let action = function (): Promise { // $FlowFixMe[method-unbinding] const args = Array.prototype.slice.call(arguments); return callServer(id, args); }; - registerServerReference(proxy, {id, bound: null}, encodeFormAction); - return proxy; + if (__DEV__) { + // Let's see if we can find a source map for the file which contained the + // server action. We extract it from the runtime so that it's resilient to + // multiple passes of compilation as long as we can find the final source map. + const location = parseStackLocation(new Error('react-stack-top-frame')); + if (location !== null) { + const [, filename, line, col] = location; + // While the environment that the Server Reference points to can be + // in any environment, what matters here is where the compiled source + // is from and that's in the currently executing environment. We hard + // code that as the value "Client" in case the findSourceMapURL helper + // needs it. + const env = 'Client'; + const sourceMap = + findSourceMapURL == null ? null : findSourceMapURL(filename, env); + action = createFakeServerFunction( + functionName || '', + filename, + sourceMap, + line, + col, + env, + action, + ); + } + } + registerServerReference(action, {id, bound: null}, encodeFormAction); + return action; } diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index c3ab6a46805f..0c3b8798dc8c 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -2952,8 +2952,14 @@ describe('ReactFlight', () => { function foo() { return 'hello'; } + function ServerComponent() { - console.log('hi', {prop: 123, fn: foo, map: new Map([['foo', foo]])}); + console.log('hi', { + prop: 123, + fn: foo, + map: new Map([['foo', foo]]), + promise: new Promise(() => {}), + }); throw new Error('err'); } @@ -3018,6 +3024,9 @@ describe('ReactFlight', () => { expect(loggedFn2).not.toBe(foo); expect(loggedFn2.toString()).toBe(foo.toString()); + const promise = mockConsoleLog.mock.calls[0][1].promise; + expect(promise).toBeInstanceOf(Promise); + expect(ownerStacks).toEqual(['\n in App (at **)']); }); diff --git a/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack-bundled.js b/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack-bundled.js deleted file mode 100644 index f4226a93d86b..000000000000 --- a/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack-bundled.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export * from 'react-client/src/ReactFlightClientStreamConfigNode'; -export * from 'react-client/src/ReactClientConsoleConfigServer'; -export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack'; -export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer'; -export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigTargetTurbopackServer'; -export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM'; -export const usedWithSSR = true; diff --git a/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack.js b/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack.js index b6f2b77dd368..f4226a93d86b 100644 --- a/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack.js +++ b/packages/react-client/src/forks/ReactFlightClientConfig.dom-node-turbopack.js @@ -9,7 +9,8 @@ export * from 'react-client/src/ReactFlightClientStreamConfigNode'; export * from 'react-client/src/ReactClientConsoleConfigServer'; -export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerNode'; +export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack'; +export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer'; export * from 'react-server-dom-turbopack/src/client/ReactFlightClientConfigTargetTurbopackServer'; export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM'; export const usedWithSSR = true; diff --git a/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js b/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js index c77013aba3e7..843c6dff9c08 100644 --- a/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js +++ b/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js @@ -2893,26 +2893,29 @@ describe('InspectedElement', () => { `); const inspectedElement = await inspectElementAtIndex(4); - expect(inspectedElement.owners).toMatchInlineSnapshot(` - [ - { - "compiledWithForget": false, - "displayName": "Child", - "hocDisplayNames": null, - "id": 8, - "key": null, - "type": 5, - }, - { - "compiledWithForget": false, - "displayName": "App", - "hocDisplayNames": null, - "id": 7, - "key": null, - "type": 5, - }, - ] - `); + // TODO: Ideally this should match the owners of the Group but those are + // part of a different parent tree. Ideally the Group would be parent of + // that parent tree though which would fix this issue. + // + // [ + // { + // "compiledWithForget": false, + // "displayName": "Child", + // "hocDisplayNames": null, + // "id": 8, + // "key": null, + // "type": 5, + // }, + // { + // "compiledWithForget": false, + // "displayName": "App", + // "hocDisplayNames": null, + // "id": 7, + // "key": null, + // "type": 5, + // }, + // ] + expect(inspectedElement.owners).toMatchInlineSnapshot(`[]`); }); describe('error boundary', () => { diff --git a/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js b/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js index 243759e5b02e..b5941ee5c6cc 100644 --- a/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js +++ b/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js @@ -289,23 +289,9 @@ describe('InspectedElementContext', () => { "preview_long": {boolean: true, number: 123, string: "abc"}, }, }, - "react_element": { - "$$typeof": Dehydrated { - "preview_short": Symbol(react.element), - "preview_long": Symbol(react.element), - }, - "_owner": null, - "_store": Dehydrated { - "preview_short": {…}, - "preview_long": {}, - }, - "key": null, - "props": Dehydrated { - "preview_short": {…}, - "preview_long": {}, - }, - "ref": null, - "type": "span", + "react_element": Dehydrated { + "preview_short": , + "preview_long": , }, "regexp": Dehydrated { "preview_short": /abc/giu, diff --git a/packages/react-devtools-shared/src/backend/fiber/renderer.js b/packages/react-devtools-shared/src/backend/fiber/renderer.js index a48b22f64754..62eacdf5dbe9 100644 --- a/packages/react-devtools-shared/src/backend/fiber/renderer.js +++ b/packages/react-devtools-shared/src/backend/fiber/renderer.js @@ -2143,29 +2143,18 @@ export function attach( const {key} = fiber; const displayName = getDisplayNameForFiber(fiber); const elementType = getElementTypeForFiber(fiber); - const debugOwner = fiber._debugOwner; - - // Ideally we should call getFiberIDThrows() for _debugOwner, - // since owners are almost always higher in the tree (and so have already been processed), - // but in some (rare) instances reported in open source, a descendant mounts before an owner. - // Since this is a DEV only field it's probably okay to also just lazily generate and ID here if needed. - // See https://github.com/facebook/react/issues/21445 - let ownerID: number; - if (debugOwner != null) { - if (typeof debugOwner.tag === 'number') { - const ownerFiberInstance = getFiberInstanceUnsafe((debugOwner: any)); - if (ownerFiberInstance !== null) { - ownerID = ownerFiberInstance.id; - } else { - ownerID = 0; - } - } else { - // TODO: Track Server Component Owners. - ownerID = 0; - } - } else { - ownerID = 0; - } + + // Finding the owner instance might require traversing the whole parent path which + // doesn't have great big O notation. Ideally we'd lazily fetch the owner when we + // need it but we have some synchronous operations in the front end like Alt+Left + // which selects the owner immediately. Typically most owners are only a few parents + // away so maybe it's not so bad. + const debugOwner = getUnfilteredOwner(fiber); + const ownerInstance = findNearestOwnerInstance( + parentInstance, + debugOwner, + ); + const ownerID = ownerInstance === null ? 0 : ownerInstance.id; const parentID = parentInstance ? parentInstance.id : 0; const displayNameStringID = getStringID(displayName); @@ -2231,11 +2220,15 @@ export function attach( displayName = env + '(' + displayName + ')'; } const elementType = ElementTypeVirtual; - // TODO: Support Virtual Owners. To do this we need to find a matching - // virtual instance which is not a super cheap parent traversal and so - // we should ideally only do that lazily. We should maybe change the - // frontend to get it lazily. - const ownerID: number = 0; + + // Finding the owner instance might require traversing the whole parent path which + // doesn't have great big O notation. Ideally we'd lazily fetch the owner when we + // need it but we have some synchronous operations in the front end like Alt+Left + // which selects the owner immediately. Typically most owners are only a few parents + // away so maybe it's not so bad. + const debugOwner = getUnfilteredOwner(componentInfo); + const ownerInstance = findNearestOwnerInstance(parentInstance, debugOwner); + const ownerID = ownerInstance === null ? 0 : ownerInstance.id; const parentID = parentInstance ? parentInstance.id : 0; const displayNameStringID = getStringID(displayName); @@ -3354,11 +3347,19 @@ export function attach( } function getUpdatersList(root: any): Array | null { - return root.memoizedUpdaters != null - ? Array.from(root.memoizedUpdaters) - .filter(fiber => getFiberIDUnsafe(fiber) !== null) - .map(fiberToSerializedElement) - : null; + const updaters = root.memoizedUpdaters; + if (updaters == null) { + return null; + } + const result = []; + // eslint-disable-next-line no-for-of-loops/no-for-of-loops + for (const updater of updaters) { + const inst = getFiberInstanceUnsafe(updater); + if (inst !== null) { + result.push(instanceToSerializedElement(inst)); + } + } + return result; } function handleCommitFiberUnmount(fiber: any) { @@ -3923,13 +3924,26 @@ export function attach( } } - function fiberToSerializedElement(fiber: Fiber): SerializedElement { - return { - displayName: getDisplayNameForFiber(fiber) || 'Anonymous', - id: getFiberIDThrows(fiber), - key: fiber.key, - type: getElementTypeForFiber(fiber), - }; + function instanceToSerializedElement( + instance: DevToolsInstance, + ): SerializedElement { + if (instance.kind === FIBER_INSTANCE) { + const fiber = instance.data; + return { + displayName: getDisplayNameForFiber(fiber) || 'Anonymous', + id: instance.id, + key: fiber.key, + type: getElementTypeForFiber(fiber), + }; + } else { + const componentInfo = instance.data; + return { + displayName: componentInfo.name || 'Anonymous', + id: instance.id, + key: componentInfo.key == null ? null : componentInfo.key, + type: ElementTypeVirtual, + }; + } } function getOwnersList(id: number): Array | null { @@ -3938,33 +3952,97 @@ export function attach( console.warn(`Could not find DevToolsInstance with id "${id}"`); return null; } - if (devtoolsInstance.kind !== FIBER_INSTANCE) { - // TODO: Handle VirtualInstance. - return null; + const self = instanceToSerializedElement(devtoolsInstance); + const owners = getOwnersListFromInstance(devtoolsInstance); + // This is particular API is prefixed with the current instance too for some reason. + if (owners === null) { + return [self]; } - const fiber = - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance); - if (fiber == null) { + owners.unshift(self); + owners.reverse(); + return owners; + } + + function getOwnersListFromInstance( + instance: DevToolsInstance, + ): Array | null { + let owner = getUnfilteredOwner(instance.data); + if (owner === null) { return null; } + const owners: Array = []; + let parentInstance: null | DevToolsInstance = instance.parent; + while (parentInstance !== null && owner !== null) { + const ownerInstance = findNearestOwnerInstance(parentInstance, owner); + if (ownerInstance !== null) { + owners.push(instanceToSerializedElement(ownerInstance)); + // Get the next owner and keep searching from the previous match. + owner = getUnfilteredOwner(owner); + parentInstance = ownerInstance.parent; + } else { + break; + } + } + return owners; + } - const owners: Array = [fiberToSerializedElement(fiber)]; - - let owner = fiber._debugOwner; - while (owner != null) { + function getUnfilteredOwner( + owner: ReactComponentInfo | Fiber | null | void, + ): ReactComponentInfo | Fiber | null { + if (owner == null) { + return null; + } + if (typeof owner.tag === 'number') { + const ownerFiber: Fiber = (owner: any); // Refined + owner = ownerFiber._debugOwner; + } else { + const ownerInfo: ReactComponentInfo = (owner: any); // Refined + owner = ownerInfo.owner; + } + while (owner) { if (typeof owner.tag === 'number') { const ownerFiber: Fiber = (owner: any); // Refined if (!shouldFilterFiber(ownerFiber)) { - owners.unshift(fiberToSerializedElement(ownerFiber)); + return ownerFiber; } owner = ownerFiber._debugOwner; } else { - // TODO: Track Server Component Owners. - break; + const ownerInfo: ReactComponentInfo = (owner: any); // Refined + if (!shouldFilterVirtual(ownerInfo)) { + return ownerInfo; + } + owner = ownerInfo.owner; } } + return null; + } - return owners; + function findNearestOwnerInstance( + parentInstance: null | DevToolsInstance, + owner: void | null | ReactComponentInfo | Fiber, + ): null | DevToolsInstance { + if (owner == null) { + return null; + } + // Search the parent path for any instance that matches this kind of owner. + while (parentInstance !== null) { + if ( + parentInstance.data === owner || + // Typically both owner and instance.data would refer to the current version of a Fiber + // but it is possible for memoization to ignore the owner on the JSX. Then the new Fiber + // isn't propagated down as the new owner. In that case we might match the alternate + // instead. This is a bit hacky but the fastest check since type casting owner to a Fiber + // needs a duck type check anyway. + parentInstance.data === (owner: any).alternate + ) { + return parentInstance; + } + parentInstance = parentInstance.parent; + } + // It is technically possible to create an element and render it in a different parent + // but this is a weird edge case and it is worth not having to scan the tree or keep + // a register for every fiber/component info. + return null; } // Fast path props lookup for React Native style editor. @@ -4047,7 +4125,6 @@ export function attach( } const { - _debugOwner: debugOwner, stateNode, key, memoizedProps, @@ -4174,21 +4251,8 @@ export function attach( context = {value: context}; } - let owners: null | Array = null; - let owner = debugOwner; - while (owner != null) { - if (typeof owner.tag === 'number') { - const ownerFiber: Fiber = (owner: any); // Refined - if (owners === null) { - owners = []; - } - owners.push(fiberToSerializedElement(ownerFiber)); - owner = ownerFiber._debugOwner; - } else { - // TODO: Track Server Component Owners. - break; - } - } + const owners: null | Array = + getOwnersListFromInstance(fiberInstance); const isTimedOutSuspense = tag === SuspenseComponent && memoizedState !== null; @@ -4352,8 +4416,8 @@ export function attach( displayName = env + '(' + displayName + ')'; } - // TODO: Support Virtual Owners. - const owners: null | Array = null; + const owners: null | Array = + getOwnersListFromInstance(virtualInstance); let rootType = null; let targetErrorBoundaryID = null; diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index 8e6f52f6c0f8..62ae8070bf02 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -8,26 +8,13 @@ */ import LRU from 'lru-cache'; -import { - isElement, - typeOf, - ContextConsumer, - ContextProvider, - ForwardRef, - Fragment, - Lazy, - Memo, - Portal, - Profiler, - StrictMode, - Suspense, -} from 'react-is'; import { REACT_CONSUMER_TYPE, REACT_CONTEXT_TYPE, REACT_FORWARD_REF_TYPE, REACT_FRAGMENT_TYPE, REACT_LAZY_TYPE, + REACT_ELEMENT_TYPE, REACT_LEGACY_ELEMENT_TYPE, REACT_MEMO_TYPE, REACT_PORTAL_TYPE, @@ -35,9 +22,8 @@ import { REACT_PROVIDER_TYPE, REACT_STRICT_MODE_TYPE, REACT_SUSPENSE_LIST_TYPE, - REACT_SUSPENSE_LIST_TYPE as SuspenseList, REACT_SUSPENSE_TYPE, - REACT_TRACING_MARKER_TYPE as TracingMarker, + REACT_TRACING_MARKER_TYPE, } from 'shared/ReactSymbols'; import {enableRenderableContext} from 'shared/ReactFeatureFlags'; import { @@ -632,10 +618,6 @@ export function getDataType(data: Object): DataType { return 'undefined'; } - if (isElement(data)) { - return 'react_element'; - } - if (typeof HTMLElement !== 'undefined' && data instanceof HTMLElement) { return 'html_element'; } @@ -657,6 +639,12 @@ export function getDataType(data: Object): DataType { return 'number'; } case 'object': + if ( + data.$$typeof === REACT_ELEMENT_TYPE || + data.$$typeof === REACT_LEGACY_ELEMENT_TYPE + ) { + return 'react_element'; + } if (isArray(data)) { return 'array'; } else if (ArrayBuffer.isView(data)) { @@ -717,6 +705,7 @@ function typeOfWithLegacyElementSymbol(object: any): mixed { if (typeof object === 'object' && object !== null) { const $$typeof = object.$$typeof; switch ($$typeof) { + case REACT_ELEMENT_TYPE: case REACT_LEGACY_ELEMENT_TYPE: const type = object.type; @@ -761,31 +750,33 @@ function typeOfWithLegacyElementSymbol(object: any): mixed { export function getDisplayNameForReactElement( element: React$Element, ): string | null { - const elementType = typeOf(element) || typeOfWithLegacyElementSymbol(element); + const elementType = typeOfWithLegacyElementSymbol(element); switch (elementType) { - case ContextConsumer: + case REACT_CONSUMER_TYPE: return 'ContextConsumer'; - case ContextProvider: + case REACT_PROVIDER_TYPE: return 'ContextProvider'; - case ForwardRef: + case REACT_CONTEXT_TYPE: + return 'Context'; + case REACT_FORWARD_REF_TYPE: return 'ForwardRef'; - case Fragment: + case REACT_FRAGMENT_TYPE: return 'Fragment'; - case Lazy: + case REACT_LAZY_TYPE: return 'Lazy'; - case Memo: + case REACT_MEMO_TYPE: return 'Memo'; - case Portal: + case REACT_PORTAL_TYPE: return 'Portal'; - case Profiler: + case REACT_PROFILER_TYPE: return 'Profiler'; - case StrictMode: + case REACT_STRICT_MODE_TYPE: return 'StrictMode'; - case Suspense: + case REACT_SUSPENSE_TYPE: return 'Suspense'; - case SuspenseList: + case REACT_SUSPENSE_LIST_TYPE: return 'SuspenseList'; - case TracingMarker: + case REACT_TRACING_MARKER_TYPE: return 'TracingMarker'; default: const {type} = element; diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index e9abb25eb176..5a763ffe949a 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -7727,7 +7727,6 @@ describe('ReactDOMFizzServer', () => { const prerendered = await pendingPrerender; - expect(prerendered.postponed).toBe(null); expect(errors).toEqual([]); expect(postpones).toEqual(['manufactured', 'manufactured']); @@ -7747,6 +7746,112 @@ describe('ReactDOMFizzServer', () => { ); }); + // @gate enableHalt + it('can resume a prerender that was aborted', async () => { + const promise = new Promise(r => {}); + + let prerendering = true; + + function Wait() { + if (prerendering) { + return React.use(promise); + } else { + return 'Hello'; + } + } + + function App() { + return ( +
+ +

+ + + + + +

+

+ + + + + +

+
+
+ ); + } + + const controller = new AbortController(); + const signal = controller.signal; + + const errors = []; + function onError(error) { + errors.push(error); + } + let pendingPrerender; + await act(() => { + pendingPrerender = ReactDOMFizzStatic.prerenderToNodeStream(, { + signal, + onError, + }); + }); + controller.abort('boom'); + + const prerendered = await pendingPrerender; + + expect(errors).toEqual(['boom', 'boom']); + + const preludeWritable = new Stream.PassThrough(); + preludeWritable.setEncoding('utf8'); + preludeWritable.on('data', chunk => { + writable.write(chunk); + }); + + await act(() => { + prerendered.prelude.pipe(preludeWritable); + }); + + expect(getVisibleChildren(container)).toEqual( +
+

+ Loading again... +

+

+ Loading again too... +

+
, + ); + + prerendering = false; + + errors.length = 0; + const resumed = await ReactDOMFizzServer.resumeToPipeableStream( + , + JSON.parse(JSON.stringify(prerendered.postponed)), + { + onError, + }, + ); + + await act(() => { + resumed.pipe(writable); + }); + + expect(errors).toEqual([]); + expect(getVisibleChildren(container)).toEqual( +
+

+ Hello +

+

+ Hello +

+
, + ); + }); + // @gate enablePostpone it('does not call onError when you abort with a postpone instance during resume', async () => { let prerendering = true; @@ -8377,6 +8482,48 @@ describe('ReactDOMFizzServer', () => { ); }); + it('can support throwing after aborting during a render', async () => { + function App() { + return ( +
+ loading...

}> + +
+
+ ); + } + + function ComponentThatAborts() { + abortRef.current('boom'); + throw new Error('bam'); + } + + const abortRef = {current: null}; + let finished = false; + const errors = []; + await act(() => { + const {pipe, abort} = renderToPipeableStream(, { + onError(err) { + errors.push(err); + }, + }); + abortRef.current = abort; + writable.on('finish', () => { + finished = true; + }); + pipe(writable); + }); + + expect(errors).toEqual(['boom']); + + expect(finished).toBe(true); + expect(getVisibleChildren(container)).toEqual( +
+

loading...

+
, + ); + }); + it('should warn for using generators as children props', async () => { function* getChildren() { yield

Hello

; diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js index 1f3bfa7b3308..03db4e3f5ed8 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js @@ -454,4 +454,56 @@ describe('ReactDOMFizzStatic', () => { }); expect(getVisibleChildren(container)).toEqual(undefined); }); + + // @gate enableHalt + it('will halt a prerender when aborting with an error during a render', async () => { + const controller = new AbortController(); + function App() { + controller.abort('sync'); + return
hello world
; + } + + const errors = []; + const result = await ReactDOMFizzStatic.prerenderToNodeStream(, { + signal: controller.signal, + onError(error) { + errors.push(error); + }, + }); + await act(async () => { + result.prelude.pipe(writable); + }); + expect(errors).toEqual(['sync']); + expect(getVisibleChildren(container)).toEqual(undefined); + }); + + // @gate enableHalt + it('will halt a prerender when aborting with an error in a microtask', async () => { + const errors = []; + + const controller = new AbortController(); + function App() { + React.use( + new Promise(() => { + Promise.resolve().then(() => { + controller.abort('async'); + }); + }), + ); + return
hello world
; + } + + errors.length = 0; + const result = await ReactDOMFizzStatic.prerenderToNodeStream(, { + signal: controller.signal, + onError(error) { + errors.push(error); + }, + }); + await act(async () => { + result.prelude.pipe(writable); + }); + expect(errors).toEqual(['async']); + expect(getVisibleChildren(container)).toEqual(undefined); + }); }); diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js index 7a3db48b016e..357ef1dcb478 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js @@ -307,7 +307,8 @@ describe('ReactDOMFizzStaticBrowser', () => { }); // @gate experimental - it('should reject if aborting before the shell is complete', async () => { + // @gate !enableHalt + it('should reject if aborting before the shell is complete and enableHalt is disabled', async () => { const errors = []; const controller = new AbortController(); const promise = serverAct(() => @@ -339,6 +340,42 @@ describe('ReactDOMFizzStaticBrowser', () => { expect(errors).toEqual(['aborted for reasons']); }); + // @gate enableHalt + it('should resolve an empty prelude if aborting before the shell is complete', async () => { + const errors = []; + const controller = new AbortController(); + const promise = serverAct(() => + ReactDOMFizzStatic.prerender( +
+ +
, + { + signal: controller.signal, + onError(x) { + errors.push(x.message); + }, + }, + ), + ); + + await jest.runAllTimers(); + + const theReason = new Error('aborted for reasons'); + controller.abort(theReason); + + let rejected = false; + let prelude; + try { + ({prelude} = await promise); + } catch (error) { + rejected = true; + } + expect(rejected).toBe(false); + expect(errors).toEqual(['aborted for reasons']); + const content = await readContent(prelude); + expect(content).toBe(''); + }); + // @gate experimental it('should be able to abort before something suspends', async () => { const errors = []; @@ -365,18 +402,26 @@ describe('ReactDOMFizzStaticBrowser', () => { ), ); - let caughtError = null; - try { - await streamPromise; - } catch (error) { - caughtError = error; + if (gate(flags => flags.enableHalt)) { + const {prelude} = await streamPromise; + const content = await readContent(prelude); + expect(errors).toEqual(['The operation was aborted.']); + expect(content).toBe(''); + } else { + let caughtError = null; + try { + await streamPromise; + } catch (error) { + caughtError = error; + } + expect(caughtError.message).toBe('The operation was aborted.'); + expect(errors).toEqual(['The operation was aborted.']); } - expect(caughtError.message).toBe('The operation was aborted.'); - expect(errors).toEqual(['The operation was aborted.']); }); // @gate experimental - it('should reject if passing an already aborted signal', async () => { + // @gate !enableHalt + it('should reject if passing an already aborted signal and enableHalt is disabled', async () => { const errors = []; const controller = new AbortController(); const theReason = new Error('aborted for reasons'); @@ -410,6 +455,44 @@ describe('ReactDOMFizzStaticBrowser', () => { expect(errors).toEqual(['aborted for reasons']); }); + // @gate enableHalt + it('should resolve an empty prelude if passing an already aborted signal', async () => { + const errors = []; + const controller = new AbortController(); + const theReason = new Error('aborted for reasons'); + controller.abort(theReason); + + const promise = serverAct(() => + ReactDOMFizzStatic.prerender( +
+ Loading
}> + + +
, + { + signal: controller.signal, + onError(x) { + errors.push(x.message); + }, + }, + ), + ); + + // Technically we could still continue rendering the shell but currently the + // semantics mean that we also abort any pending CPU work. + let didThrow = false; + let prelude; + try { + ({prelude} = await promise); + } catch (error) { + didThrow = true; + } + expect(didThrow).toBe(false); + expect(errors).toEqual(['aborted for reasons']); + const content = await readContent(prelude); + expect(content).toBe(''); + }); + // @gate experimental it('supports custom abort reasons with a string', async () => { const promise = new Promise(r => {}); diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzStaticNode-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzStaticNode-test.js index ade755bdffea..12ac4de34d68 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzStaticNode-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzStaticNode-test.js @@ -212,7 +212,8 @@ describe('ReactDOMFizzStaticNode', () => { }); // @gate experimental - it('should reject if aborting before the shell is complete', async () => { + // @gate !enableHalt + it('should reject if aborting before the shell is complete and enableHalt is disabled', async () => { const errors = []; const controller = new AbortController(); const promise = ReactDOMFizzStatic.prerenderToNodeStream( @@ -242,6 +243,40 @@ describe('ReactDOMFizzStaticNode', () => { expect(errors).toEqual(['aborted for reasons']); }); + // @gate enableHalt + it('should resolve an empty shell if aborting before the shell is complete', async () => { + const errors = []; + const controller = new AbortController(); + const promise = ReactDOMFizzStatic.prerenderToNodeStream( +
+ +
, + { + signal: controller.signal, + onError(x) { + errors.push(x.message); + }, + }, + ); + + await jest.runAllTimers(); + + const theReason = new Error('aborted for reasons'); + controller.abort(theReason); + + let didThrow = false; + let prelude; + try { + ({prelude} = await promise); + } catch (error) { + didThrow = true; + } + expect(didThrow).toBe(false); + expect(errors).toEqual(['aborted for reasons']); + const content = await readContent(prelude); + expect(content).toBe(''); + }); + // @gate experimental it('should be able to abort before something suspends', async () => { const errors = []; @@ -266,18 +301,26 @@ describe('ReactDOMFizzStaticNode', () => { }, ); - let caughtError = null; - try { - await streamPromise; - } catch (error) { - caughtError = error; + if (gate(flags => flags.enableHalt)) { + const {prelude} = await streamPromise; + const content = await readContent(prelude); + expect(errors).toEqual(['This operation was aborted']); + expect(content).toBe(''); + } else { + let caughtError = null; + try { + await streamPromise; + } catch (error) { + caughtError = error; + } + expect(caughtError.message).toBe('This operation was aborted'); + expect(errors).toEqual(['This operation was aborted']); } - expect(caughtError.message).toBe('This operation was aborted'); - expect(errors).toEqual(['This operation was aborted']); }); // @gate experimental - it('should reject if passing an already aborted signal', async () => { + // @gate !enableHalt + it('should reject if passing an already aborted signal and enableHalt is disabled', async () => { const errors = []; const controller = new AbortController(); const theReason = new Error('aborted for reasons'); @@ -309,6 +352,43 @@ describe('ReactDOMFizzStaticNode', () => { expect(errors).toEqual(['aborted for reasons']); }); + // @gate enableHalt + it('should resolve with an empty prelude if passing an already aborted signal', async () => { + const errors = []; + const controller = new AbortController(); + const theReason = new Error('aborted for reasons'); + controller.abort(theReason); + + const promise = ReactDOMFizzStatic.prerenderToNodeStream( +
+ Loading
}> + + +
, + { + signal: controller.signal, + onError(x) { + errors.push(x.message); + }, + }, + ); + + // Technically we could still continue rendering the shell but currently the + // semantics mean that we also abort any pending CPU work. + + let didThrow = false; + let prelude; + try { + ({prelude} = await promise); + } catch (error) { + didThrow = true; + } + expect(didThrow).toBe(false); + expect(errors).toEqual(['aborted for reasons']); + const content = await readContent(prelude); + expect(content).toBe(''); + }); + // @gate experimental it('supports custom abort reasons with a string', async () => { const promise = new Promise(r => {}); diff --git a/packages/react-server-dom-esm/src/ReactFlightESMReferences.js b/packages/react-server-dom-esm/src/ReactFlightESMReferences.js index cd3dd349157a..86a25c7c8608 100644 --- a/packages/react-server-dom-esm/src/ReactFlightESMReferences.js +++ b/packages/react-server-dom-esm/src/ReactFlightESMReferences.js @@ -13,6 +13,7 @@ export type ServerReference = T & { $$typeof: symbol, $$id: string, $$bound: null | Array, + $$location?: Error, }; // eslint-disable-next-line no-unused-vars @@ -68,10 +69,30 @@ export function registerServerReference( id: string, exportName: string, ): ServerReference { - return Object.defineProperties((reference: any), { - $$typeof: {value: SERVER_REFERENCE_TAG}, - $$id: {value: id + '#' + exportName, configurable: true}, - $$bound: {value: null, configurable: true}, - bind: {value: bind, configurable: true}, - }); + const $$typeof = {value: SERVER_REFERENCE_TAG}; + const $$id = { + value: id + '#' + exportName, + configurable: true, + }; + const $$bound = {value: null, configurable: true}; + return Object.defineProperties( + (reference: any), + __DEV__ + ? { + $$typeof, + $$id, + $$bound, + $$location: { + value: Error('react-stack-top-frame'), + configurable: true, + }, + bind: {value: bind, configurable: true}, + } + : { + $$typeof, + $$id, + $$bound, + bind: {value: bind, configurable: true}, + }, + ); } diff --git a/packages/react-server-dom-esm/src/server/ReactFlightDOMServerNode.js b/packages/react-server-dom-esm/src/server/ReactFlightDOMServerNode.js index bb65ef4b659a..a9c978b49301 100644 --- a/packages/react-server-dom-esm/src/server/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-esm/src/server/ReactFlightDOMServerNode.js @@ -22,6 +22,7 @@ import {Readable} from 'stream'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -172,25 +173,27 @@ function prerenderToNodeStream( resolve({prelude: readable}); } - const request = createRequest( + const request = createPrerenderRequest( model, moduleBasePath, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-esm/src/server/ReactFlightServerConfigESMBundler.js b/packages/react-server-dom-esm/src/server/ReactFlightServerConfigESMBundler.js index cba5223bcf7a..5e789518b40c 100644 --- a/packages/react-server-dom-esm/src/server/ReactFlightServerConfigESMBundler.js +++ b/packages/react-server-dom-esm/src/server/ReactFlightServerConfigESMBundler.js @@ -70,3 +70,10 @@ export function getServerReferenceBoundArguments( ): null | Array { return serverReference.$$bound; } + +export function getServerReferenceLocation( + config: ClientManifest, + serverReference: ServerReference, +): void | Error { + return serverReference.$$location; +} diff --git a/packages/react-server-dom-turbopack/client.node.unbundled.js b/packages/react-server-dom-turbopack/client.node.unbundled.js deleted file mode 100644 index c2e364f42f13..000000000000 --- a/packages/react-server-dom-turbopack/client.node.unbundled.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export * from './src/client/ReactFlightDOMClientNode'; diff --git a/packages/react-server-dom-turbopack/esm/package.json b/packages/react-server-dom-turbopack/esm/package.json deleted file mode 100644 index 3dbc1ca591c0..000000000000 --- a/packages/react-server-dom-turbopack/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/packages/react-server-dom-turbopack/esm/react-server-dom-turbopack-node-loader.production.js b/packages/react-server-dom-turbopack/esm/react-server-dom-turbopack-node-loader.production.js deleted file mode 100644 index ef6486656caf..000000000000 --- a/packages/react-server-dom-turbopack/esm/react-server-dom-turbopack-node-loader.production.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export * from '../src/ReactFlightTurbopackNodeLoader.js'; diff --git a/packages/react-server-dom-turbopack/node-register.js b/packages/react-server-dom-turbopack/node-register.js deleted file mode 100644 index 0d399f384273..000000000000 --- a/packages/react-server-dom-turbopack/node-register.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -module.exports = require('./src/ReactFlightTurbopackNodeRegister'); diff --git a/packages/react-server-dom-turbopack/npm/client.node.unbundled.js b/packages/react-server-dom-turbopack/npm/client.node.unbundled.js deleted file mode 100644 index 04eb5b1972be..000000000000 --- a/packages/react-server-dom-turbopack/npm/client.node.unbundled.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -if (process.env.NODE_ENV === 'production') { - module.exports = require('./cjs/react-server-dom-turbopack-client.node.unbundled.production.js'); -} else { - module.exports = require('./cjs/react-server-dom-turbopack-client.node.unbundled.development.js'); -} diff --git a/packages/react-server-dom-turbopack/npm/esm/package.json b/packages/react-server-dom-turbopack/npm/esm/package.json deleted file mode 100644 index 3dbc1ca591c0..000000000000 --- a/packages/react-server-dom-turbopack/npm/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/packages/react-server-dom-turbopack/npm/node-register.js b/packages/react-server-dom-turbopack/npm/node-register.js deleted file mode 100644 index 7506743f033f..000000000000 --- a/packages/react-server-dom-turbopack/npm/node-register.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = require('./cjs/react-server-dom-turbopack-node-register.js'); diff --git a/packages/react-server-dom-turbopack/npm/server.node.unbundled.js b/packages/react-server-dom-turbopack/npm/server.node.unbundled.js deleted file mode 100644 index 1e8648ccef13..000000000000 --- a/packages/react-server-dom-turbopack/npm/server.node.unbundled.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -var s; -if (process.env.NODE_ENV === 'production') { - s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.production.js'); -} else { - s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.development.js'); -} - -exports.renderToPipeableStream = s.renderToPipeableStream; -exports.decodeReplyFromBusboy = s.decodeReplyFromBusboy; -exports.decodeReply = s.decodeReply; -exports.decodeAction = s.decodeAction; -exports.decodeFormState = s.decodeFormState; -exports.registerServerReference = s.registerServerReference; -exports.registerClientReference = s.registerClientReference; -exports.createClientModuleProxy = s.createClientModuleProxy; -exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet; diff --git a/packages/react-server-dom-turbopack/npm/static.node.unbundled.js b/packages/react-server-dom-turbopack/npm/static.node.unbundled.js deleted file mode 100644 index e77863bf36a6..000000000000 --- a/packages/react-server-dom-turbopack/npm/static.node.unbundled.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -var s; -if (process.env.NODE_ENV === 'production') { - s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.production.js'); -} else { - s = require('./cjs/react-server-dom-turbopack-server.node.unbundled.development.js'); -} - -if (s.prerenderToNodeStream) { - exports.prerenderToNodeStream = s.prerenderToNodeStream; -} diff --git a/packages/react-server-dom-turbopack/package.json b/packages/react-server-dom-turbopack/package.json index 93cd7d37a04a..3b638137612d 100644 --- a/packages/react-server-dom-turbopack/package.json +++ b/packages/react-server-dom-turbopack/package.json @@ -16,20 +16,15 @@ "client.browser.js", "client.edge.js", "client.node.js", - "client.node.unbundled.js", "server.js", "server.browser.js", "server.edge.js", "server.node.js", - "server.node.unbundled.js", "static.js", "static.browser.js", "static.edge.js", "static.node.js", - "static.node.unbundled.js", - "node-register.js", - "cjs/", - "esm/" + "cjs/" ], "exports": { ".": "./index.js", @@ -37,11 +32,7 @@ "workerd": "./client.edge.js", "deno": "./client.edge.js", "worker": "./client.edge.js", - "node": { - "turbopack": "./client.node.js", - "webpack": "./client.node.js", - "default": "./client.node.unbundled.js" - }, + "node": "./client.node.js", "edge-light": "./client.edge.js", "browser": "./client.browser.js", "default": "./client.browser.js" @@ -49,16 +40,11 @@ "./client.browser": "./client.browser.js", "./client.edge": "./client.edge.js", "./client.node": "./client.node.js", - "./client.node.unbundled": "./client.node.unbundled.js", "./server": { "react-server": { "workerd": "./server.edge.js", "deno": "./server.browser.js", - "node": { - "turbopack": "./server.node.js", - "webpack": "./server.node.js", - "default": "./server.node.unbundled.js" - }, + "node": "./server.node.js", "edge-light": "./server.edge.js", "browser": "./server.browser.js" }, @@ -67,16 +53,11 @@ "./server.browser": "./server.browser.js", "./server.edge": "./server.edge.js", "./server.node": "./server.node.js", - "./server.node.unbundled": "./server.node.unbundled.js", "./static": { "react-server": { "workerd": "./static.edge.js", "deno": "./static.browser.js", - "node": { - "turbopack": "./static.node.js", - "webpack": "./static.node.js", - "default": "./static.node.unbundled.js" - }, + "node": "./static.node.js", "edge-light": "./static.edge.js", "browser": "./static.browser.js" }, @@ -85,9 +66,6 @@ "./static.browser": "./static.browser.js", "./static.edge": "./static.edge.js", "./static.node": "./static.node.js", - "./static.node.unbundled": "./static.node.unbundled.js", - "./node-loader": "./esm/react-server-dom-turbopack-node-loader.production.js", - "./node-register": "./node-register.js", "./src/*": "./src/*.js", "./package.json": "./package.json" }, diff --git a/packages/react-server-dom-turbopack/server.node.unbundled.js b/packages/react-server-dom-turbopack/server.node.unbundled.js deleted file mode 100644 index 9b8455bf6687..000000000000 --- a/packages/react-server-dom-turbopack/server.node.unbundled.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export { - renderToPipeableStream, - decodeReplyFromBusboy, - decodeReply, - decodeAction, - decodeFormState, - registerServerReference, - registerClientReference, - createClientModuleProxy, - createTemporaryReferenceSet, -} from './src/server/react-flight-dom-server.node.unbundled'; diff --git a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeLoader.js b/packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeLoader.js deleted file mode 100644 index b2f80e6b915f..000000000000 --- a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeLoader.js +++ /dev/null @@ -1,483 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import * as acorn from 'acorn-loose'; - -type ResolveContext = { - conditions: Array, - parentURL: string | void, -}; - -type ResolveFunction = ( - string, - ResolveContext, - ResolveFunction, -) => {url: string} | Promise<{url: string}>; - -type GetSourceContext = { - format: string, -}; - -type GetSourceFunction = ( - string, - GetSourceContext, - GetSourceFunction, -) => Promise<{source: Source}>; - -type TransformSourceContext = { - format: string, - url: string, -}; - -type TransformSourceFunction = ( - Source, - TransformSourceContext, - TransformSourceFunction, -) => Promise<{source: Source}>; - -type LoadContext = { - conditions: Array, - format: string | null | void, - importAssertions: Object, -}; - -type LoadFunction = ( - string, - LoadContext, - LoadFunction, -) => Promise<{format: string, shortCircuit?: boolean, source: Source}>; - -type Source = string | ArrayBuffer | Uint8Array; - -let warnedAboutConditionsFlag = false; - -let stashedGetSource: null | GetSourceFunction = null; -let stashedResolve: null | ResolveFunction = null; - -export async function resolve( - specifier: string, - context: ResolveContext, - defaultResolve: ResolveFunction, -): Promise<{url: string}> { - // We stash this in case we end up needing to resolve export * statements later. - stashedResolve = defaultResolve; - - if (!context.conditions.includes('react-server')) { - context = { - ...context, - conditions: [...context.conditions, 'react-server'], - }; - if (!warnedAboutConditionsFlag) { - warnedAboutConditionsFlag = true; - // eslint-disable-next-line react-internal/no-production-logging - console.warn( - 'You did not run Node.js with the `--conditions react-server` flag. ' + - 'Any "react-server" override will only work with ESM imports.', - ); - } - } - return await defaultResolve(specifier, context, defaultResolve); -} - -export async function getSource( - url: string, - context: GetSourceContext, - defaultGetSource: GetSourceFunction, -): Promise<{source: Source}> { - // We stash this in case we end up needing to resolve export * statements later. - stashedGetSource = defaultGetSource; - return defaultGetSource(url, context, defaultGetSource); -} - -function addLocalExportedNames(names: Map, node: any) { - switch (node.type) { - case 'Identifier': - names.set(node.name, node.name); - return; - case 'ObjectPattern': - for (let i = 0; i < node.properties.length; i++) - addLocalExportedNames(names, node.properties[i]); - return; - case 'ArrayPattern': - for (let i = 0; i < node.elements.length; i++) { - const element = node.elements[i]; - if (element) addLocalExportedNames(names, element); - } - return; - case 'Property': - addLocalExportedNames(names, node.value); - return; - case 'AssignmentPattern': - addLocalExportedNames(names, node.left); - return; - case 'RestElement': - addLocalExportedNames(names, node.argument); - return; - case 'ParenthesizedExpression': - addLocalExportedNames(names, node.expression); - return; - } -} - -function transformServerModule( - source: string, - body: any, - url: string, - loader: LoadFunction, -): string { - // If the same local name is exported more than once, we only need one of the names. - const localNames: Map = new Map(); - const localTypes: Map = new Map(); - - for (let i = 0; i < body.length; i++) { - const node = body[i]; - switch (node.type) { - case 'ExportAllDeclaration': - // If export * is used, the other file needs to explicitly opt into "use server" too. - break; - case 'ExportDefaultDeclaration': - if (node.declaration.type === 'Identifier') { - localNames.set(node.declaration.name, 'default'); - } else if (node.declaration.type === 'FunctionDeclaration') { - if (node.declaration.id) { - localNames.set(node.declaration.id.name, 'default'); - localTypes.set(node.declaration.id.name, 'function'); - } else { - // TODO: This needs to be rewritten inline because it doesn't have a local name. - } - } - continue; - case 'ExportNamedDeclaration': - if (node.declaration) { - if (node.declaration.type === 'VariableDeclaration') { - const declarations = node.declaration.declarations; - for (let j = 0; j < declarations.length; j++) { - addLocalExportedNames(localNames, declarations[j].id); - } - } else { - const name = node.declaration.id.name; - localNames.set(name, name); - if (node.declaration.type === 'FunctionDeclaration') { - localTypes.set(name, 'function'); - } - } - } - if (node.specifiers) { - const specifiers = node.specifiers; - for (let j = 0; j < specifiers.length; j++) { - const specifier = specifiers[j]; - localNames.set(specifier.local.name, specifier.exported.name); - } - } - continue; - } - } - if (localNames.size === 0) { - return source; - } - let newSrc = source + '\n\n;'; - newSrc += - 'import {registerServerReference} from "react-server-dom-turbopack/server";\n'; - localNames.forEach(function (exported, local) { - if (localTypes.get(local) !== 'function') { - // We first check if the export is a function and if so annotate it. - newSrc += 'if (typeof ' + local + ' === "function") '; - } - newSrc += 'registerServerReference(' + local + ','; - newSrc += JSON.stringify(url) + ','; - newSrc += JSON.stringify(exported) + ');\n'; - }); - return newSrc; -} - -function addExportNames(names: Array, node: any) { - switch (node.type) { - case 'Identifier': - names.push(node.name); - return; - case 'ObjectPattern': - for (let i = 0; i < node.properties.length; i++) - addExportNames(names, node.properties[i]); - return; - case 'ArrayPattern': - for (let i = 0; i < node.elements.length; i++) { - const element = node.elements[i]; - if (element) addExportNames(names, element); - } - return; - case 'Property': - addExportNames(names, node.value); - return; - case 'AssignmentPattern': - addExportNames(names, node.left); - return; - case 'RestElement': - addExportNames(names, node.argument); - return; - case 'ParenthesizedExpression': - addExportNames(names, node.expression); - return; - } -} - -function resolveClientImport( - specifier: string, - parentURL: string, -): {url: string} | Promise<{url: string}> { - // Resolve an import specifier as if it was loaded by the client. This doesn't use - // the overrides that this loader does but instead reverts to the default. - // This resolution algorithm will not necessarily have the same configuration - // as the actual client loader. It should mostly work and if it doesn't you can - // always convert to explicit exported names instead. - const conditions = ['node', 'import']; - if (stashedResolve === null) { - throw new Error( - 'Expected resolve to have been called before transformSource', - ); - } - return stashedResolve(specifier, {conditions, parentURL}, stashedResolve); -} - -async function parseExportNamesInto( - body: any, - names: Array, - parentURL: string, - loader: LoadFunction, -): Promise { - for (let i = 0; i < body.length; i++) { - const node = body[i]; - switch (node.type) { - case 'ExportAllDeclaration': - if (node.exported) { - addExportNames(names, node.exported); - continue; - } else { - const {url} = await resolveClientImport(node.source.value, parentURL); - const {source} = await loader( - url, - {format: 'module', conditions: [], importAssertions: {}}, - loader, - ); - if (typeof source !== 'string') { - throw new Error('Expected the transformed source to be a string.'); - } - let childBody; - try { - childBody = acorn.parse(source, { - ecmaVersion: '2024', - sourceType: 'module', - }).body; - } catch (x) { - // eslint-disable-next-line react-internal/no-production-logging - console.error('Error parsing %s %s', url, x.message); - continue; - } - await parseExportNamesInto(childBody, names, url, loader); - continue; - } - case 'ExportDefaultDeclaration': - names.push('default'); - continue; - case 'ExportNamedDeclaration': - if (node.declaration) { - if (node.declaration.type === 'VariableDeclaration') { - const declarations = node.declaration.declarations; - for (let j = 0; j < declarations.length; j++) { - addExportNames(names, declarations[j].id); - } - } else { - addExportNames(names, node.declaration.id); - } - } - if (node.specifiers) { - const specifiers = node.specifiers; - for (let j = 0; j < specifiers.length; j++) { - addExportNames(names, specifiers[j].exported); - } - } - continue; - } - } -} - -async function transformClientModule( - body: any, - url: string, - loader: LoadFunction, -): Promise { - const names: Array = []; - - await parseExportNamesInto(body, names, url, loader); - - if (names.length === 0) { - return ''; - } - - let newSrc = - 'import {registerClientReference} from "react-server-dom-turbopack/server";\n'; - for (let i = 0; i < names.length; i++) { - const name = names[i]; - if (name === 'default') { - newSrc += 'export default '; - newSrc += 'registerClientReference(function() {'; - newSrc += - 'throw new Error(' + - JSON.stringify( - `Attempted to call the default export of ${url} from the server ` + - `but it's on the client. It's not possible to invoke a client function from ` + - `the server, it can only be rendered as a Component or passed to props of a ` + - `Client Component.`, - ) + - ');'; - } else { - newSrc += 'export const ' + name + ' = '; - newSrc += 'registerClientReference(function() {'; - newSrc += - 'throw new Error(' + - JSON.stringify( - `Attempted to call ${name}() from the server but ${name} is on the client. ` + - `It's not possible to invoke a client function from the server, it can ` + - `only be rendered as a Component or passed to props of a Client Component.`, - ) + - ');'; - } - newSrc += '},'; - newSrc += JSON.stringify(url) + ','; - newSrc += JSON.stringify(name) + ');\n'; - } - return newSrc; -} - -async function loadClientImport( - url: string, - defaultTransformSource: TransformSourceFunction, -): Promise<{format: string, shortCircuit?: boolean, source: Source}> { - if (stashedGetSource === null) { - throw new Error( - 'Expected getSource to have been called before transformSource', - ); - } - // TODO: Validate that this is another module by calling getFormat. - const {source} = await stashedGetSource( - url, - {format: 'module'}, - stashedGetSource, - ); - const result = await defaultTransformSource( - source, - {format: 'module', url}, - defaultTransformSource, - ); - return {format: 'module', source: result.source}; -} - -async function transformModuleIfNeeded( - source: string, - url: string, - loader: LoadFunction, -): Promise { - // Do a quick check for the exact string. If it doesn't exist, don't - // bother parsing. - if ( - source.indexOf('use client') === -1 && - source.indexOf('use server') === -1 - ) { - return source; - } - - let body; - try { - body = acorn.parse(source, { - ecmaVersion: '2024', - sourceType: 'module', - }).body; - } catch (x) { - // eslint-disable-next-line react-internal/no-production-logging - console.error('Error parsing %s %s', url, x.message); - return source; - } - - let useClient = false; - let useServer = false; - for (let i = 0; i < body.length; i++) { - const node = body[i]; - if (node.type !== 'ExpressionStatement' || !node.directive) { - break; - } - if (node.directive === 'use client') { - useClient = true; - } - if (node.directive === 'use server') { - useServer = true; - } - } - - if (!useClient && !useServer) { - return source; - } - - if (useClient && useServer) { - throw new Error( - 'Cannot have both "use client" and "use server" directives in the same file.', - ); - } - - if (useClient) { - return transformClientModule(body, url, loader); - } - - return transformServerModule(source, body, url, loader); -} - -export async function transformSource( - source: Source, - context: TransformSourceContext, - defaultTransformSource: TransformSourceFunction, -): Promise<{source: Source}> { - const transformed = await defaultTransformSource( - source, - context, - defaultTransformSource, - ); - if (context.format === 'module') { - const transformedSource = transformed.source; - if (typeof transformedSource !== 'string') { - throw new Error('Expected source to have been transformed to a string.'); - } - const newSrc = await transformModuleIfNeeded( - transformedSource, - context.url, - (url: string, ctx: LoadContext, defaultLoad: LoadFunction) => { - return loadClientImport(url, defaultTransformSource); - }, - ); - return {source: newSrc}; - } - return transformed; -} - -export async function load( - url: string, - context: LoadContext, - defaultLoad: LoadFunction, -): Promise<{format: string, shortCircuit?: boolean, source: Source}> { - const result = await defaultLoad(url, context, defaultLoad); - if (result.format === 'module') { - if (typeof result.source !== 'string') { - throw new Error('Expected source to have been loaded into a string.'); - } - const newSrc = await transformModuleIfNeeded( - result.source, - url, - defaultLoad, - ); - return {format: 'module', source: newSrc}; - } - return result; -} diff --git a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister.js b/packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister.js deleted file mode 100644 index fa7965cc8994..000000000000 --- a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -const acorn = require('acorn-loose'); - -const url = require('url'); - -const Module = require('module'); - -module.exports = function register() { - const Server: any = require('react-server-dom-turbopack/server'); - const registerServerReference = Server.registerServerReference; - const createClientModuleProxy = Server.createClientModuleProxy; - - // $FlowFixMe[prop-missing] found when upgrading Flow - const originalCompile = Module.prototype._compile; - - // $FlowFixMe[prop-missing] found when upgrading Flow - Module.prototype._compile = function ( - this: any, - content: string, - filename: string, - ): void { - // Do a quick check for the exact string. If it doesn't exist, don't - // bother parsing. - if ( - content.indexOf('use client') === -1 && - content.indexOf('use server') === -1 - ) { - return originalCompile.apply(this, arguments); - } - - let body; - try { - body = acorn.parse(content, { - ecmaVersion: '2024', - sourceType: 'source', - }).body; - } catch (x) { - console['error']('Error parsing %s %s', url, x.message); - return originalCompile.apply(this, arguments); - } - - let useClient = false; - let useServer = false; - for (let i = 0; i < body.length; i++) { - const node = body[i]; - if (node.type !== 'ExpressionStatement' || !node.directive) { - break; - } - if (node.directive === 'use client') { - useClient = true; - } - if (node.directive === 'use server') { - useServer = true; - } - } - - if (!useClient && !useServer) { - return originalCompile.apply(this, arguments); - } - - if (useClient && useServer) { - throw new Error( - 'Cannot have both "use client" and "use server" directives in the same file.', - ); - } - - if (useClient) { - const moduleId: string = (url.pathToFileURL(filename).href: any); - this.exports = createClientModuleProxy(moduleId); - } - - if (useServer) { - originalCompile.apply(this, arguments); - - const moduleId: string = (url.pathToFileURL(filename).href: any); - - const exports = this.exports; - - // This module is imported server to server, but opts in to exposing functions by - // reference. If there are any functions in the export. - if (typeof exports === 'function') { - // The module exports a function directly, - registerServerReference( - (exports: any), - moduleId, - // Represents the whole Module object instead of a particular import. - null, - ); - } else { - const keys = Object.keys(exports); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const value = exports[keys[i]]; - if (typeof value === 'function') { - registerServerReference((value: any), moduleId, key); - } - } - } - } - }; -}; diff --git a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js b/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js index ecf6a35dfa6e..613a7e7dc862 100644 --- a/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js +++ b/packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js @@ -13,6 +13,7 @@ export type ServerReference = T & { $$typeof: symbol, $$id: string, $$bound: null | Array, + $$location?: Error, }; // eslint-disable-next-line no-unused-vars @@ -81,15 +82,32 @@ export function registerServerReference( id: string, exportName: null | string, ): ServerReference { - return Object.defineProperties((reference: any), { - $$typeof: {value: SERVER_REFERENCE_TAG}, - $$id: { - value: exportName === null ? id : id + '#' + exportName, - configurable: true, - }, - $$bound: {value: null, configurable: true}, - bind: {value: bind, configurable: true}, - }); + const $$typeof = {value: SERVER_REFERENCE_TAG}; + const $$id = { + value: exportName === null ? id : id + '#' + exportName, + configurable: true, + }; + const $$bound = {value: null, configurable: true}; + return Object.defineProperties( + (reference: any), + __DEV__ + ? { + $$typeof, + $$id, + $$bound, + $$location: { + value: Error('react-stack-top-frame'), + configurable: true, + }, + bind: {value: bind, configurable: true}, + } + : { + $$typeof, + $$id, + $$bound, + bind: {value: bind, configurable: true}, + }, + ); } const PROMISE_PROTOTYPE = Promise.prototype; diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOM-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOM-test.js index eef2e824543e..0cf2876fedba 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOM-test.js +++ b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOM-test.js @@ -30,7 +30,7 @@ let Suspense; let ReactServerScheduler; let reactServerAct; -describe('ReactFlightDOM', () => { +describe('ReactFlightTurbopackDOM', () => { beforeEach(() => { // For this first reset we are going to load the dom-node version of react-server-dom-turbopack/server // This can be thought of as essentially being the React Server Components scope with react-server @@ -43,7 +43,7 @@ describe('ReactFlightDOM', () => { // Simulate the condition resolution jest.mock('react-server-dom-turbopack/server', () => - require('react-server-dom-turbopack/server.node.unbundled'), + require('react-server-dom-turbopack/server.node'), ); jest.mock('react', () => require('react/react.react-server')); diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMBrowser-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMBrowser-test.js index a47cca706880..d90e1189d508 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMBrowser-test.js +++ b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMBrowser-test.js @@ -23,7 +23,7 @@ let ReactServerDOMClient; let ReactServerScheduler; let reactServerAct; -describe('ReactFlightDOMBrowser', () => { +describe('ReactFlightTurbopackDOMBrowser', () => { beforeEach(() => { jest.resetModules(); diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMEdge-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMEdge-test.js index 67d25c967f47..767e1f1ed0eb 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMEdge-test.js +++ b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMEdge-test.js @@ -28,7 +28,7 @@ let ReactServerDOMServer; let ReactServerDOMClient; let use; -describe('ReactFlightDOMEdge', () => { +describe('ReactFlightTurbopackDOMEdge', () => { beforeEach(() => { jest.resetModules(); diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMForm-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMForm-test.js deleted file mode 100644 index e7da697fad8e..000000000000 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMForm-test.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @emails react-core - */ - -'use strict'; - -import {insertNodesAndExecuteScripts} from 'react-dom/src/test-utils/FizzTestUtils'; - -// Polyfills for test environment -global.ReadableStream = - require('web-streams-polyfill/ponyfill/es6').ReadableStream; -global.TextEncoder = require('util').TextEncoder; -global.TextDecoder = require('util').TextDecoder; - -// Don't wait before processing work on the server. -// TODO: we can replace this with FlightServer.act(). -global.setTimeout = cb => cb(); - -let container; -let serverExports; -let turbopackServerMap; -let React; -let ReactDOMServer; -let ReactServerDOMServer; -let ReactServerDOMClient; - -describe('ReactFlightDOMForm', () => { - beforeEach(() => { - jest.resetModules(); - // Simulate the condition resolution - jest.mock('react', () => require('react/react.react-server')); - jest.mock('react-server-dom-turbopack/server', () => - require('react-server-dom-turbopack/server.edge'), - ); - ReactServerDOMServer = require('react-server-dom-turbopack/server.edge'); - const TurbopackMock = require('./utils/TurbopackMock'); - serverExports = TurbopackMock.serverExports; - turbopackServerMap = TurbopackMock.turbopackServerMap; - __unmockReact(); - jest.resetModules(); - React = require('react'); - ReactServerDOMClient = require('react-server-dom-turbopack/client.edge'); - ReactDOMServer = require('react-dom/server.edge'); - container = document.createElement('div'); - document.body.appendChild(container); - }); - - afterEach(() => { - document.body.removeChild(container); - }); - - async function POST(formData) { - const boundAction = await ReactServerDOMServer.decodeAction( - formData, - turbopackServerMap, - ); - return boundAction(); - } - - function submit(submitter) { - const form = submitter.form || submitter; - if (!submitter.form) { - submitter = undefined; - } - const submitEvent = new Event('submit', {bubbles: true, cancelable: true}); - submitEvent.submitter = submitter; - const returnValue = form.dispatchEvent(submitEvent); - if (!returnValue) { - return; - } - const action = - (submitter && submitter.getAttribute('formaction')) || form.action; - if (!/\s*javascript:/i.test(action)) { - const method = (submitter && submitter.formMethod) || form.method; - const encType = (submitter && submitter.formEnctype) || form.enctype; - if (method === 'post' && encType === 'multipart/form-data') { - let formData; - if (submitter) { - const temp = document.createElement('input'); - temp.name = submitter.name; - temp.value = submitter.value; - submitter.parentNode.insertBefore(temp, submitter); - formData = new FormData(form); - temp.parentNode.removeChild(temp); - } else { - formData = new FormData(form); - } - return POST(formData); - } - throw new Error('Navigate to: ' + action); - } - } - - async function readIntoContainer(stream) { - const reader = stream.getReader(); - let result = ''; - while (true) { - const {done, value} = await reader.read(); - if (done) { - break; - } - result += Buffer.from(value).toString('utf8'); - } - const temp = document.createElement('div'); - temp.innerHTML = result; - insertNodesAndExecuteScripts(temp, container, null); - } - - it('can submit a passed server action without hydrating it', async () => { - let foo = null; - - const serverAction = serverExports(function action(formData) { - foo = formData.get('foo'); - return 'hello'; - }); - function App() { - return ( -
- -
- ); - } - const rscStream = ReactServerDOMServer.renderToReadableStream(); - const response = ReactServerDOMClient.createFromReadableStream(rscStream, { - ssrManifest: { - moduleMap: null, - moduleLoading: null, - }, - }); - const ssrStream = await ReactDOMServer.renderToReadableStream(response); - await readIntoContainer(ssrStream); - - const form = container.firstChild; - - expect(foo).toBe(null); - - const result = await submit(form); - - expect(result).toBe('hello'); - expect(foo).toBe('bar'); - }); -}); diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMNode-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMNode-test.js index 1276d4d0be40..a7b6ff75d57b 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMNode-test.js +++ b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMNode-test.js @@ -24,7 +24,7 @@ let use; let ReactServerScheduler; let reactServerAct; -describe('ReactFlightDOMNode', () => { +describe('ReactFlightTurbopackDOMNode', () => { beforeEach(() => { jest.resetModules(); diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReply-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReply-test.js index cf328ab2e8fe..04abb546df39 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReply-test.js +++ b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReply-test.js @@ -23,7 +23,7 @@ let ReactServerDOMServer; let ReactServerDOMClient; let ReactServerScheduler; -describe('ReactFlightDOMReply', () => { +describe('ReactFlightTurbopackDOMReply', () => { beforeEach(() => { jest.resetModules(); diff --git a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReplyEdge-test.js b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReplyEdge-test.js index 0cd8605c7e8d..cbc06ef80d50 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReplyEdge-test.js +++ b/packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReplyEdge-test.js @@ -20,7 +20,7 @@ let turbopackServerMap; let ReactServerDOMServer; let ReactServerDOMClient; -describe('ReactFlightDOMReply', () => { +describe('ReactFlightDOMTurbopackReply', () => { beforeEach(() => { jest.resetModules(); // Simulate the condition resolution diff --git a/packages/react-server-dom-turbopack/src/__tests__/utils/TurbopackMock.js b/packages/react-server-dom-turbopack/src/__tests__/utils/TurbopackMock.js index 35c1aae80a02..5ed6fa535740 100644 --- a/packages/react-server-dom-turbopack/src/__tests__/utils/TurbopackMock.js +++ b/packages/react-server-dom-turbopack/src/__tests__/utils/TurbopackMock.js @@ -8,7 +8,6 @@ 'use strict'; const url = require('url'); -const Module = require('module'); let turbopackModuleIdx = 0; const turbopackServerModules = {}; @@ -23,21 +22,9 @@ global.__turbopack_require__ = function (id) { return turbopackClientModules[id] || turbopackServerModules[id]; }; -const previousCompile = Module.prototype._compile; - -const register = require('react-server-dom-turbopack/node-register'); -// Register node compile -register(); - -const nodeCompile = Module.prototype._compile; - -if (previousCompile === nodeCompile) { - throw new Error( - 'Expected the Node loader to register the _compile extension', - ); -} - -Module.prototype._compile = previousCompile; +const Server = require('react-server-dom-turbopack/server'); +const registerServerReference = Server.registerServerReference; +const createClientModuleProxy = Server.createClientModuleProxy; exports.turbopackMap = turbopackClientMap; exports.turbopackModules = turbopackClientModules; @@ -46,20 +33,6 @@ exports.moduleLoading = { prefix: '/prefix/', }; -exports.clientModuleError = function clientModuleError(moduleError) { - const idx = '' + turbopackModuleIdx++; - turbopackErroredModules[idx] = moduleError; - const path = url.pathToFileURL(idx).href; - turbopackClientMap[path] = { - id: idx, - chunks: [], - name: '*', - }; - const mod = new Module(); - nodeCompile.call(mod, '"use client"', idx); - return mod.exports; -}; - exports.clientExports = function clientExports(moduleExports, chunkUrl) { const chunks = []; if (chunkUrl !== undefined) { @@ -107,9 +80,7 @@ exports.clientExports = function clientExports(moduleExports, chunkUrl) { name: 's', }; } - const mod = new Module(); - nodeCompile.call(mod, '"use client"', idx); - return mod.exports; + return createClientModuleProxy(path); }; // This tests server to server references. There's another case of client to server references. @@ -142,8 +113,25 @@ exports.serverExports = function serverExports(moduleExports) { name: 's', }; } - const mod = new Module(); - mod.exports = moduleExports; - nodeCompile.call(mod, '"use server"', idx); - return mod.exports; + + if (typeof exports === 'function') { + // The module exports a function directly, + registerServerReference( + (exports: any), + idx, + // Represents the whole Module object instead of a particular import. + null, + ); + } else { + const keys = Object.keys(exports); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const value = exports[keys[i]]; + if (typeof value === 'function') { + registerServerReference((value: any), idx, key); + } + } + } + + return moduleExports; }; diff --git a/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerBrowser.js b/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerBrowser.js index ef980764942d..11dbe1a7c135 100644 --- a/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerBrowser.js +++ b/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerBrowser.js @@ -14,6 +14,7 @@ import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -131,25 +132,27 @@ function prerender( ); resolve({prelude: stream}); } - const request = createRequest( + const request = createPrerenderRequest( model, turbopackMap, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerEdge.js b/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerEdge.js index ef980764942d..11dbe1a7c135 100644 --- a/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerEdge.js +++ b/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerEdge.js @@ -14,6 +14,7 @@ import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -131,25 +132,27 @@ function prerender( ); resolve({prelude: stream}); } - const request = createRequest( + const request = createPrerenderRequest( model, turbopackMap, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerNode.js b/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerNode.js index e484d4b7e77d..9f25004ea4b6 100644 --- a/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-turbopack/src/server/ReactFlightDOMServerNode.js @@ -22,6 +22,7 @@ import {Readable} from 'stream'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -174,25 +175,27 @@ function prerenderToNodeStream( resolve({prelude: readable}); } - const request = createRequest( + const request = createPrerenderRequest( model, turbopackMap, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-turbopack/src/server/ReactFlightServerConfigTurbopackBundler.js b/packages/react-server-dom-turbopack/src/server/ReactFlightServerConfigTurbopackBundler.js index 2ebc5d3f1042..d8224aff341d 100644 --- a/packages/react-server-dom-turbopack/src/server/ReactFlightServerConfigTurbopackBundler.js +++ b/packages/react-server-dom-turbopack/src/server/ReactFlightServerConfigTurbopackBundler.js @@ -91,3 +91,10 @@ export function getServerReferenceBoundArguments( ): null | Array { return serverReference.$$bound; } + +export function getServerReferenceLocation( + config: ClientManifest, + serverReference: ServerReference, +): void | Error { + return serverReference.$$location; +} diff --git a/packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.js b/packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.js deleted file mode 100644 index badc2ed50b69..000000000000 --- a/packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export { - renderToPipeableStream, - prerenderToNodeStream, - decodeReplyFromBusboy, - decodeReply, - decodeAction, - decodeFormState, - registerServerReference, - registerClientReference, - createClientModuleProxy, - createTemporaryReferenceSet, -} from './ReactFlightDOMServerNode'; diff --git a/packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.stable.js b/packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.stable.js deleted file mode 100644 index 0d159704067e..000000000000 --- a/packages/react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled.stable.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export { - renderToPipeableStream, - decodeReplyFromBusboy, - decodeReply, - decodeAction, - decodeFormState, - registerServerReference, - registerClientReference, - createClientModuleProxy, - createTemporaryReferenceSet, -} from './ReactFlightDOMServerNode'; diff --git a/packages/react-server-dom-turbopack/static.node.unbundled.js b/packages/react-server-dom-turbopack/static.node.unbundled.js deleted file mode 100644 index b2134459afc7..000000000000 --- a/packages/react-server-dom-turbopack/static.node.unbundled.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -export {prerenderToNodeStream} from './src/server/react-flight-dom-server.node.unbundled'; diff --git a/packages/react-server-dom-webpack/package.json b/packages/react-server-dom-webpack/package.json index 7a1fe29d4d4a..f0c33a744116 100644 --- a/packages/react-server-dom-webpack/package.json +++ b/packages/react-server-dom-webpack/package.json @@ -106,6 +106,7 @@ }, "dependencies": { "acorn-loose": "^8.3.0", - "neo-async": "^2.6.1" + "neo-async": "^2.6.1", + "webpack-sources": "^3.2.0" } } diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeLoader.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeLoader.js index 5dab530965bc..9799acc3a07b 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeLoader.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeLoader.js @@ -9,6 +9,9 @@ import * as acorn from 'acorn-loose'; +import readMappings from 'webpack-sources/lib/helpers/readMappings.js'; +import createMappingsSerializer from 'webpack-sources/lib/helpers/createMappingsSerializer.js'; + type ResolveContext = { conditions: Array, parentURL: string | void, @@ -95,45 +98,102 @@ export async function getSource( return defaultGetSource(url, context, defaultGetSource); } -function addLocalExportedNames(names: Map, node: any) { +type ExportedEntry = { + localName: string, + exportedName: string, + type: null | string, + loc: { + start: {line: number, column: number}, + end: {line: number, column: number}, + }, + originalLine: number, + originalColumn: number, + originalSource: number, + nameIndex: number, +}; + +function addExportedEntry( + exportedEntries: Array, + localNames: Set, + localName: string, + exportedName: string, + type: null | 'function', + loc: { + start: {line: number, column: number}, + end: {line: number, column: number}, + }, +) { + if (localNames.has(localName)) { + // If the same local name is exported more than once, we only need one of the names. + return; + } + exportedEntries.push({ + localName, + exportedName, + type, + loc, + originalLine: -1, + originalColumn: -1, + originalSource: -1, + nameIndex: -1, + }); +} + +function addLocalExportedNames( + exportedEntries: Array, + localNames: Set, + node: any, +) { switch (node.type) { case 'Identifier': - names.set(node.name, node.name); + addExportedEntry( + exportedEntries, + localNames, + node.name, + node.name, + null, + node.loc, + ); return; case 'ObjectPattern': for (let i = 0; i < node.properties.length; i++) - addLocalExportedNames(names, node.properties[i]); + addLocalExportedNames(exportedEntries, localNames, node.properties[i]); return; case 'ArrayPattern': for (let i = 0; i < node.elements.length; i++) { const element = node.elements[i]; - if (element) addLocalExportedNames(names, element); + if (element) + addLocalExportedNames(exportedEntries, localNames, element); } return; case 'Property': - addLocalExportedNames(names, node.value); + addLocalExportedNames(exportedEntries, localNames, node.value); return; case 'AssignmentPattern': - addLocalExportedNames(names, node.left); + addLocalExportedNames(exportedEntries, localNames, node.left); return; case 'RestElement': - addLocalExportedNames(names, node.argument); + addLocalExportedNames(exportedEntries, localNames, node.argument); return; case 'ParenthesizedExpression': - addLocalExportedNames(names, node.expression); + addLocalExportedNames(exportedEntries, localNames, node.expression); return; } } function transformServerModule( source: string, - body: any, + program: any, url: string, + sourceMap: any, loader: LoadFunction, ): string { - // If the same local name is exported more than once, we only need one of the names. - const localNames: Map = new Map(); - const localTypes: Map = new Map(); + const body = program.body; + + // This entry list needs to be in source location order. + const exportedEntries: Array = []; + // Dedupe set. + const localNames: Set = new Set(); for (let i = 0; i < body.length; i++) { const node = body[i]; @@ -143,11 +203,24 @@ function transformServerModule( break; case 'ExportDefaultDeclaration': if (node.declaration.type === 'Identifier') { - localNames.set(node.declaration.name, 'default'); + addExportedEntry( + exportedEntries, + localNames, + node.declaration.name, + 'default', + null, + node.declaration.loc, + ); } else if (node.declaration.type === 'FunctionDeclaration') { if (node.declaration.id) { - localNames.set(node.declaration.id.name, 'default'); - localTypes.set(node.declaration.id.name, 'function'); + addExportedEntry( + exportedEntries, + localNames, + node.declaration.id.name, + 'default', + 'function', + node.declaration.id.loc, + ); } else { // TODO: This needs to be rewritten inline because it doesn't have a local name. } @@ -158,41 +231,230 @@ function transformServerModule( if (node.declaration.type === 'VariableDeclaration') { const declarations = node.declaration.declarations; for (let j = 0; j < declarations.length; j++) { - addLocalExportedNames(localNames, declarations[j].id); + addLocalExportedNames( + exportedEntries, + localNames, + declarations[j].id, + ); } } else { const name = node.declaration.id.name; - localNames.set(name, name); - if (node.declaration.type === 'FunctionDeclaration') { - localTypes.set(name, 'function'); - } + addExportedEntry( + exportedEntries, + localNames, + name, + name, + + node.declaration.type === 'FunctionDeclaration' + ? 'function' + : null, + node.declaration.id.loc, + ); } } if (node.specifiers) { const specifiers = node.specifiers; for (let j = 0; j < specifiers.length; j++) { const specifier = specifiers[j]; - localNames.set(specifier.local.name, specifier.exported.name); + addExportedEntry( + exportedEntries, + localNames, + specifier.local.name, + specifier.exported.name, + null, + specifier.local.loc, + ); } } continue; } } - if (localNames.size === 0) { - return source; - } - let newSrc = source + '\n\n;'; - newSrc += - 'import {registerServerReference} from "react-server-dom-webpack/server";\n'; - localNames.forEach(function (exported, local) { - if (localTypes.get(local) !== 'function') { - // We first check if the export is a function and if so annotate it. - newSrc += 'if (typeof ' + local + ' === "function") '; + + let mappings = + sourceMap && typeof sourceMap.mappings === 'string' + ? sourceMap.mappings + : ''; + let newSrc = source; + + if (exportedEntries.length > 0) { + let lastSourceIndex = 0; + let lastOriginalLine = 0; + let lastOriginalColumn = 0; + let lastNameIndex = 0; + let sourceLineCount = 0; + let lastMappedLine = 0; + + if (sourceMap) { + // We iterate source mapping entries and our matched exports in parallel to source map + // them to their original location. + let nextEntryIdx = 0; + let nextEntryLine = exportedEntries[nextEntryIdx].loc.start.line; + let nextEntryColumn = exportedEntries[nextEntryIdx].loc.start.column; + readMappings( + mappings, + ( + generatedLine: number, + generatedColumn: number, + sourceIndex: number, + originalLine: number, + originalColumn: number, + nameIndex: number, + ) => { + if ( + generatedLine > nextEntryLine || + (generatedLine === nextEntryLine && + generatedColumn > nextEntryColumn) + ) { + // We're past the entry which means that the best match we have is the previous entry. + if (lastMappedLine === nextEntryLine) { + // Match + exportedEntries[nextEntryIdx].originalLine = lastOriginalLine; + exportedEntries[nextEntryIdx].originalColumn = lastOriginalColumn; + exportedEntries[nextEntryIdx].originalSource = lastSourceIndex; + exportedEntries[nextEntryIdx].nameIndex = lastNameIndex; + } else { + // Skip if we didn't have any mappings on the exported line. + } + nextEntryIdx++; + if (nextEntryIdx < exportedEntries.length) { + nextEntryLine = exportedEntries[nextEntryIdx].loc.start.line; + nextEntryColumn = exportedEntries[nextEntryIdx].loc.start.column; + } else { + nextEntryLine = -1; + nextEntryColumn = -1; + } + } + lastMappedLine = generatedLine; + if (sourceIndex > -1) { + lastSourceIndex = sourceIndex; + } + if (originalLine > -1) { + lastOriginalLine = originalLine; + } + if (originalColumn > -1) { + lastOriginalColumn = originalColumn; + } + if (nameIndex > -1) { + lastNameIndex = nameIndex; + } + }, + ); + if (nextEntryIdx < exportedEntries.length) { + if (lastMappedLine === nextEntryLine) { + // Match + exportedEntries[nextEntryIdx].originalLine = lastOriginalLine; + exportedEntries[nextEntryIdx].originalColumn = lastOriginalColumn; + exportedEntries[nextEntryIdx].originalSource = lastSourceIndex; + exportedEntries[nextEntryIdx].nameIndex = lastNameIndex; + } + } + + for ( + let lastIdx = mappings.length - 1; + lastIdx >= 0 && mappings[lastIdx] === ';'; + lastIdx-- + ) { + // If the last mapped lines don't contain any segments, we don't get a callback from readMappings + // so we need to pad the number of mapped lines, with one for each empty line. + lastMappedLine++; + } + + sourceLineCount = program.loc.end.line; + if (sourceLineCount < lastMappedLine) { + throw new Error( + 'The source map has more mappings than there are lines.', + ); + } + // If the original source string had more lines than there are mappings in the source map. + // Add some extra padding of unmapped lines so that any lines that we add line up. + for ( + let extraLines = sourceLineCount - lastMappedLine; + extraLines > 0; + extraLines-- + ) { + mappings += ';'; + } + } else { + // If a file doesn't have a source map then we generate a blank source map that just + // contains the original content and segments pointing to the original lines. + sourceLineCount = 1; + let idx = -1; + while ((idx = source.indexOf('\n', idx + 1)) !== -1) { + sourceLineCount++; + } + mappings = 'AAAA' + ';AACA'.repeat(sourceLineCount - 1); + sourceMap = { + version: 3, + sources: [url], + sourcesContent: [source], + mappings: mappings, + sourceRoot: '', + }; + lastSourceIndex = 0; + lastOriginalLine = sourceLineCount; + lastOriginalColumn = 0; + lastNameIndex = -1; + lastMappedLine = sourceLineCount; + + for (let i = 0; i < exportedEntries.length; i++) { + // Point each entry to original location. + const entry = exportedEntries[i]; + entry.originalSource = 0; + entry.originalLine = entry.loc.start.line; + // We use column zero since we do the short-hand line-only source maps above. + entry.originalColumn = 0; // entry.loc.start.column; + } } - newSrc += 'registerServerReference(' + local + ','; - newSrc += JSON.stringify(url) + ','; - newSrc += JSON.stringify(exported) + ');\n'; - }); + + newSrc += '\n\n;'; + newSrc += + 'import {registerServerReference} from "react-server-dom-webpack/server";\n'; + if (mappings) { + mappings += ';;'; + } + + const createMapping = createMappingsSerializer(); + + // Create an empty mapping pointing to where we last left off to reset the counters. + let generatedLine = 1; + createMapping( + generatedLine, + 0, + lastSourceIndex, + lastOriginalLine, + lastOriginalColumn, + lastNameIndex, + ); + for (let i = 0; i < exportedEntries.length; i++) { + const entry = exportedEntries[i]; + generatedLine++; + if (entry.type !== 'function') { + // We first check if the export is a function and if so annotate it. + newSrc += 'if (typeof ' + entry.localName + ' === "function") '; + } + newSrc += 'registerServerReference(' + entry.localName + ','; + newSrc += JSON.stringify(url) + ','; + newSrc += JSON.stringify(entry.exportedName) + ');\n'; + + mappings += createMapping( + generatedLine, + 0, + entry.originalSource, + entry.originalLine, + entry.originalColumn, + entry.nameIndex, + ); + } + } + + if (sourceMap) { + // Override with an new mappings and serialize an inline source map. + sourceMap.mappings = mappings; + newSrc += + '//# sourceMappingURL=data:application/json;charset=utf-8;base64,' + + Buffer.from(JSON.stringify(sourceMap)).toString('base64'); + } + return newSrc; } @@ -307,10 +569,13 @@ async function parseExportNamesInto( } async function transformClientModule( - body: any, + program: any, url: string, + sourceMap: any, loader: LoadFunction, ): Promise { + const body = program.body; + const names: Array = []; await parseExportNamesInto(body, names, url, loader); @@ -351,6 +616,9 @@ async function transformClientModule( newSrc += JSON.stringify(url) + ','; newSrc += JSON.stringify(name) + ');\n'; } + + // TODO: Generate source maps for Client Reference functions so they can point to their + // original locations. return newSrc; } @@ -391,12 +659,36 @@ async function transformModuleIfNeeded( return source; } - let body; + let sourceMappingURL = null; + let sourceMappingStart = 0; + let sourceMappingEnd = 0; + let sourceMappingLines = 0; + + let program; try { - body = acorn.parse(source, { + program = acorn.parse(source, { ecmaVersion: '2024', sourceType: 'module', - }).body; + locations: true, + onComment( + block: boolean, + text: string, + start: number, + end: number, + startLoc: {line: number, column: number}, + endLoc: {line: number, column: number}, + ) { + if ( + text.startsWith('# sourceMappingURL=') || + text.startsWith('@ sourceMappingURL=') + ) { + sourceMappingURL = text.slice(19); + sourceMappingStart = start; + sourceMappingEnd = end; + sourceMappingLines = endLoc.line - startLoc.line; + } + }, + }); } catch (x) { // eslint-disable-next-line react-internal/no-production-logging console.error('Error parsing %s %s', url, x.message); @@ -405,6 +697,8 @@ async function transformModuleIfNeeded( let useClient = false; let useServer = false; + + const body = program.body; for (let i = 0; i < body.length; i++) { const node = body[i]; if (node.type !== 'ExpressionStatement' || !node.directive) { @@ -428,11 +722,38 @@ async function transformModuleIfNeeded( ); } + let sourceMap = null; + if (sourceMappingURL) { + const sourceMapResult = await loader( + sourceMappingURL, + // $FlowFixMe + { + format: 'json', + conditions: [], + importAssertions: {type: 'json'}, + importAttributes: {type: 'json'}, + }, + loader, + ); + const sourceMapString = + typeof sourceMapResult.source === 'string' + ? sourceMapResult.source + : // $FlowFixMe + sourceMapResult.source.toString('utf8'); + sourceMap = JSON.parse(sourceMapString); + + // Strip the source mapping comment. We'll re-add it below if needed. + source = + source.slice(0, sourceMappingStart) + + '\n'.repeat(sourceMappingLines) + + source.slice(sourceMappingEnd); + } + if (useClient) { - return transformClientModule(body, url, loader); + return transformClientModule(program, url, sourceMap, loader); } - return transformServerModule(source, body, url, loader); + return transformServerModule(source, program, url, sourceMap, loader); } export async function transformSource( diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js index 6d14f412063c..025a7368213f 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js @@ -13,6 +13,7 @@ export type ServerReference = T & { $$typeof: symbol, $$id: string, $$bound: null | Array, + $$location?: Error, }; // eslint-disable-next-line no-unused-vars @@ -89,15 +90,32 @@ export function registerServerReference( id: string, exportName: null | string, ): ServerReference { - return Object.defineProperties((reference: any), { - $$typeof: {value: SERVER_REFERENCE_TAG}, - $$id: { - value: exportName === null ? id : id + '#' + exportName, - configurable: true, - }, - $$bound: {value: null, configurable: true}, - bind: {value: bind, configurable: true}, - }); + const $$typeof = {value: SERVER_REFERENCE_TAG}; + const $$id = { + value: exportName === null ? id : id + '#' + exportName, + configurable: true, + }; + const $$bound = {value: null, configurable: true}; + return Object.defineProperties( + (reference: any), + __DEV__ + ? { + $$typeof, + $$id, + $$bound, + $$location: { + value: Error('react-stack-top-frame'), + configurable: true, + }, + bind: {value: bind, configurable: true}, + } + : { + $$typeof, + $$id, + $$bound, + bind: {value: bind, configurable: true}, + }, + ); } const PROMISE_PROTOTYPE = Promise.prototype; diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js index faaf8aef01b0..41fc0bfd4108 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js @@ -2722,4 +2722,263 @@ describe('ReactFlightDOM', () => { await readInto(container, fizzReadable); expect(getMeaningfulChildren(container)).toEqual(
hello world
); }); + + // @gate enableHalt + it('does not propagate abort reasons errors when aborting a prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ + + +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const controller = new AbortController(); + const errors = []; + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream( + , + webpackMap, + { + signal: controller.signal, + onError(err) { + errors.push(err); + }, + }, + ), + }; + }); + + controller.abort('boom'); + resolveGreeting(); + const {prelude} = await pendingResult; + + expect(errors).toEqual(['boom']); + + const preludeWeb = Readable.toWeb(prelude); + const response = ReactServerDOMClient.createFromReadableStream(preludeWeb); + + const {writable: fizzWritable, readable: fizzReadable} = getTestStream(); + + function ClientApp() { + return use(response); + } + + errors.length = 0; + let abortFizz; + await serverAct(async () => { + const {pipe, abort} = ReactDOMFizzServer.renderToPipeableStream( + React.createElement(ClientApp), + { + onError(error) { + errors.push(error); + }, + }, + ); + pipe(fizzWritable); + abortFizz = abort; + }); + + await serverAct(() => { + abortFizz('bam'); + }); + + if (__DEV__) { + expect(errors).toEqual([new Error('Connection closed.')]); + } else { + // This is likely a bug. In Dev we get a connection closed error + // because the debug info creates a chunk that has a pending status + // and when the stream finishes we error if any chunks are still pending. + // In production there is no debug info so the missing chunk is never instantiated + // because nothing triggers model evaluation before the stream completes + expect(errors).toEqual(['bam']); + } + + const container = document.createElement('div'); + await readInto(container, fizzReadable); + expect(getMeaningfulChildren(container)).toEqual(
loading...
); + }); + + // @gate enableHalt + it('will leave async iterables in an incomplete state when halting', async () => { + let resolve; + const wait = new Promise(r => (resolve = r)); + const errors = []; + + const multiShotIterable = { + async *[Symbol.asyncIterator]() { + yield {hello: 'A'}; + await wait; + yield {hi: 'B'}; + return 'C'; + }, + }; + + const controller = new AbortController(); + const {pendingResult} = await serverAct(() => { + return { + pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream( + { + multiShotIterable, + }, + {}, + { + onError(x) { + errors.push(x); + }, + signal: controller.signal, + }, + ), + }; + }); + + controller.abort(); + await serverAct(() => resolve()); + + const {prelude} = await pendingResult; + + const result = await ReactServerDOMClient.createFromReadableStream( + Readable.toWeb(prelude), + ); + + const iterator = result.multiShotIterable[Symbol.asyncIterator](); + + expect(await iterator.next()).toEqual({ + value: {hello: 'A'}, + done: false, + }); + + const race = Promise.race([ + iterator.next(), + new Promise(r => setTimeout(() => r('timeout'), 10)), + ]); + + await 1; + jest.advanceTimersByTime('100'); + expect(await race).toBe('timeout'); + }); + + // @gate enableHalt + it('will halt unfinished chunks inside Suspense when aborting a prerender', async () => { + const controller = new AbortController(); + function ComponentThatAborts() { + controller.abort('boom'); + return null; + } + + async function Greeting() { + await 1; + return 'hello world'; + } + + async function Farewell() { + return 'goodbye world'; + } + + async function Wrapper() { + return ( + + + + ); + } + + function App() { + return ( +
+ + + + + + + +
+ ); + } + + const errors = []; + const {pendingResult} = await serverAct(() => { + return { + pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream( + , + {}, + { + onError(x) { + errors.push(x); + }, + signal: controller.signal, + }, + ), + }; + }); + + const {prelude} = await pendingResult; + + expect(errors).toEqual(['boom']); + + const preludeWeb = Readable.toWeb(prelude); + const response = ReactServerDOMClient.createFromReadableStream(preludeWeb); + + const {writable: fizzWritable, readable: fizzReadable} = getTestStream(); + + function ClientApp() { + return use(response); + } + errors.length = 0; + let abortFizz; + await serverAct(async () => { + const {pipe, abort} = ReactDOMFizzServer.renderToPipeableStream( + React.createElement(ClientApp), + { + onError(error, errorInfo) { + errors.push(error); + }, + }, + ); + pipe(fizzWritable); + abortFizz = abort; + }); + + await serverAct(() => { + abortFizz('boom'); + }); + + // one error per boundary + if (__DEV__) { + const err = new Error('Connection closed.'); + expect(errors).toEqual([err, err, err]); + } else { + // This is likely a bug. In Dev we get a connection closed error + // because the debug info creates a chunk that has a pending status + // and when the stream finishes we error if any chunks are still pending. + // In production there is no debug info so the missing chunk is never instantiated + // because nothing triggers model evaluation before the stream completes + expect(errors).toEqual(['boom', 'boom', 'boom']); + } + + const container = document.createElement('div'); + await readInto(container, fizzReadable); + expect(getMeaningfulChildren(container)).toEqual( +
+ {'loading...'} + {'loading too...'} + {'loading three...'} +
, + ); + }); }); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js index db8edf7ad683..fa1e65862564 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js @@ -29,6 +29,7 @@ let ReactDOM; let ReactDOMClient; let ReactDOMFizzServer; let ReactServerDOMServer; +let ReactServerDOMStaticServer; let ReactServerDOMClient; let Suspense; let use; @@ -60,7 +61,13 @@ describe('ReactFlightDOMBrowser', () => { serverExports = WebpackMock.serverExports; webpackMap = WebpackMock.webpackMap; webpackServerMap = WebpackMock.webpackServerMap; - ReactServerDOMServer = require('react-server-dom-webpack/server.browser'); + ReactServerDOMServer = require('react-server-dom-webpack/server'); + if (__EXPERIMENTAL__) { + jest.mock('react-server-dom-webpack/static', () => + require('react-server-dom-webpack/static.browser'), + ); + ReactServerDOMStaticServer = require('react-server-dom-webpack/static'); + } __unmockReact(); jest.resetModules(); @@ -1386,9 +1393,21 @@ describe('ReactFlightDOMBrowser', () => { const body = await ReactServerDOMClient.encodeReply(args); return callServer(ref, body); }, + undefined, + undefined, + 'upper', ), }; + expect(ServerModuleBImportedOnClient.upper.name).toBe( + __DEV__ ? 'upper' : 'action', + ); + if (__DEV__) { + expect(ServerModuleBImportedOnClient.upper.toString()).toBe( + '(...args) => server(...args)', + ); + } + function Client({action}) { // Client side pass a Server Reference into an action. actionProxy = text => action(ServerModuleBImportedOnClient.upper, text); @@ -2332,4 +2351,131 @@ describe('ReactFlightDOMBrowser', () => { expect(error.digest).toBe('aborted'); expect(errors).toEqual([reason]); }); + + // @gate experimental + it('can prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerender( + , + webpackMap, + ), + }; + }); + + resolveGreeting(); + const {prelude} = await pendingResult; + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromReadableStream( + passThrough(prelude), + ); + const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(container); + + await act(() => { + root.render(); + }); + expect(container.innerHTML).toBe('
hello world
'); + }); + + // @gate enableHalt + it('does not propagate abort reasons errors when aborting a prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ + + +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const controller = new AbortController(); + const errors = []; + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerender( + , + webpackMap, + { + signal: controller.signal, + onError(err) { + errors.push(err); + }, + }, + ), + }; + }); + + controller.abort('boom'); + resolveGreeting(); + const {prelude} = await pendingResult; + expect(errors).toEqual(['boom']); + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromReadableStream( + passThrough(prelude), + ); + const container = document.createElement('div'); + errors.length = 0; + const root = ReactDOMClient.createRoot(container, { + onUncaughtError(err) { + errors.push(err); + }, + }); + + await act(() => { + root.render(); + }); + + if (__DEV__) { + expect(errors).toEqual([new Error('Connection closed.')]); + expect(container.innerHTML).toBe(''); + } else { + // This is likely a bug. In Dev we get a connection closed error + // because the debug info creates a chunk that has a pending status + // and when the stream finishes we error if any chunks are still pending. + // In production there is no debug info so the missing chunk is never instantiated + // because nothing triggers model evaluation before the stream completes + expect(errors).toEqual([]); + expect(container.innerHTML).toBe('
loading...
'); + } + }); }); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js index ffef621e9761..27dbcc067e91 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js @@ -23,10 +23,6 @@ if (typeof File === 'undefined' || typeof FormData === 'undefined') { // Patch for Edge environments for global scope global.AsyncLocalStorage = require('async_hooks').AsyncLocalStorage; -// Don't wait before processing work on the server. -// TODO: we can replace this with FlightServer.act(). -global.setTimeout = cb => cb(); - let serverExports; let clientExports; let webpackMap; @@ -36,8 +32,10 @@ let React; let ReactServer; let ReactDOMServer; let ReactServerDOMServer; +let ReactServerDOMStaticServer; let ReactServerDOMClient; let use; +let reactServerAct; function normalizeCodeLocInfo(str) { return ( @@ -52,6 +50,8 @@ describe('ReactFlightDOMEdge', () => { beforeEach(() => { jest.resetModules(); + reactServerAct = require('internal-test-utils').serverAct; + // Simulate the condition resolution jest.mock('react', () => require('react/react.react-server')); jest.mock('react-server-dom-webpack/server', () => @@ -68,6 +68,12 @@ describe('ReactFlightDOMEdge', () => { ReactServer = require('react'); ReactServerDOMServer = require('react-server-dom-webpack/server'); + if (__EXPERIMENTAL__) { + jest.mock('react-server-dom-webpack/static', () => + require('react-server-dom-webpack/static.edge'), + ); + ReactServerDOMStaticServer = require('react-server-dom-webpack/static'); + } jest.resetModules(); __unmockReact(); @@ -81,6 +87,17 @@ describe('ReactFlightDOMEdge', () => { use = React.use; }); + async function serverAct(callback) { + let maybePromise; + await reactServerAct(() => { + maybePromise = callback(); + if (maybePromise && typeof maybePromise.catch === 'function') { + maybePromise.catch(() => {}); + } + }); + return maybePromise; + } + function passThrough(stream) { // Simulate more realistic network by splitting up and rejoining some chunks. // This lets us test that we don't accidentally rely on particular bounds of the chunks. @@ -174,9 +191,8 @@ describe('ReactFlightDOMEdge', () => { return ; } - const stream = ReactServerDOMServer.renderToReadableStream( - , - webpackMap, + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(, webpackMap), ); const response = ReactServerDOMClient.createFromReadableStream(stream, { ssrManifest: { @@ -189,8 +205,8 @@ describe('ReactFlightDOMEdge', () => { return use(response); } - const ssrStream = await ReactDOMServer.renderToReadableStream( - , + const ssrStream = await serverAct(() => + ReactDOMServer.renderToReadableStream(), ); const result = await readResult(ssrStream); expect(result).toEqual('Client Component'); @@ -200,10 +216,12 @@ describe('ReactFlightDOMEdge', () => { const testString = '"\n\t'.repeat(500) + '🙃'; const testString2 = 'hello'.repeat(400); - const stream = ReactServerDOMServer.renderToReadableStream({ - text: testString, - text2: testString2, - }); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream({ + text: testString, + text2: testString2, + }), + ); const [stream1, stream2] = passThrough(stream).tee(); const serializedContent = await readResult(stream1); @@ -234,7 +252,9 @@ describe('ReactFlightDOMEdge', () => { with: {many: 'properties in it'}, }; const props = {root:
{new Array(30).fill(obj)}
}; - const stream = ReactServerDOMServer.renderToReadableStream(props); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(props), + ); const [stream1, stream2] = passThrough(stream).tee(); const serializedContent = await readResult(stream1); @@ -302,7 +322,9 @@ describe('ReactFlightDOMEdge', () => { ); const resolvedChildren = new Array(30).fill(str); - const stream = ReactServerDOMServer.renderToReadableStream(children); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(children), + ); const [stream1, stream2] = passThrough(stream).tee(); const serializedContent = await readResult(stream1); @@ -318,7 +340,9 @@ describe('ReactFlightDOMEdge', () => { }); // Use the SSR render to resolve any lazy elements - const ssrStream = await ReactDOMServer.renderToReadableStream(model); + const ssrStream = await serverAct(() => + ReactDOMServer.renderToReadableStream(model), + ); // Should still match the result when parsed const result = await readResult(ssrStream); expect(result).toEqual(resolvedChildren.join('')); @@ -370,22 +394,28 @@ describe('ReactFlightDOMEdge', () => { const resolvedChildren = new Array(30).fill( '
this is a long return value
', ); - const stream = ReactServerDOMServer.renderToReadableStream(children); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(children), + ); const [stream1, stream2] = passThrough(stream).tee(); const serializedContent = await readResult(stream1); expect(serializedContent.length).toBeLessThan(__DEV__ ? 605 : 400); expect(timesRendered).toBeLessThan(5); - const model = await ReactServerDOMClient.createFromReadableStream(stream2, { - ssrManifest: { - moduleMap: null, - moduleLoading: null, - }, - }); + const model = await serverAct(() => + ReactServerDOMClient.createFromReadableStream(stream2, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }), + ); // Use the SSR render to resolve any lazy elements - const ssrStream = await ReactDOMServer.renderToReadableStream(model); + const ssrStream = await serverAct(() => + ReactDOMServer.renderToReadableStream(model), + ); // Should still match the result when parsed const result = await readResult(ssrStream); expect(result).toEqual(resolvedChildren.join('')); @@ -398,8 +428,10 @@ describe('ReactFlightDOMEdge', () => { } return
Fin
; } - const stream = ReactServerDOMServer.renderToReadableStream( - , + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream( + , + ), ); const serializedContent = await readResult(stream); const expectedDebugInfoSize = __DEV__ ? 300 * 20 : 0; @@ -426,8 +458,8 @@ describe('ReactFlightDOMEdge', () => { new BigUint64Array(buffer, 0), new DataView(buffer, 3), ]; - const stream = passThrough( - ReactServerDOMServer.renderToReadableStream(buffers), + const stream = await serverAct(() => + passThrough(ReactServerDOMServer.renderToReadableStream(buffers)), ); const result = await ReactServerDOMClient.createFromReadableStream(stream, { ssrManifest: { @@ -446,8 +478,8 @@ describe('ReactFlightDOMEdge', () => { const blob = new Blob([bytes, bytes], { type: 'application/x-test', }); - const stream = passThrough( - ReactServerDOMServer.renderToReadableStream(blob), + const stream = await serverAct(() => + passThrough(ReactServerDOMServer.renderToReadableStream(blob)), ); const result = await ReactServerDOMClient.createFromReadableStream(stream, { ssrManifest: { @@ -476,8 +508,8 @@ describe('ReactFlightDOMEdge', () => { expect(formData.get('file') instanceof File).toBe(true); expect(formData.get('file').name).toBe('filename.test'); - const stream = passThrough( - ReactServerDOMServer.renderToReadableStream(formData), + const stream = await serverAct(() => + passThrough(ReactServerDOMServer.renderToReadableStream(formData)), ); const result = await ReactServerDOMClient.createFromReadableStream(stream, { ssrManifest: { @@ -507,8 +539,8 @@ describe('ReactFlightDOMEdge', () => { const map = new Map(); map.set('value', awaitedValue); - const stream = passThrough( - ReactServerDOMServer.renderToReadableStream(map, webpackMap), + const stream = await serverAct(() => + passThrough(ReactServerDOMServer.renderToReadableStream(map, webpackMap)), ); // Parsing the root blocks because the module hasn't loaded yet @@ -549,16 +581,18 @@ describe('ReactFlightDOMEdge', () => { }, }); - const stream = passThrough( - ReactServerDOMServer.renderToReadableStream(s, webpackMap), + const stream = await serverAct(() => + passThrough(ReactServerDOMServer.renderToReadableStream(s, webpackMap)), ); - const result = await ReactServerDOMClient.createFromReadableStream(stream, { - ssrManifest: { - moduleMap: null, - moduleLoading: null, - }, - }); + const result = await serverAct(() => + ReactServerDOMClient.createFromReadableStream(stream, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }), + ); const reader = result.getReader(); @@ -589,20 +623,24 @@ describe('ReactFlightDOMEdge', () => { }, }; - const stream = passThrough( - ReactServerDOMServer.renderToReadableStream( - multiShotIterable, - webpackMap, + const stream = await serverAct(() => + passThrough( + ReactServerDOMServer.renderToReadableStream( + multiShotIterable, + webpackMap, + ), ), ); // Parsing the root blocks because the module hasn't loaded yet - const result = await ReactServerDOMClient.createFromReadableStream(stream, { - ssrManifest: { - moduleMap: null, - moduleLoading: null, - }, - }); + const result = await serverAct(() => + ReactServerDOMClient.createFromReadableStream(stream, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }), + ); const iterator = result[Symbol.asyncIterator](); @@ -635,9 +673,11 @@ describe('ReactFlightDOMEdge', () => { }, }; - const stream = ReactServerDOMServer.renderToReadableStream({ - iterable, - }); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream({ + iterable, + }), + ); const [stream1, stream2] = passThrough(stream).tee(); const serializedContent = await readResult(stream1); @@ -728,7 +768,9 @@ describe('ReactFlightDOMEdge', () => { }, }); - const stream = ReactServerDOMServer.renderToReadableStream(s, {}); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(s, {}), + ); const [stream1, stream2] = passThrough(stream).tee(); @@ -785,7 +827,9 @@ describe('ReactFlightDOMEdge', () => { }, }); - const stream = ReactServerDOMServer.renderToReadableStream(s, {}); + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(s, {}), + ); const [stream1, stream2] = passThrough(stream).tee(); @@ -841,23 +885,21 @@ describe('ReactFlightDOMEdge', () => { greeting: ReactServer.createElement(Greeting, {firstName: 'Seb'}), }; - const stream = ReactServerDOMServer.renderToReadableStream( - model, - webpackMap, + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(model, webpackMap), ); - const rootModel = await ReactServerDOMClient.createFromReadableStream( - stream, - { + const rootModel = await serverAct(() => + ReactServerDOMClient.createFromReadableStream(stream, { ssrManifest: { moduleMap: null, moduleLoading: null, }, - }, + }), ); - const ssrStream = await ReactDOMServer.renderToReadableStream( - rootModel.greeting, + const ssrStream = await serverAct(() => + ReactDOMServer.renderToReadableStream(rootModel.greeting), ); const result = await readResult(ssrStream); expect(result).toEqual('Hello, Seb'); @@ -916,13 +958,15 @@ describe('ReactFlightDOMEdge', () => { return ReactServer.createElement('span', null, 'hi'); } - const stream = ReactServerDOMServer.renderToReadableStream( - ReactServer.createElement( - 'div', - null, - ReactServer.createElement(Foo, null), + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream( + ReactServer.createElement( + 'div', + null, + ReactServer.createElement(Foo, null), + ), + webpackMap, ), - webpackMap, ); await readResult(stream); @@ -943,35 +987,31 @@ describe('ReactFlightDOMEdge', () => { root: ReactServer.createElement(Erroring), }; - const stream = ReactServerDOMServer.renderToReadableStream( - model, - webpackMap, - { + const stream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(model, webpackMap, { onError() {}, - }, + }), ); - const rootModel = await ReactServerDOMClient.createFromReadableStream( - stream, - { + const rootModel = await serverAct(() => + ReactServerDOMClient.createFromReadableStream(stream, { ssrManifest: { moduleMap: null, moduleLoading: null, }, - }, + }), ); const errors = []; - const result = ReactDOMServer.renderToReadableStream( -
{rootModel.root}
, - { + const result = serverAct(() => + ReactDOMServer.renderToReadableStream(
{rootModel.root}
, { onError(error, {componentStack}) { errors.push({ error, componentStack: normalizeCodeLocInfo(componentStack), }); }, - }, + }), ); const theError = new Error('my error'); @@ -1000,4 +1040,145 @@ describe('ReactFlightDOMEdge', () => { }, ]); }); + + // @gate experimental + it('can prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerender( + , + webpackMap, + ), + }; + }); + + resolveGreeting(); + const {prelude} = await pendingResult; + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromReadableStream(prelude, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }); + // Use the SSR render to resolve any lazy elements + const ssrStream = await serverAct(() => + ReactDOMServer.renderToReadableStream( + React.createElement(ClientRoot, {response}), + ), + ); + // Should still match the result when parsed + const result = await readResult(ssrStream); + expect(result).toBe('
hello world
'); + }); + + // @gate enableHalt + it('does not propagate abort reasons errors when aborting a prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ + + +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const controller = new AbortController(); + const errors = []; + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerender( + , + webpackMap, + { + signal: controller.signal, + onError(err) { + errors.push(err); + }, + }, + ), + }; + }); + + controller.abort('boom'); + resolveGreeting(); + const {prelude} = await pendingResult; + + expect(errors).toEqual(['boom']); + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromReadableStream(prelude, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }); + const fizzController = new AbortController(); + errors.length = 0; + const ssrStream = await serverAct(() => + ReactDOMServer.renderToReadableStream( + React.createElement(ClientRoot, {response}), + { + signal: fizzController.signal, + onError(error) { + errors.push(error); + }, + }, + ), + ); + fizzController.abort('bam'); + if (__DEV__) { + expect(errors).toEqual([new Error('Connection closed.')]); + } else { + // This is likely a bug. In Dev we get a connection closed error + // because the debug info creates a chunk that has a pending status + // and when the stream finishes we error if any chunks are still pending. + // In production there is no debug info so the missing chunk is never instantiated + // because nothing triggers model evaluation before the stream completes + expect(errors).toEqual(['bam']); + } + // Should still match the result when parsed + const result = await readResult(ssrStream); + const div = document.createElement('div'); + div.innerHTML = result; + expect(div.textContent).toBe('loading...'); + }); }); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js index 2de34cc1c493..f2dca4a45c7f 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js @@ -20,7 +20,9 @@ let webpackModules; let webpackModuleLoading; let React; let ReactDOMServer; +let ReactServer; let ReactServerDOMServer; +let ReactServerDOMStaticServer; let ReactServerDOMClient; let Stream; let use; @@ -45,7 +47,14 @@ describe('ReactFlightDOMNode', () => { jest.mock('react-server-dom-webpack/server', () => require('react-server-dom-webpack/server.node'), ); + ReactServer = require('react'); ReactServerDOMServer = require('react-server-dom-webpack/server'); + if (__EXPERIMENTAL__) { + jest.mock('react-server-dom-webpack/static', () => + require('react-server-dom-webpack/static.node'), + ); + ReactServerDOMStaticServer = require('react-server-dom-webpack/static'); + } const WebpackMock = require('./utils/WebpackMock'); clientExports = WebpackMock.clientExports; @@ -378,4 +387,142 @@ describe('ReactFlightDOMNode', () => { expect(error.digest).toBe('aborted'); expect(errors).toEqual([reason]); }); + + // @gate experimental + it('can prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream( + , + webpackMap, + ), + }; + }); + + resolveGreeting(); + const {prelude} = await pendingResult; + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromNodeStream(prelude, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }); + // Use the SSR render to resolve any lazy elements + const ssrStream = await serverAct(() => + ReactDOMServer.renderToPipeableStream( + React.createElement(ClientRoot, {response}), + ), + ); + // Should still match the result when parsed + const result = await readResult(ssrStream); + expect(result).toBe('
hello world
'); + }); + + // @gate enableHalt + it('does not propagate abort reasons errors when aborting a prerender', async () => { + let resolveGreeting; + const greetingPromise = new Promise(resolve => { + resolveGreeting = resolve; + }); + + function App() { + return ( +
+ + + +
+ ); + } + + async function Greeting() { + await greetingPromise; + return 'hello world'; + } + + const controller = new AbortController(); + const errors = []; + const {pendingResult} = await serverAct(async () => { + // destructure trick to avoid the act scope from awaiting the returned value + return { + pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream( + , + webpackMap, + { + signal: controller.signal, + onError(err) { + errors.push(err); + }, + }, + ), + }; + }); + + controller.abort('boom'); + resolveGreeting(); + const {prelude} = await pendingResult; + expect(errors).toEqual(['boom']); + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromNodeStream(prelude, { + ssrManifest: { + moduleMap: null, + moduleLoading: null, + }, + }); + errors.length = 0; + const ssrStream = await serverAct(() => + ReactDOMServer.renderToPipeableStream( + React.createElement(ClientRoot, {response}), + { + onError(error) { + errors.push(error); + }, + }, + ), + ); + ssrStream.abort('bam'); + if (__DEV__) { + expect(errors).toEqual([new Error('Connection closed.')]); + } else { + // This is likely a bug. In Dev we get a connection closed error + // because the debug info creates a chunk that has a pending status + // and when the stream finishes we error if any chunks are still pending. + // In production there is no debug info so the missing chunk is never instantiated + // because nothing triggers model evaluation before the stream completes + expect(errors).toEqual(['bam']); + } + // Should still match the result when parsed + const result = await readResult(ssrStream); + const div = document.createElement('div'); + div.innerHTML = result; + expect(div.textContent).toBe('loading...'); + }); }); diff --git a/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerBrowser.js b/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerBrowser.js index a4e0c3bef693..7954417b95a2 100644 --- a/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerBrowser.js +++ b/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerBrowser.js @@ -14,6 +14,7 @@ import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -131,25 +132,27 @@ function prerender( ); resolve({prelude: stream}); } - const request = createRequest( + const request = createPrerenderRequest( model, webpackMap, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerEdge.js b/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerEdge.js index a4e0c3bef693..7954417b95a2 100644 --- a/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerEdge.js +++ b/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerEdge.js @@ -14,6 +14,7 @@ import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -131,25 +132,27 @@ function prerender( ); resolve({prelude: stream}); } - const request = createRequest( + const request = createPrerenderRequest( model, webpackMap, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerNode.js b/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerNode.js index 150625947670..f459e04914b6 100644 --- a/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-webpack/src/server/ReactFlightDOMServerNode.js @@ -22,6 +22,7 @@ import {Readable} from 'stream'; import { createRequest, + createPrerenderRequest, startWork, startFlowing, stopFlowing, @@ -174,25 +175,27 @@ function prerenderToNodeStream( resolve({prelude: readable}); } - const request = createRequest( + const request = createPrerenderRequest( model, webpackMap, + onAllReady, + onFatalError, options ? options.onError : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, options ? options.temporaryReferences : undefined, __DEV__ && options ? options.environmentName : undefined, __DEV__ && options ? options.filterStackFrame : undefined, - onAllReady, - onFatalError, ); if (options && options.signal) { const signal = options.signal; if (signal.aborted) { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); } else { const listener = () => { - abort(request, (signal: any).reason); + const reason = (signal: any).reason; + abort(request, reason); signal.removeEventListener('abort', listener); }; signal.addEventListener('abort', listener); diff --git a/packages/react-server-dom-webpack/src/server/ReactFlightServerConfigWebpackBundler.js b/packages/react-server-dom-webpack/src/server/ReactFlightServerConfigWebpackBundler.js index a0872b61fa47..d29516ff946e 100644 --- a/packages/react-server-dom-webpack/src/server/ReactFlightServerConfigWebpackBundler.js +++ b/packages/react-server-dom-webpack/src/server/ReactFlightServerConfigWebpackBundler.js @@ -91,3 +91,10 @@ export function getServerReferenceBoundArguments( ): null | Array { return serverReference.$$bound; } + +export function getServerReferenceLocation( + config: ClientManifest, + serverReference: ServerReference, +): void | Error { + return serverReference.$$location; +} diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index a6c77f8bafb7..7ccbd65d16b7 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -38,6 +38,7 @@ import {describeObjectForErrorMessage} from 'shared/ReactSerializationErrors'; import { scheduleWork, + scheduleMicrotask, beginWriting, writeChunk, writeChunkAndReturn, @@ -157,6 +158,7 @@ import { enableSuspenseAvoidThisFallbackFizz, enableCache, enablePostpone, + enableHalt, enableRenderableContext, enableRefAsProp, disableDefaultPropsExceptForClasses, @@ -652,8 +654,6 @@ export function resumeRequest( return request; } -const AbortSigil = {}; - let currentRequest: null | Request = null; export function resolveRequest(): null | Request { @@ -670,7 +670,11 @@ function pingTask(request: Request, task: Task): void { pingedTasks.push(task); if (request.pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(() => performWork(request)); + if (request.trackedPostpones !== null) { + scheduleMicrotask(() => performWork(request)); + } else { + scheduleWork(() => performWork(request)); + } } } @@ -1173,7 +1177,7 @@ function renderSuspenseBoundary( ); boundarySegment.status = COMPLETED; } catch (thrownValue: mixed) { - if (thrownValue === AbortSigil) { + if (request.status === ABORTING) { boundarySegment.status = ABORTED; } else { boundarySegment.status = ERRORED; @@ -1246,7 +1250,7 @@ function renderSuspenseBoundary( } catch (thrownValue: mixed) { newBoundary.status = CLIENT_RENDERED; let error: mixed; - if (thrownValue === AbortSigil) { + if (request.status === ABORTING) { contentRootSegment.status = ABORTED; error = request.fatalError; } else { @@ -1601,7 +1605,8 @@ function finishClassComponent( nextChildren = instance.render(); } if (request.status === ABORTING) { - throw AbortSigil; + // eslint-disable-next-line no-throw-literal + throw null; } if (__DEV__) { @@ -1757,7 +1762,8 @@ function renderFunctionComponent( legacyContext, ); if (request.status === ABORTING) { - throw AbortSigil; + // eslint-disable-next-line no-throw-literal + throw null; } const hasId = checkDidRenderIdHook(); @@ -2076,7 +2082,8 @@ function renderLazyComponent( Component = init(payload); } if (request.status === ABORTING) { - throw AbortSigil; + // eslint-disable-next-line no-throw-literal + throw null; } const resolvedProps = resolveDefaultPropsOnNonClassComponent( Component, @@ -2655,7 +2662,8 @@ function retryNode(request: Request, task: Task): void { resolvedNode = init(payload); } if (request.status === ABORTING) { - throw AbortSigil; + // eslint-disable-next-line no-throw-literal + throw null; } // Now we render the resolved node renderNodeDestructive(request, task, resolvedNode, childIndex); @@ -3623,6 +3631,9 @@ function erroredTask( ) { // Report the error to a global handler. let errorDigest; + // We don't handle halts here because we only halt when prerendering and + // when prerendering we should be finishing tasks not erroring them when + // they halt or postpone if ( enablePostpone && typeof error === 'object' && @@ -3810,6 +3821,17 @@ function abortTask(task: Task, request: Request, error: mixed): void { logRecoverableError(request, fatal, errorInfo, null); fatalError(request, fatal, errorInfo, null); } + } else if ( + enableHalt && + request.trackedPostpones !== null && + segment !== null + ) { + const trackedPostpones = request.trackedPostpones; + // We are aborting a prerender and must treat the shell as halted + // We log the error but we still resolve the prerender + logRecoverableError(request, error, errorInfo, null); + trackPostpone(request, trackedPostpones, task, segment); + finishedTask(request, null, segment); } else { logRecoverableError(request, error, errorInfo, null); fatalError(request, error, errorInfo, null); @@ -3854,11 +3876,40 @@ function abortTask(task: Task, request: Request, error: mixed): void { } } else { boundary.pendingTasks--; + // We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which + // boundary the message is referring to + const errorInfo = getThrownInfo(task.componentStack); + const trackedPostpones = request.trackedPostpones; if (boundary.status !== CLIENT_RENDERED) { + if (enableHalt) { + if (trackedPostpones !== null && segment !== null) { + // We are aborting a prerender + if ( + enablePostpone && + typeof error === 'object' && + error !== null && + error.$$typeof === REACT_POSTPONE_TYPE + ) { + const postponeInstance: Postpone = (error: any); + logPostpone(request, postponeInstance.message, errorInfo, null); + } else { + // We are aborting a prerender and must halt this boundary. + // We treat this like other postpones during prerendering + logRecoverableError(request, error, errorInfo, null); + } + trackPostpone(request, trackedPostpones, task, segment); + // If this boundary was still pending then we haven't already cancelled its fallbacks. + // We'll need to abort the fallbacks, which will also error that parent boundary. + boundary.fallbackAbortableTasks.forEach(fallbackTask => + abortTask(fallbackTask, request, error), + ); + boundary.fallbackAbortableTasks.clear(); + return finishedTask(request, boundary, segment); + } + } boundary.status = CLIENT_RENDERED; - // We construct an errorInfo from the boundary's componentStack so the error in dev will indicate which - // boundary the message is referring to - const errorInfo = getThrownInfo(task.componentStack); + // We are aborting a render or resume which should put boundaries + // into an explicitly client rendered state let errorDigest; if ( enablePostpone && @@ -3868,11 +3919,24 @@ function abortTask(task: Task, request: Request, error: mixed): void { ) { const postponeInstance: Postpone = (error: any); logPostpone(request, postponeInstance.message, errorInfo, null); + if (request.trackedPostpones !== null && segment !== null) { + trackPostpone(request, request.trackedPostpones, task, segment); + finishedTask(request, task.blockedBoundary, segment); + + // If this boundary was still pending then we haven't already cancelled its fallbacks. + // We'll need to abort the fallbacks, which will also error that parent boundary. + boundary.fallbackAbortableTasks.forEach(fallbackTask => + abortTask(fallbackTask, request, error), + ); + boundary.fallbackAbortableTasks.clear(); + return; + } // TODO: Figure out a better signal than a magic digest value. errorDigest = 'POSTPONE'; } else { errorDigest = logRecoverableError(request, error, errorInfo, null); } + boundary.status = CLIENT_RENDERED; encodeErrorForBoundary(boundary, errorDigest, error, errorInfo, true); untrackBoundary(request, boundary); @@ -4127,10 +4191,47 @@ function retryRenderTask( // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue === AbortSigil + : request.status === ABORTING ? request.fatalError : thrownValue; + if ( + enableHalt && + request.status === ABORTING && + request.trackedPostpones !== null + ) { + // We are aborting a prerender and need to halt this task. + const trackedPostpones = request.trackedPostpones; + const thrownInfo = getThrownInfo(task.componentStack); + task.abortSet.delete(task); + + if ( + enablePostpone && + typeof x === 'object' && + x !== null && + x.$$typeof === REACT_POSTPONE_TYPE + ) { + const postponeInstance: Postpone = (x: any); + logPostpone( + request, + postponeInstance.message, + thrownInfo, + __DEV__ && enableOwnerStacks ? task.debugTask : null, + ); + } else { + logRecoverableError( + request, + x, + thrownInfo, + __DEV__ && enableOwnerStacks ? task.debugTask : null, + ); + } + + trackPostpone(request, trackedPostpones, task, segment); + finishedTask(request, task.blockedBoundary, segment); + return; + } + if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { @@ -4250,7 +4351,7 @@ function retryReplayTask(request: Request, task: ReplayTask): void { erroredReplay( request, task.blockedBoundary, - x === AbortSigil ? request.fatalError : x, + request.status === ABORTING ? request.fatalError : x, errorInfo, task.replay.nodes, task.replay.slots, @@ -4797,12 +4898,22 @@ function flushCompletedQueues( export function startWork(request: Request): void { request.flushScheduled = request.destination !== null; - if (supportsRequestStorage) { - scheduleWork(() => requestStorage.run(request, performWork, request)); + if (request.trackedPostpones !== null) { + // When prerendering we use microtasks for pinging work + if (supportsRequestStorage) { + scheduleMicrotask(() => + requestStorage.run(request, performWork, request), + ); + } else { + scheduleMicrotask(() => performWork(request)); + } } else { - scheduleWork(() => performWork(request)); - } - if (request.trackedPostpones === null) { + // When rendering/resuming we use regular tasks and we also emit early preloads + if (supportsRequestStorage) { + scheduleWork(() => requestStorage.run(request, performWork, request)); + } else { + scheduleWork(() => performWork(request)); + } // this is either a regular render or a resume. For regular render we want // to call emitEarlyPreloads after the first performWork because we want // are responding to a live request and need to balance sending something early diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index d8ba106d37e7..df811a8c7fa9 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -16,6 +16,7 @@ import type {TemporaryReferenceSet} from './ReactFlightServerTemporaryReferences import { enableBinaryFlight, enablePostpone, + enableHalt, enableTaint, enableRefAsProp, enableServerComponentLogs, @@ -63,6 +64,7 @@ import type { ReactComponentInfo, ReactAsyncInfo, ReactStackTrace, + ReactCallSite, } from 'shared/ReactTypes'; import type {ReactElement} from 'shared/ReactElementType'; import type {LazyComponent} from 'react/src/ReactLazy'; @@ -71,6 +73,7 @@ import { resolveClientReferenceMetadata, getServerReferenceId, getServerReferenceBoundArguments, + getServerReferenceLocation, getClientReferenceKey, isClientReference, isServerReference, @@ -350,7 +353,8 @@ type Task = { interface Reference {} export type Request = { - status: 0 | 1 | 2 | 3, + status: 10 | 11 | 12 | 13, + type: 20 | 21, flushScheduled: boolean, fatalError: mixed, destination: null | Destination, @@ -422,13 +426,17 @@ function defaultPostponeHandler(reason: string) { // Noop } -const OPEN = 0; -const ABORTING = 1; -const CLOSING = 2; -const CLOSED = 3; +const OPEN = 10; +const ABORTING = 11; +const CLOSING = 12; +const CLOSED = 13; + +const RENDER = 20; +const PRERENDER = 21; function RequestInstance( this: $FlowFixMe, + type: 20 | 21, model: ReactClientValue, bundlerConfig: ClientManifest, onError: void | ((error: mixed) => ?string), @@ -437,8 +445,8 @@ function RequestInstance( temporaryReferences: void | TemporaryReferenceSet, environmentName: void | string | (() => string), // DEV-only filterStackFrame: void | ((url: string, functionName: string) => boolean), // DEV-only - onAllReady: void | (() => void), - onFatalError: void | ((error: mixed) => void), + onAllReady: () => void, + onFatalError: (error: mixed) => void, ) { if ( ReactSharedInternals.A !== null && @@ -463,6 +471,7 @@ function RequestInstance( TaintRegistryPendingRequests.add(cleanupQueue); } const hints = createHints(); + this.type = type; this.status = OPEN; this.flushScheduled = false; this.fatalError = null; @@ -490,8 +499,8 @@ function RequestInstance( this.onError = onError === undefined ? defaultErrorHandler : onError; this.onPostpone = onPostpone === undefined ? defaultPostponeHandler : onPostpone; - this.onAllReady = onAllReady === undefined ? noop : onAllReady; - this.onFatalError = onFatalError === undefined ? noop : onFatalError; + this.onAllReady = onAllReady; + this.onFatalError = onFatalError; if (__DEV__) { this.environmentName = @@ -519,7 +528,7 @@ function RequestInstance( pingedTasks.push(rootTask); } -function noop(): void {} +function noop() {} export function createRequest( model: ReactClientValue, @@ -530,11 +539,38 @@ export function createRequest( temporaryReferences: void | TemporaryReferenceSet, environmentName: void | string | (() => string), // DEV-only filterStackFrame: void | ((url: string, functionName: string) => boolean), // DEV-only - onAllReady: void | (() => void), - onFatalError: void | (() => void), ): Request { // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors return new RequestInstance( + RENDER, + model, + bundlerConfig, + onError, + identifierPrefix, + onPostpone, + temporaryReferences, + environmentName, + filterStackFrame, + noop, + noop, + ); +} + +export function createPrerenderRequest( + model: ReactClientValue, + bundlerConfig: ClientManifest, + onAllReady: () => void, + onFatalError: () => void, + onError: void | ((error: mixed) => ?string), + identifierPrefix?: string, + onPostpone: void | ((reason: string) => void), + temporaryReferences: void | TemporaryReferenceSet, + environmentName: void | string | (() => string), // DEV-only + filterStackFrame: void | ((url: string, functionName: string) => boolean), // DEV-only +): Request { + // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors + return new RequestInstance( + PRERENDER, model, bundlerConfig, onError, @@ -611,11 +647,15 @@ function serializeThenable( default: { if (request.status === ABORTING) { // We can no longer accept any resolved values - newTask.status = ABORTED; - const errorId: number = (request.fatalError: any); - const model = stringify(serializeByValueID(errorId)); - emitModelChunk(request, newTask.id, model); request.abortableTasks.delete(newTask); + newTask.status = ABORTED; + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + const errorId: number = (request.fatalError: any); + const model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + } return newTask.id; } if (typeof thenable.status === 'string') { @@ -725,7 +765,7 @@ function serializeReadableStream( } if (entry.done) { - request.abortListeners.delete(error); + request.abortListeners.delete(abortStream); const endStreamRow = streamTask.id.toString(16) + ':C\n'; request.completedRegularChunks.push(stringToChunk(endStreamRow)); enqueueFlush(request); @@ -747,7 +787,20 @@ function serializeReadableStream( return; } aborted = true; - request.abortListeners.delete(error); + request.abortListeners.delete(abortStream); + const digest = logRecoverableError(request, reason, streamTask); + emitErrorChunk(request, streamTask.id, digest, reason); + enqueueFlush(request); + + // $FlowFixMe should be able to pass mixed + reader.cancel(reason).then(error, error); + } + function abortStream(reason: mixed) { + if (aborted) { + return; + } + aborted = true; + request.abortListeners.delete(abortStream); if ( enablePostpone && typeof reason === 'object' && @@ -756,16 +809,27 @@ function serializeReadableStream( ) { const postponeInstance: Postpone = (reason: any); logPostpone(request, postponeInstance.message, streamTask); - emitPostponeChunk(request, streamTask.id, postponeInstance); + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + emitPostponeChunk(request, streamTask.id, postponeInstance); + enqueueFlush(request); + } } else { const digest = logRecoverableError(request, reason, streamTask); - emitErrorChunk(request, streamTask.id, digest, reason); + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + emitErrorChunk(request, streamTask.id, digest, reason); + enqueueFlush(request); + } } - enqueueFlush(request); + // $FlowFixMe should be able to pass mixed reader.cancel(reason).then(error, error); } - request.abortListeners.add(error); + + request.abortListeners.add(abortStream); reader.read().then(progress, error); return serializeByValueID(streamTask.id); } @@ -821,7 +885,7 @@ function serializeAsyncIterable( } if (entry.done) { - request.abortListeners.delete(error); + request.abortListeners.delete(abortIterable); let endStreamRow; if (entry.value === undefined) { endStreamRow = streamTask.id.toString(16) + ':C\n'; @@ -865,7 +929,22 @@ function serializeAsyncIterable( return; } aborted = true; - request.abortListeners.delete(error); + request.abortListeners.delete(abortIterable); + const digest = logRecoverableError(request, reason, streamTask); + emitErrorChunk(request, streamTask.id, digest, reason); + enqueueFlush(request); + if (typeof (iterator: any).throw === 'function') { + // The iterator protocol doesn't necessarily include this but a generator do. + // $FlowFixMe should be able to pass mixed + iterator.throw(reason).then(error, error); + } + } + function abortIterable(reason: mixed) { + if (aborted) { + return; + } + aborted = true; + request.abortListeners.delete(abortIterable); if ( enablePostpone && typeof reason === 'object' && @@ -874,19 +953,28 @@ function serializeAsyncIterable( ) { const postponeInstance: Postpone = (reason: any); logPostpone(request, postponeInstance.message, streamTask); - emitPostponeChunk(request, streamTask.id, postponeInstance); + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + emitPostponeChunk(request, streamTask.id, postponeInstance); + enqueueFlush(request); + } } else { const digest = logRecoverableError(request, reason, streamTask); - emitErrorChunk(request, streamTask.id, digest, reason); + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + emitErrorChunk(request, streamTask.id, digest, reason); + enqueueFlush(request); + } } - enqueueFlush(request); if (typeof (iterator: any).throw === 'function') { // The iterator protocol doesn't necessarily include this but a generator do. // $FlowFixMe should be able to pass mixed iterator.throw(reason).then(error, error); } } - request.abortListeners.add(error); + request.abortListeners.add(abortIterable); if (__DEV__) { callIteratorInDEV(iterator, progress, error); } else { @@ -1549,6 +1637,24 @@ function outlineTask(request: Request, task: Task): ReactJSONValue { return serializeLazyID(newTask.id); } +function outlineHaltedTask( + request: Request, + task: Task, + allowLazy: boolean, +): ReactJSONValue { + // In the future if we track task state for resuming we'll maybe need to + // construnct an actual task here but since we're never going to retry it + // we just claim the id and serialize it according to the proper convention + const taskId = request.nextChunkId++; + if (allowLazy) { + // We're halting in a position that can handle a lazy reference + return serializeLazyID(taskId); + } else { + // We're halting in a position that needs a value reference + return serializeByValueID(taskId); + } +} + function renderElement( request: Request, task: Task, @@ -1688,7 +1794,11 @@ function pingTask(request: Request, task: Task): void { pingedTasks.push(task); if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleMicrotask(() => performWork(request)); + if (request.type === PRERENDER) { + scheduleMicrotask(() => performWork(request)); + } else { + scheduleWork(() => performWork(request)); + } } } @@ -1934,17 +2044,47 @@ function serializeServerReference( return serializeServerReferenceID(existingId); } - const bound: null | Array = getServerReferenceBoundArguments( + const boundArgs: null | Array = getServerReferenceBoundArguments( request.bundlerConfig, serverReference, ); + const bound = boundArgs === null ? null : Promise.resolve(boundArgs); + const id = getServerReferenceId(request.bundlerConfig, serverReference); + + let location: null | ReactCallSite = null; + if (__DEV__) { + const error = getServerReferenceLocation( + request.bundlerConfig, + serverReference, + ); + if (error) { + const frames = parseStackTrace(error, 1); + if (frames.length > 0) { + location = frames[0]; + } + } + } + const serverReferenceMetadata: { id: ServerReferenceId, bound: null | Promise>, - } = { - id: getServerReferenceId(request.bundlerConfig, serverReference), - bound: bound ? Promise.resolve(bound) : null, - }; + name?: string, // DEV-only + env?: string, // DEV-only + location?: ReactCallSite, // DEV-only + } = + __DEV__ && location !== null + ? { + id, + bound, + name: + typeof serverReference === 'function' ? serverReference.name : '', + env: (0, request.environmentName)(), + location, + } + : { + id, + bound, + }; const metadataId = outlineModel(request, serverReferenceMetadata); writtenServerReferences.set(serverReference, metadataId); return serializeServerReferenceID(metadataId); @@ -2049,7 +2189,7 @@ function serializeBlob(request: Request, blob: Blob): string { return; } if (entry.done) { - request.abortListeners.delete(error); + request.abortListeners.delete(abortBlob); aborted = true; pingTask(request, newTask); return; @@ -2059,22 +2199,52 @@ function serializeBlob(request: Request, blob: Blob): string { // $FlowFixMe[incompatible-call] return reader.read().then(progress).catch(error); } - function error(reason: mixed) { if (aborted) { return; } aborted = true; - request.abortListeners.delete(error); + request.abortListeners.delete(abortBlob); const digest = logRecoverableError(request, reason, newTask); emitErrorChunk(request, newTask.id, digest, reason); - request.abortableTasks.delete(newTask); enqueueFlush(request); // $FlowFixMe should be able to pass mixed reader.cancel(reason).then(error, error); } + function abortBlob(reason: mixed) { + if (aborted) { + return; + } + aborted = true; + request.abortListeners.delete(abortBlob); + if ( + enablePostpone && + typeof reason === 'object' && + reason !== null && + (reason: any).$$typeof === REACT_POSTPONE_TYPE + ) { + const postponeInstance: Postpone = (reason: any); + logPostpone(request, postponeInstance.message, newTask); + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + emitPostponeChunk(request, newTask.id, postponeInstance); + enqueueFlush(request); + } + } else { + const digest = logRecoverableError(request, reason, newTask); + if (enableHalt && request.type === PRERENDER) { + request.pendingChunks--; + } else { + emitErrorChunk(request, newTask.id, digest, reason); + enqueueFlush(request); + } + } + // $FlowFixMe should be able to pass mixed + reader.cancel(reason).then(error, error); + } - request.abortListeners.add(error); + request.abortListeners.add(abortBlob); // $FlowFixMe[incompatible-call] reader.read().then(progress).catch(error); @@ -2134,6 +2304,20 @@ function renderModel( ((model: any).$$typeof === REACT_ELEMENT_TYPE || (model: any).$$typeof === REACT_LAZY_TYPE); + if (request.status === ABORTING) { + task.status = ABORTED; + if (enableHalt && request.type === PRERENDER) { + // This will create a new task and refer to it in this slot + // the new task won't be retried because we are aborting + return outlineHaltedTask(request, task, wasReactNode); + } + const errorId = (request.fatalError: any); + if (wasReactNode) { + return serializeLazyID(errorId); + } + return serializeByValueID(errorId); + } + const x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical @@ -2147,14 +2331,6 @@ function renderModel( if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - if (request.status === ABORTING) { - task.status = ABORTED; - const errorId: number = (request.fatalError: any); - if (wasReactNode) { - return serializeLazyID(errorId); - } - return serializeByValueID(errorId); - } // Something suspended, we'll need to create a new task and resolve it later. const newTask = createTask( request, @@ -2200,15 +2376,6 @@ function renderModel( } } - if (request.status === ABORTING) { - task.status = ABORTED; - const errorId: number = (request.fatalError: any); - if (wasReactNode) { - return serializeLazyID(errorId); - } - return serializeByValueID(errorId); - } - // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. task.keyPath = prevKeyPath; @@ -3676,6 +3843,22 @@ function retryTask(request: Request, task: Task): void { request.abortableTasks.delete(task); task.status = COMPLETED; } catch (thrownValue) { + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + if (enableHalt && request.type === PRERENDER) { + // When aborting a prerener with halt semantics we don't emit + // anything into the slot for a task that aborts, it remains unresolved + request.pendingChunks--; + } else { + // Otherwise we emit an error chunk into the task slot. + const errorId: number = (request.fatalError: any); + const model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + } + return; + } + const x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical @@ -3688,14 +3871,6 @@ function retryTask(request: Request, task: Task): void { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - if (request.status === ABORTING) { - request.abortableTasks.delete(task); - task.status = ABORTED; - const errorId: number = (request.fatalError: any); - const model = stringify(serializeByValueID(errorId)); - emitModelChunk(request, task.id, model); - return; - } // Something suspended again, let's pick it back up later. task.status = PENDING; task.thenableState = getThenableStateAfterSuspending(); @@ -3712,15 +3887,6 @@ function retryTask(request: Request, task: Task): void { } } - if (request.status === ABORTING) { - request.abortableTasks.delete(task); - task.status = ABORTED; - const errorId: number = (request.fatalError: any); - const model = stringify(serializeByValueID(errorId)); - emitModelChunk(request, task.id, model); - return; - } - request.abortableTasks.delete(task); task.status = ERRORED; const digest = logRecoverableError(request, x, task); @@ -3757,6 +3923,7 @@ function performWork(request: Request): void { currentRequest = request; prepareToUseHooksForRequest(request); + const hadAbortableTasks = request.abortableTasks.size > 0; try { const pingedTasks = request.pingedTasks; request.pingedTasks = []; @@ -3767,8 +3934,10 @@ function performWork(request: Request): void { if (request.destination !== null) { flushCompletedChunks(request, request.destination); } - if (request.abortableTasks.size === 0) { - // we're done rendering + if (hadAbortableTasks && request.abortableTasks.size === 0) { + // We can ping after completing but if this happens there already + // wouldn't be any abortable tasks. So we only call allReady after + // the work which actually completed the last pending task const onAllReady = request.onAllReady; onAllReady(); } @@ -3795,6 +3964,17 @@ function abortTask(task: Task, request: Request, errorId: number): void { request.completedErrorChunks.push(processedChunk); } +function haltTask(task: Task, request: Request): void { + if (task.status === RENDERING) { + // this task will be halted by the render + return; + } + task.status = ABORTED; + // We don't actually emit anything for this task id because we are intentionally + // leaving the reference unfulfilled. + request.pendingChunks--; +} + function flushCompletedChunks( request: Request, destination: Destination, @@ -3880,10 +4060,20 @@ function flushCompletedChunks( export function startWork(request: Request): void { request.flushScheduled = request.destination !== null; - if (supportsRequestStorage) { - scheduleWork(() => requestStorage.run(request, performWork, request)); + if (request.type === PRERENDER) { + if (supportsRequestStorage) { + scheduleMicrotask(() => { + requestStorage.run(request, performWork, request); + }); + } else { + scheduleMicrotask(() => performWork(request)); + } } else { - scheduleWork(() => performWork(request)); + if (supportsRequestStorage) { + scheduleWork(() => requestStorage.run(request, performWork, request)); + } else { + scheduleWork(() => performWork(request)); + } } } @@ -3897,6 +4087,8 @@ function enqueueFlush(request: Request): void { request.destination !== null ) { request.flushScheduled = true; + // Unlike startWork and pingTask we intetionally use scheduleWork + // here even during prerenders to allow as much batching as possible scheduleWork(() => { request.flushScheduled = false; const destination = request.destination; @@ -3933,19 +4125,13 @@ export function stopFlowing(request: Request): void { request.destination = null; } -// This is called to early terminate a request. It creates an error at all pending tasks. export function abort(request: Request, reason: mixed): void { try { if (request.status === OPEN) { request.status = ABORTING; } const abortableTasks = request.abortableTasks; - // We have tasks to abort. We'll emit one error row and then emit a reference - // to that row from every row that's still remaining. if (abortableTasks.size > 0) { - request.pendingChunks++; - const errorId = request.nextChunkId++; - request.fatalError = errorId; if ( enablePostpone && typeof reason === 'object' && @@ -3954,7 +4140,21 @@ export function abort(request: Request, reason: mixed): void { ) { const postponeInstance: Postpone = (reason: any); logPostpone(request, postponeInstance.message, null); - emitPostponeChunk(request, errorId, postponeInstance); + if (enableHalt && request.type === PRERENDER) { + // When prerendering with halt semantics we simply halt the task + // and leave the reference unfulfilled. + abortableTasks.forEach(task => haltTask(task, request)); + abortableTasks.clear(); + } else { + // When rendering we produce a shared postpone chunk and then + // fulfill each task with a reference to that chunk. + const errorId = request.nextChunkId++; + request.fatalError = errorId; + request.pendingChunks++; + emitPostponeChunk(request, errorId, postponeInstance); + abortableTasks.forEach(task => abortTask(task, request, errorId)); + abortableTasks.clear(); + } } else { const error = reason === undefined @@ -3969,10 +4169,24 @@ export function abort(request: Request, reason: mixed): void { ) : reason; const digest = logRecoverableError(request, error, null); - emitErrorChunk(request, errorId, digest, error); + if (enableHalt && request.type === PRERENDER) { + // When prerendering with halt semantics we simply halt the task + // and leave the reference unfulfilled. + abortableTasks.forEach(task => haltTask(task, request)); + abortableTasks.clear(); + } else { + // When rendering we produce a shared error chunk and then + // fulfill each task with a reference to that chunk. + const errorId = request.nextChunkId++; + request.fatalError = errorId; + request.pendingChunks++; + emitErrorChunk(request, errorId, digest, error); + abortableTasks.forEach(task => abortTask(task, request, errorId)); + abortableTasks.clear(); + } } - abortableTasks.forEach(task => abortTask(task, request, errorId)); - abortableTasks.clear(); + const onAllReady = request.onAllReady; + onAllReady(); } const abortListeners = request.abortListeners; if (abortListeners.size > 0) { diff --git a/packages/react-server/src/ReactFlightServerConfigBundlerCustom.js b/packages/react-server/src/ReactFlightServerConfigBundlerCustom.js index 00578a4da245..ac3e17c63017 100644 --- a/packages/react-server/src/ReactFlightServerConfigBundlerCustom.js +++ b/packages/react-server/src/ReactFlightServerConfigBundlerCustom.js @@ -23,3 +23,4 @@ export const resolveClientReferenceMetadata = export const getServerReferenceId = $$$config.getServerReferenceId; export const getServerReferenceBoundArguments = $$$config.getServerReferenceBoundArguments; +export const getServerReferenceLocation = $$$config.getServerReferenceLocation; diff --git a/packages/react-server/src/forks/ReactFlightServerConfig.markup.js b/packages/react-server/src/forks/ReactFlightServerConfig.markup.js index 12feb37ac569..7c879de39f27 100644 --- a/packages/react-server/src/forks/ReactFlightServerConfig.markup.js +++ b/packages/react-server/src/forks/ReactFlightServerConfig.markup.js @@ -90,3 +90,10 @@ export function getServerReferenceBoundArguments( 'Use a fixed URL for any forms instead.', ); } + +export function getServerReferenceLocation( + config: ClientManifest, + serverReference: ServerReference, +): void { + return undefined; +} diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index b0286405a6cc..673ff9d7e845 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -87,6 +87,8 @@ export const enableTaint = __EXPERIMENTAL__; export const enablePostpone = __EXPERIMENTAL__; +export const enableHalt = __EXPERIMENTAL__; + /** * Switches the Fabric API from doing layout in commit work instead of complete work. */ @@ -146,6 +148,8 @@ export const enableOwnerStacks = __EXPERIMENTAL__; export const enableShallowPropDiffing = false; +export const enableSiblingPrerendering = __EXPERIMENTAL__; + /** * Enables an expiration time for retry lanes to avoid starvation. */ diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js index 2426206bc825..2d49c56377a2 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js @@ -25,3 +25,4 @@ export const enableShallowPropDiffing = __VARIANT__; export const passChildrenWhenCloningPersistedNodes = __VARIANT__; export const enableFabricCompleteRootInCommitPhase = __VARIANT__; export const enableLazyContextPropagation = __VARIANT__; +export const enableSiblingPrerendering = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 4eda27d16cfc..6ba5a79ff0f3 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -27,6 +27,7 @@ export const { enableShallowPropDiffing, passChildrenWhenCloningPersistedNodes, enableLazyContextPropagation, + enableSiblingPrerendering, } = dynamicFlags; // The rest of the flags are static for better dead code elimination. @@ -58,6 +59,7 @@ export const enableFilterEmptyStringAttributesDOM = true; export const enableFizzExternalRuntime = true; export const enableFlightReadableStream = true; export const enableGetInspectorDataForInstanceInProduction = true; +export const enableHalt = false; export const enableInfiniteRenderLoopDetection = true; export const enableContextProfiling = false; export const enableLegacyCache = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 2a4421f41da0..4e50442c2579 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -49,6 +49,7 @@ export const enableFilterEmptyStringAttributesDOM = true; export const enableFizzExternalRuntime = true; export const enableFlightReadableStream = true; export const enableGetInspectorDataForInstanceInProduction = false; +export const enableHalt = false; export const enableInfiniteRenderLoopDetection = true; export const enableLazyContextPropagation = false; export const enableContextProfiling = false; @@ -83,6 +84,7 @@ export const retryLaneExpirationMs = 5000; export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; export const useModernStrictMode = true; +export const enableSiblingPrerendering = false; // Profiling Only export const enableProfilerTimer = __PROFILE__; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 8778bf6558cb..ae211b9ec463 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -25,6 +25,7 @@ export const enableFlightReadableStream = true; export const enableAsyncIterableChildren = false; export const enableTaint = true; export const enablePostpone = false; +export const enableHalt = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; export const disableIEWorkarounds = true; @@ -79,6 +80,7 @@ export const enableAddPropertiesFastPath = false; export const renameElementSymbol = true; export const enableShallowPropDiffing = false; +export const enableSiblingPrerendering = __EXPERIMENTAL__; // TODO: This must be in sync with the main ReactFeatureFlags file because // the Test Renderer's value must be the same as the one used by the diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index 3a8a0c1d44ce..ebc3ddab2a55 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -40,6 +40,7 @@ export const enableFilterEmptyStringAttributesDOM = true; export const enableFizzExternalRuntime = true; export const enableFlightReadableStream = true; export const enableGetInspectorDataForInstanceInProduction = false; +export const enableHalt = false; export const enableInfiniteRenderLoopDetection = true; export const enableLazyContextPropagation = false; export const enableContextProfiling = false; @@ -79,6 +80,7 @@ export const syncLaneExpirationMs = 250; export const transitionLaneExpirationMs = 5000; export const useModernStrictMode = true; export const enableFabricCompleteRootInCommitPhase = false; +export const enableSiblingPrerendering = false; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType); diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index eb801d7bac4b..a378ab3edf17 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -25,6 +25,7 @@ export const enableFlightReadableStream = true; export const enableAsyncIterableChildren = false; export const enableTaint = true; export const enablePostpone = false; +export const enableHalt = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; export const disableIEWorkarounds = true; @@ -93,6 +94,7 @@ export const renameElementSymbol = false; export const enableObjectFiber = false; export const enableOwnerStacks = false; export const enableShallowPropDiffing = false; +export const enableSiblingPrerendering = false; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType); diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index e2f2751f0c2c..d6e11f92649b 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -41,6 +41,7 @@ export const enableDebugTracing = __EXPERIMENTAL__; export const enableSchedulingProfiler = __VARIANT__; export const enableInfiniteRenderLoopDetection = __VARIANT__; +export const enableSiblingPrerendering = __VARIANT__; // TODO: These flags are hard-coded to the default values used in open source. // Update the tests so that they pass in either mode, then set these diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 95cd1e5a6ebe..e207dbb71b66 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -35,6 +35,7 @@ export const { retryLaneExpirationMs, syncLaneExpirationMs, transitionLaneExpirationMs, + enableSiblingPrerendering, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build. @@ -78,6 +79,8 @@ export const enableTaint = false; export const enablePostpone = false; +export const enableHalt = false; + export const enableContextProfiling = true; // TODO: www currently relies on this feature. It's disabled in open source. diff --git a/scripts/babel/__tests__/transform-test-gate-pragma-test.js b/scripts/babel/__tests__/transform-test-gate-pragma-test.js index f4abf54bec0e..6250b5b4ded1 100644 --- a/scripts/babel/__tests__/transform-test-gate-pragma-test.js +++ b/scripts/babel/__tests__/transform-test-gate-pragma-test.js @@ -221,4 +221,8 @@ describe('dynamic gate method', () => { it('returns same conditions as pragma', () => { expect(gate(ctx => ctx.experimental && ctx.__DEV__)).toBe(true); }); + + it('converts string conditions to accessor function', () => { + expect(gate('experimental')).toBe(gate(flags => flags.experimental)); + }); }); diff --git a/scripts/flow/config/flowconfig b/scripts/flow/config/flowconfig index b2032e0dadcb..46e7b6e96969 100644 --- a/scripts/flow/config/flowconfig +++ b/scripts/flow/config/flowconfig @@ -33,7 +33,6 @@ untyped-type-import=error [options] -%CI_MAX_WORKERS% munge_underscores=false # Substituted by createFlowConfig.js: diff --git a/scripts/flow/createFlowConfigs.js b/scripts/flow/createFlowConfigs.js index c1e847416024..7ff68cce5b03 100644 --- a/scripts/flow/createFlowConfigs.js +++ b/scripts/flow/createFlowConfigs.js @@ -107,11 +107,6 @@ function writeConfig( }); const config = configTemplate - .replace( - '%CI_MAX_WORKERS%\n', - // On CI, we seem to need to limit workers. - process.env.CI ? 'server.max_workers=4\n' : '', - ) .replace('%REACT_RENDERER_FLOW_OPTIONS%', moduleMappings.trim()) .replace('%REACT_RENDERER_FLOW_IGNORES%', ignoredPaths.join('\n')) .replace('%FLOW_VERSION%', flowVersion); diff --git a/scripts/jest/setupTests.js b/scripts/jest/setupTests.js index 722df83f1953..d339c86433a4 100644 --- a/scripts/jest/setupTests.js +++ b/scripts/jest/setupTests.js @@ -205,8 +205,17 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { } }; + const coerceGateConditionToFunction = gateFnOrString => { + return typeof gateFnOrString === 'string' + ? // `gate('foo')` is treated as equivalent to `gate(flags => flags.foo)` + flags => flags[gateFnOrString] + : // Assume this is already a function + gateFnOrString; + }; + const gatedErrorMessage = 'Gated test was expected to fail, but it passed.'; - global._test_gate = (gateFn, testName, callback, timeoutMS) => { + global._test_gate = (gateFnOrString, testName, callback, timeoutMS) => { + const gateFn = coerceGateConditionToFunction(gateFnOrString); let shouldPass; try { const flags = getTestFlags(); @@ -230,7 +239,8 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { expectTestToFail(callback, error, timeoutMS)); } }; - global._test_gate_focus = (gateFn, testName, callback, timeoutMS) => { + global._test_gate_focus = (gateFnOrString, testName, callback, timeoutMS) => { + const gateFn = coerceGateConditionToFunction(gateFnOrString); let shouldPass; try { const flags = getTestFlags(); @@ -259,8 +269,9 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) { }; // Dynamic version of @gate pragma - global.gate = fn => { + global.gate = gateFnOrString => { + const gateFn = coerceGateConditionToFunction(gateFnOrString); const flags = getTestFlags(); - return fn(flags); + return gateFn(flags); }; } diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index ea4d1a034bf4..081b91b9d0b8 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -534,18 +534,6 @@ const bundles = [ wrapWithModuleBoundaries: false, externals: ['react', 'util', 'async_hooks', 'react-dom'], }, - { - bundleTypes: [NODE_DEV, NODE_PROD], - moduleType: RENDERER, - entry: - 'react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled', - name: 'react-server-dom-turbopack-server.node.unbundled', - condition: 'react-server', - global: 'ReactServerDOMServer', - minifyWithProdErrorCodes: false, - wrapWithModuleBoundaries: false, - externals: ['react', 'util', 'async_hooks', 'react-dom'], - }, { bundleTypes: [NODE_DEV, NODE_PROD], moduleType: RENDERER, @@ -577,15 +565,6 @@ const bundles = [ wrapWithModuleBoundaries: false, externals: ['react', 'react-dom', 'util'], }, - { - bundleTypes: [NODE_DEV, NODE_PROD], - moduleType: RENDERER, - entry: 'react-server-dom-turbopack/client.node.unbundled', - global: 'ReactServerDOMClient', - minifyWithProdErrorCodes: false, - wrapWithModuleBoundaries: false, - externals: ['react', 'react-dom', 'util'], - }, { bundleTypes: [NODE_DEV, NODE_PROD], moduleType: RENDERER, @@ -596,35 +575,6 @@ const bundles = [ externals: ['react', 'react-dom'], }, - /******* React Server DOM Turbopack Plugin *******/ - // There is no plugin the moment because Turbopack - // does not expose a plugin interface yet. - - /******* React Server DOM Turbopack Node.js Loader *******/ - { - bundleTypes: [ESM_PROD], - moduleType: RENDERER_UTILS, - entry: 'react-server-dom-turbopack/node-loader', - condition: 'react-server', - global: 'ReactServerTurbopackNodeLoader', - minifyWithProdErrorCodes: false, - wrapWithModuleBoundaries: false, - externals: ['acorn'], - }, - - /******* React Server DOM Turbopack Node.js CommonJS Loader *******/ - { - bundleTypes: [NODE_ES2015], - moduleType: RENDERER_UTILS, - entry: 'react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister', - name: 'react-server-dom-turbopack-node-register', - condition: 'react-server', - global: 'ReactFlightWebpackNodeRegister', - minifyWithProdErrorCodes: false, - wrapWithModuleBoundaries: false, - externals: ['url', 'module', 'react-server-dom-turbopack/server'], - }, - /******* React Server DOM ESM Server *******/ { bundleTypes: [NODE_DEV, NODE_PROD], diff --git a/scripts/rollup/modules.js b/scripts/rollup/modules.js index e1ebc1c945a0..2afa0cc98b10 100644 --- a/scripts/rollup/modules.js +++ b/scripts/rollup/modules.js @@ -22,6 +22,9 @@ const importSideEffects = Object.freeze({ 'react-dom': HAS_NO_SIDE_EFFECTS_ON_IMPORT, url: HAS_NO_SIDE_EFFECTS_ON_IMPORT, ReactNativeInternalFeatureFlags: HAS_NO_SIDE_EFFECTS_ON_IMPORT, + 'webpack-sources/lib/helpers/createMappingsSerializer.js': + HAS_NO_SIDE_EFFECTS_ON_IMPORT, + 'webpack-sources/lib/helpers/readMappings.js': HAS_NO_SIDE_EFFECTS_ON_IMPORT, }); // Bundles exporting globals that other modules rely on. diff --git a/scripts/shared/inlinedHostConfigs.js b/scripts/shared/inlinedHostConfigs.js index be5706c927c7..514ecc4567b0 100644 --- a/scripts/shared/inlinedHostConfigs.js +++ b/scripts/shared/inlinedHostConfigs.js @@ -104,49 +104,6 @@ module.exports = [ }, { shortName: 'dom-node-turbopack', - entryPoints: [ - 'react-server-dom-turbopack/client.node.unbundled', - 'react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled', - ], - paths: [ - 'react-dom', - 'react-dom-bindings', - 'react-dom/client', - 'react-dom/profiling', - 'react-dom/server', - 'react-dom/server.node', - 'react-dom/static', - 'react-dom/static.node', - 'react-dom/src/server/react-dom-server.node', - 'react-dom/src/server/ReactDOMFizzServerNode.js', // react-dom/server.node - 'react-dom/src/server/ReactDOMFizzStaticNode.js', - 'react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js', - 'react-dom-bindings/src/server/ReactFlightServerConfigDOM.js', - 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM.js', - 'react-server-dom-turbopack', - 'react-server-dom-turbopack/client.node.unbundled', - 'react-server-dom-turbopack/server', - 'react-server-dom-turbopack/server.node.unbundled', - 'react-server-dom-turbopack/static', - 'react-server-dom-turbopack/static.node.unbundled', - 'react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js', // react-server-dom-turbopack/client.node.unbundled - 'react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerNode.js', - 'react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled', - 'react-server-dom-turbopack/src/server/ReactFlightDOMServerNode.js', // react-server-dom-turbopack/src/server/react-flight-dom-server.node.unbundled - 'react-server-dom-turbopack/node-register', - 'react-server-dom-turbopack/src/ReactFlightTurbopackNodeRegister.js', - 'react-devtools', - 'react-devtools-core', - 'react-devtools-shell', - 'react-devtools-shared', - 'shared/ReactDOMSharedInternals', - 'react-server/src/ReactFlightServerConfigDebugNode.js', - ], - isFlowTyped: true, - isServerSupported: true, - }, - { - shortName: 'dom-node-turbopack-bundled', entryPoints: [ 'react-server-dom-turbopack/client.node', 'react-server-dom-turbopack/src/server/react-flight-dom-server.node', diff --git a/yarn.lock b/yarn.lock index 3ecf3e738e19..473020cfa1fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11347,11 +11347,6 @@ lodash.omitby@4.6.0: resolved "https://registry.yarnpkg.com/lodash.omitby/-/lodash.omitby-4.6.0.tgz#5c15ff4754ad555016b53c041311e8f079204791" integrity sha1-XBX/R1StVVAWtTwEExHo8HkgR5E= -lodash.throttle@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" - integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= - lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" @@ -11603,11 +11598,6 @@ memfs@^3.4.3: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== -memoize-one@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-3.1.1.tgz#ef609811e3bc28970eac2884eece64d167830d17" - integrity sha512-YqVh744GsMlZu6xkhGslPSqSurOv6P+kLN2J3ysBZfagLcL5FdRK/0UpgLoL8hwjjEvvAVkjJZyFP+1T6p1vgA== - memoize-one@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" @@ -16499,7 +16489,7 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.3: +webpack-sources@^3.2.0, webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==