feat: frontend PWA scaffolding with React and Tailwind

This commit is contained in:
Daniel Bedeleanu
2026-04-10 14:05:50 +03:00
parent 373652e8b8
commit 7f8b24aabb
33622 changed files with 4317382 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
import { PureComponent } from 'react';
import type { GlobalErrorState } from '../../../client/components/app-router-instance';
type AppDevOverlayErrorBoundaryProps = {
children: React.ReactNode;
globalError: GlobalErrorState;
};
type AppDevOverlayErrorBoundaryState = {
reactError: unknown;
};
export declare class AppDevOverlayErrorBoundary extends PureComponent<AppDevOverlayErrorBoundaryProps, AppDevOverlayErrorBoundaryState> {
state: {
reactError: null;
};
static getDerivedStateFromError(error: Error): {
reactError: Error;
};
componentDidCatch(err: Error): void;
render(): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
}
export {};

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AppDevOverlayErrorBoundary", {
enumerable: true,
get: function() {
return AppDevOverlayErrorBoundary;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = require("react");
const _nextdevtools = require("next/dist/compiled/next-devtools");
const _runtimeerrorhandler = require("../../../client/dev/runtime-error-handler");
const _errorboundary = require("../../../client/components/error-boundary");
const _globalerror = /*#__PURE__*/ _interop_require_default._(require("../../../client/components/builtin/global-error"));
const _segmentexplorernode = require("./segment-explorer-node");
function ErroredHtml(param) {
let { globalError: [GlobalError, globalErrorStyles], error } = param;
if (!error) {
return /*#__PURE__*/ (0, _jsxruntime.jsxs)("html", {
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)("head", {}),
/*#__PURE__*/ (0, _jsxruntime.jsx)("body", {})
]
});
}
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_errorboundary.ErrorBoundary, {
errorComponent: _globalerror.default,
children: [
globalErrorStyles,
/*#__PURE__*/ (0, _jsxruntime.jsx)(GlobalError, {
error: error
})
]
});
}
class AppDevOverlayErrorBoundary extends _react.PureComponent {
static getDerivedStateFromError(error) {
_runtimeerrorhandler.RuntimeErrorHandler.hadRuntimeError = true;
return {
reactError: error
};
}
componentDidCatch(err) {
if (process.env.NODE_ENV === 'development' && err.message === _segmentexplorernode.SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE) {
return;
}
_nextdevtools.dispatcher.openErrorOverlay();
}
render() {
const { children, globalError } = this.props;
const { reactError } = this.state;
const fallback = /*#__PURE__*/ (0, _jsxruntime.jsx)(ErroredHtml, {
globalError: globalError,
error: reactError
});
return reactError !== null ? fallback : children;
}
constructor(...args){
super(...args), this.state = {
reactError: null
};
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-dev-overlay-error-boundary.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/next-devtools/userspace/app/app-dev-overlay-error-boundary.tsx"],"sourcesContent":["import { PureComponent } from 'react'\nimport { dispatcher } from 'next/dist/compiled/next-devtools'\nimport { RuntimeErrorHandler } from '../../../client/dev/runtime-error-handler'\nimport { ErrorBoundary } from '../../../client/components/error-boundary'\nimport DefaultGlobalError from '../../../client/components/builtin/global-error'\nimport type { GlobalErrorState } from '../../../client/components/app-router-instance'\nimport { SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE } from './segment-explorer-node'\n\ntype AppDevOverlayErrorBoundaryProps = {\n children: React.ReactNode\n globalError: GlobalErrorState\n}\n\ntype AppDevOverlayErrorBoundaryState = {\n reactError: unknown\n}\n\nfunction ErroredHtml({\n globalError: [GlobalError, globalErrorStyles],\n error,\n}: {\n globalError: GlobalErrorState\n error: unknown\n}) {\n if (!error) {\n return (\n <html>\n <head />\n <body />\n </html>\n )\n }\n return (\n <ErrorBoundary errorComponent={DefaultGlobalError}>\n {globalErrorStyles}\n <GlobalError error={error} />\n </ErrorBoundary>\n )\n}\n\nexport class AppDevOverlayErrorBoundary extends PureComponent<\n AppDevOverlayErrorBoundaryProps,\n AppDevOverlayErrorBoundaryState\n> {\n state = { reactError: null }\n\n static getDerivedStateFromError(error: Error) {\n RuntimeErrorHandler.hadRuntimeError = true\n\n return {\n reactError: error,\n }\n }\n\n componentDidCatch(err: Error) {\n if (\n process.env.NODE_ENV === 'development' &&\n err.message === SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE\n ) {\n return\n }\n dispatcher.openErrorOverlay()\n }\n\n render() {\n const { children, globalError } = this.props\n const { reactError } = this.state\n\n const fallback = (\n <ErroredHtml globalError={globalError} error={reactError} />\n )\n\n return reactError !== null ? fallback : children\n }\n}\n"],"names":["AppDevOverlayErrorBoundary","ErroredHtml","globalError","GlobalError","globalErrorStyles","error","html","head","body","ErrorBoundary","errorComponent","DefaultGlobalError","PureComponent","getDerivedStateFromError","RuntimeErrorHandler","hadRuntimeError","reactError","componentDidCatch","err","process","env","NODE_ENV","message","SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE","dispatcher","openErrorOverlay","render","children","props","state","fallback"],"mappings":";;;;+BAwCaA;;;eAAAA;;;;;uBAxCiB;8BACH;qCACS;+BACN;sEACC;qCAE0B;AAWzD,SAASC,YAAY,KAMpB;IANoB,IAAA,EACnBC,aAAa,CAACC,aAAaC,kBAAkB,EAC7CC,KAAK,EAIN,GANoB;IAOnB,IAAI,CAACA,OAAO;QACV,qBACE,sBAACC;;8BACC,qBAACC;8BACD,qBAACC;;;IAGP;IACA,qBACE,sBAACC,4BAAa;QAACC,gBAAgBC,oBAAkB;;YAC9CP;0BACD,qBAACD;gBAAYE,OAAOA;;;;AAG1B;AAEO,MAAML,mCAAmCY,oBAAa;IAM3D,OAAOC,yBAAyBR,KAAY,EAAE;QAC5CS,wCAAmB,CAACC,eAAe,GAAG;QAEtC,OAAO;YACLC,YAAYX;QACd;IACF;IAEAY,kBAAkBC,GAAU,EAAE;QAC5B,IACEC,QAAQC,GAAG,CAACC,QAAQ,KAAK,iBACzBH,IAAII,OAAO,KAAKC,6DAAwC,EACxD;YACA;QACF;QACAC,wBAAU,CAACC,gBAAgB;IAC7B;IAEAC,SAAS;QACP,MAAM,EAAEC,QAAQ,EAAEzB,WAAW,EAAE,GAAG,IAAI,CAAC0B,KAAK;QAC5C,MAAM,EAAEZ,UAAU,EAAE,GAAG,IAAI,CAACa,KAAK;QAEjC,MAAMC,yBACJ,qBAAC7B;YAAYC,aAAaA;YAAaG,OAAOW;;QAGhD,OAAOA,eAAe,OAAOc,WAAWH;IAC1C;;QAjCK,qBAILE,QAAQ;YAAEb,YAAY;QAAK;;AA8B7B","ignoreList":[0]}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _interceptconsoleerror = require("./errors/intercept-console-error");
const _useerrorhandler = require("./errors/use-error-handler");
const _forwardlogs = require("./forward-logs");
(0, _useerrorhandler.handleGlobalErrors)();
(0, _interceptconsoleerror.patchConsoleError)();
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.initializeDebugLogForwarding)('app');
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-dev-overlay-setup.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/next-devtools/userspace/app/app-dev-overlay-setup.ts"],"sourcesContent":["import { patchConsoleError } from './errors/intercept-console-error'\nimport { handleGlobalErrors } from './errors/use-error-handler'\nimport {\n initializeDebugLogForwarding,\n isTerminalLoggingEnabled,\n} from './forward-logs'\n\nhandleGlobalErrors()\npatchConsoleError()\n\nif (isTerminalLoggingEnabled) {\n initializeDebugLogForwarding('app')\n}\n"],"names":["handleGlobalErrors","patchConsoleError","isTerminalLoggingEnabled","initializeDebugLogForwarding"],"mappings":";;;;uCAAkC;iCACC;6BAI5B;AAEPA,IAAAA,mCAAkB;AAClBC,IAAAA,wCAAiB;AAEjB,IAAIC,qCAAwB,EAAE;IAC5BC,IAAAA,yCAA4B,EAAC;AAC/B","ignoreList":[0]}

View File

@@ -0,0 +1,4 @@
import React from 'react';
export declare function RootLevelDevOverlayElement({ children, }: {
children: React.ReactNode;
}): import("react/jsx-runtime").JSX.Element;

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "RootLevelDevOverlayElement", {
enumerable: true,
get: function() {
return RootLevelDevOverlayElement;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const _globalerror = /*#__PURE__*/ _interop_require_default._(require("../../../client/components/builtin/global-error"));
const _appdevoverlayerrorboundary = require("./app-dev-overlay-error-boundary");
function RootLevelDevOverlayElement(param) {
let { children } = param;
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_appdevoverlayerrorboundary.AppDevOverlayErrorBoundary, {
globalError: [
_globalerror.default,
null
],
children: children
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=client-entry.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/next-devtools/userspace/app/client-entry.tsx"],"sourcesContent":["import React from 'react'\nimport DefaultGlobalError from '../../../client/components/builtin/global-error'\nimport { AppDevOverlayErrorBoundary } from './app-dev-overlay-error-boundary'\n\n// If an error is thrown while rendering an RSC stream, this will catch it in\n// dev and show the error overlay.\nexport function RootLevelDevOverlayElement({\n children,\n}: {\n children: React.ReactNode\n}) {\n return (\n <AppDevOverlayErrorBoundary globalError={[DefaultGlobalError, null]}>\n {children}\n </AppDevOverlayErrorBoundary>\n )\n}\n"],"names":["RootLevelDevOverlayElement","children","AppDevOverlayErrorBoundary","globalError","DefaultGlobalError"],"mappings":";;;;+BAMgBA;;;eAAAA;;;;;gEANE;sEACa;4CACY;AAIpC,SAASA,2BAA2B,KAI1C;IAJ0C,IAAA,EACzCC,QAAQ,EAGT,GAJ0C;IAKzC,qBACE,qBAACC,sDAA0B;QAACC,aAAa;YAACC,oBAAkB;YAAE;SAAK;kBAChEH;;AAGP","ignoreList":[0]}

View File

@@ -0,0 +1,3 @@
export { originConsoleError } from './intercept-console-error';
export { handleClientError } from './use-error-handler';
export { decorateDevError } from './stitched-error';

View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
decorateDevError: null,
handleClientError: null,
originConsoleError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
decorateDevError: function() {
return _stitchederror.decorateDevError;
},
handleClientError: function() {
return _useerrorhandler.handleClientError;
},
originConsoleError: function() {
return _interceptconsoleerror.originConsoleError;
}
});
const _interceptconsoleerror = require("./intercept-console-error");
const _useerrorhandler = require("./use-error-handler");
const _stitchederror = require("./stitched-error");
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/next-devtools/userspace/app/errors/index.ts"],"sourcesContent":["export { originConsoleError } from './intercept-console-error'\nexport { handleClientError } from './use-error-handler'\nexport { decorateDevError } from './stitched-error'\n"],"names":["decorateDevError","handleClientError","originConsoleError"],"mappings":";;;;;;;;;;;;;;;;IAESA,gBAAgB;eAAhBA,+BAAgB;;IADhBC,iBAAiB;eAAjBA,kCAAiB;;IADjBC,kBAAkB;eAAlBA,yCAAkB;;;uCAAQ;iCACD;+BACD","ignoreList":[0]}

View File

@@ -0,0 +1,5 @@
export declare const originConsoleError: {
(...data: any[]): void;
(message?: any, ...optionalParams: any[]): void;
};
export declare function patchConsoleError(): void;

View File

@@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
originConsoleError: null,
patchConsoleError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
originConsoleError: function() {
return originConsoleError;
},
patchConsoleError: function() {
return patchConsoleError;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _iserror = /*#__PURE__*/ _interop_require_default._(require("../../../../lib/is-error"));
const _isnextroutererror = require("../../../../client/components/is-next-router-error");
const _useerrorhandler = require("./use-error-handler");
const _console = require("../../../../client/lib/console");
const _forwardlogs = require("../forward-logs");
const originConsoleError = globalThis.console.error;
function patchConsoleError() {
// Ensure it's only patched once
if (typeof window === 'undefined') {
return;
}
window.console.error = function error() {
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
args[_key] = arguments[_key];
}
let maybeError;
if (process.env.NODE_ENV !== 'production') {
const { error: replayedError } = (0, _console.parseConsoleArgs)(args);
if (replayedError) {
maybeError = replayedError;
} else if ((0, _iserror.default)(args[0])) {
maybeError = args[0];
} else {
// See https://github.com/facebook/react/blob/d50323eb845c5fde0d720cae888bf35dedd05506/packages/react-reconciler/src/ReactFiberErrorLogger.js#L78
maybeError = args[1];
}
} else {
maybeError = args[0];
}
if (!(0, _isnextroutererror.isNextRouterError)(maybeError)) {
if (process.env.NODE_ENV !== 'production') {
(0, _useerrorhandler.handleConsoleError)(// replayed errors have their own complex format string that should be used,
// but if we pass the error directly, `handleClientError` will ignore it
maybeError, args);
}
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.forwardErrorLog)(args);
}
originConsoleError.apply(window.console, args);
}
};
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=intercept-console-error.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/next-devtools/userspace/app/errors/intercept-console-error.ts"],"sourcesContent":["import isError from '../../../../lib/is-error'\nimport { isNextRouterError } from '../../../../client/components/is-next-router-error'\nimport { handleConsoleError } from './use-error-handler'\nimport { parseConsoleArgs } from '../../../../client/lib/console'\nimport { forwardErrorLog, isTerminalLoggingEnabled } from '../forward-logs'\n\nexport const originConsoleError = globalThis.console.error\n\n// Patch console.error to collect information about hydration errors\nexport function patchConsoleError() {\n // Ensure it's only patched once\n if (typeof window === 'undefined') {\n return\n }\n window.console.error = function error(...args: any[]) {\n let maybeError: unknown\n if (process.env.NODE_ENV !== 'production') {\n const { error: replayedError } = parseConsoleArgs(args)\n if (replayedError) {\n maybeError = replayedError\n } else if (isError(args[0])) {\n maybeError = args[0]\n } else {\n // See https://github.com/facebook/react/blob/d50323eb845c5fde0d720cae888bf35dedd05506/packages/react-reconciler/src/ReactFiberErrorLogger.js#L78\n maybeError = args[1]\n }\n } else {\n maybeError = args[0]\n }\n\n if (!isNextRouterError(maybeError)) {\n if (process.env.NODE_ENV !== 'production') {\n handleConsoleError(\n // replayed errors have their own complex format string that should be used,\n // but if we pass the error directly, `handleClientError` will ignore it\n maybeError,\n args\n )\n }\n if (isTerminalLoggingEnabled) {\n forwardErrorLog(args)\n }\n\n originConsoleError.apply(window.console, args)\n }\n }\n}\n"],"names":["originConsoleError","patchConsoleError","globalThis","console","error","window","args","maybeError","process","env","NODE_ENV","replayedError","parseConsoleArgs","isError","isNextRouterError","handleConsoleError","isTerminalLoggingEnabled","forwardErrorLog","apply"],"mappings":";;;;;;;;;;;;;;;IAMaA,kBAAkB;eAAlBA;;IAGGC,iBAAiB;eAAjBA;;;;kEATI;mCACc;iCACC;yBACF;6BACyB;AAEnD,MAAMD,qBAAqBE,WAAWC,OAAO,CAACC,KAAK;AAGnD,SAASH;IACd,gCAAgC;IAChC,IAAI,OAAOI,WAAW,aAAa;QACjC;IACF;IACAA,OAAOF,OAAO,CAACC,KAAK,GAAG,SAASA;QAAM,IAAA,IAAA,OAAA,UAAA,QAAA,AAAGE,OAAH,UAAA,OAAA,OAAA,GAAA,OAAA,MAAA;YAAGA,KAAH,QAAA,SAAA,CAAA,KAAc;;QAClD,IAAIC;QACJ,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,MAAM,EAAEN,OAAOO,aAAa,EAAE,GAAGC,IAAAA,yBAAgB,EAACN;YAClD,IAAIK,eAAe;gBACjBJ,aAAaI;YACf,OAAO,IAAIE,IAAAA,gBAAO,EAACP,IAAI,CAAC,EAAE,GAAG;gBAC3BC,aAAaD,IAAI,CAAC,EAAE;YACtB,OAAO;gBACL,iJAAiJ;gBACjJC,aAAaD,IAAI,CAAC,EAAE;YACtB;QACF,OAAO;YACLC,aAAaD,IAAI,CAAC,EAAE;QACtB;QAEA,IAAI,CAACQ,IAAAA,oCAAiB,EAACP,aAAa;YAClC,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzCK,IAAAA,mCAAkB,EAChB,4EAA4E;gBAC5E,wEAAwE;gBACxER,YACAD;YAEJ;YACA,IAAIU,qCAAwB,EAAE;gBAC5BC,IAAAA,4BAAe,EAACX;YAClB;YAEAN,mBAAmBkB,KAAK,CAACb,OAAOF,OAAO,EAAEG;QAC3C;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,8 @@
/**
* Needs to be in the same error boundary as the shell.
* If it commits, we know we recovered from an SSR error.
* If it doesn't commit, we errored again and React will take care of error reporting.
*/
export declare function ReplaySsrOnlyErrors({ onBlockingError, }: {
onBlockingError: () => void;
}): null;

View File

@@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "ReplaySsrOnlyErrors", {
enumerable: true,
get: function() {
return ReplaySsrOnlyErrors;
}
});
const _react = require("react");
const _useerrorhandler = require("./use-error-handler");
const _isnextroutererror = require("../../../../client/components/is-next-router-error");
const _constants = require("../../../../shared/lib/errors/constants");
function readSsrError() {
if (typeof document === 'undefined') {
return null;
}
const ssrErrorTemplateTag = document.querySelector('template[data-next-error-message]');
if (ssrErrorTemplateTag) {
const message = ssrErrorTemplateTag.getAttribute('data-next-error-message');
const stack = ssrErrorTemplateTag.getAttribute('data-next-error-stack');
const digest = ssrErrorTemplateTag.getAttribute('data-next-error-digest');
const error = Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
if (digest) {
;
error.digest = digest;
}
// Skip Next.js SSR'd internal errors that which will be handled by the error boundaries.
if ((0, _isnextroutererror.isNextRouterError)(error)) {
return null;
}
error.stack = stack || '';
return error;
}
return null;
}
function ReplaySsrOnlyErrors(param) {
let { onBlockingError } = param;
if (process.env.NODE_ENV !== 'production') {
// Need to read during render. The attributes will be gone after commit.
const ssrError = readSsrError();
// eslint-disable-next-line react-hooks/rules-of-hooks
(0, _react.useEffect)(()=>{
if (ssrError !== null) {
// TODO(veil): Include original Owner Stack (NDX-905)
// TODO(veil): Mark as recoverable error
// TODO(veil): console.error
(0, _useerrorhandler.handleClientError)(ssrError);
// If it's missing root tags, we can't recover, make it blocking.
if (ssrError.digest === _constants.MISSING_ROOT_TAGS_ERROR) {
onBlockingError();
}
}
}, [
ssrError,
onBlockingError
]);
}
return null;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=replay-ssr-only-errors.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/next-devtools/userspace/app/errors/replay-ssr-only-errors.tsx"],"sourcesContent":["import { useEffect } from 'react'\nimport { handleClientError } from './use-error-handler'\nimport { isNextRouterError } from '../../../../client/components/is-next-router-error'\nimport { MISSING_ROOT_TAGS_ERROR } from '../../../../shared/lib/errors/constants'\n\nfunction readSsrError(): (Error & { digest?: string }) | null {\n if (typeof document === 'undefined') {\n return null\n }\n\n const ssrErrorTemplateTag = document.querySelector(\n 'template[data-next-error-message]'\n )\n if (ssrErrorTemplateTag) {\n const message: string = ssrErrorTemplateTag.getAttribute(\n 'data-next-error-message'\n )!\n const stack = ssrErrorTemplateTag.getAttribute('data-next-error-stack')\n const digest = ssrErrorTemplateTag.getAttribute('data-next-error-digest')\n const error = new Error(message)\n if (digest) {\n ;(error as any).digest = digest\n }\n // Skip Next.js SSR'd internal errors that which will be handled by the error boundaries.\n if (isNextRouterError(error)) {\n return null\n }\n error.stack = stack || ''\n return error\n }\n\n return null\n}\n\n/**\n * Needs to be in the same error boundary as the shell.\n * If it commits, we know we recovered from an SSR error.\n * If it doesn't commit, we errored again and React will take care of error reporting.\n */\nexport function ReplaySsrOnlyErrors({\n onBlockingError,\n}: {\n onBlockingError: () => void\n}) {\n if (process.env.NODE_ENV !== 'production') {\n // Need to read during render. The attributes will be gone after commit.\n const ssrError = readSsrError()\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useEffect(() => {\n if (ssrError !== null) {\n // TODO(veil): Include original Owner Stack (NDX-905)\n // TODO(veil): Mark as recoverable error\n // TODO(veil): console.error\n handleClientError(ssrError)\n\n // If it's missing root tags, we can't recover, make it blocking.\n if (ssrError.digest === MISSING_ROOT_TAGS_ERROR) {\n onBlockingError()\n }\n }\n }, [ssrError, onBlockingError])\n }\n\n return null\n}\n"],"names":["ReplaySsrOnlyErrors","readSsrError","document","ssrErrorTemplateTag","querySelector","message","getAttribute","stack","digest","error","Error","isNextRouterError","onBlockingError","process","env","NODE_ENV","ssrError","useEffect","handleClientError","MISSING_ROOT_TAGS_ERROR"],"mappings":";;;;+BAuCgBA;;;eAAAA;;;uBAvCU;iCACQ;mCACA;2BACM;AAExC,SAASC;IACP,IAAI,OAAOC,aAAa,aAAa;QACnC,OAAO;IACT;IAEA,MAAMC,sBAAsBD,SAASE,aAAa,CAChD;IAEF,IAAID,qBAAqB;QACvB,MAAME,UAAkBF,oBAAoBG,YAAY,CACtD;QAEF,MAAMC,QAAQJ,oBAAoBG,YAAY,CAAC;QAC/C,MAAME,SAASL,oBAAoBG,YAAY,CAAC;QAChD,MAAMG,QAAQ,qBAAkB,CAAlB,IAAIC,MAAML,UAAV,qBAAA;mBAAA;wBAAA;0BAAA;QAAiB;QAC/B,IAAIG,QAAQ;;YACRC,MAAcD,MAAM,GAAGA;QAC3B;QACA,yFAAyF;QACzF,IAAIG,IAAAA,oCAAiB,EAACF,QAAQ;YAC5B,OAAO;QACT;QACAA,MAAMF,KAAK,GAAGA,SAAS;QACvB,OAAOE;IACT;IAEA,OAAO;AACT;AAOO,SAAST,oBAAoB,KAInC;IAJmC,IAAA,EAClCY,eAAe,EAGhB,GAJmC;IAKlC,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;QACzC,wEAAwE;QACxE,MAAMC,WAAWf;QACjB,sDAAsD;QACtDgB,IAAAA,gBAAS,EAAC;YACR,IAAID,aAAa,MAAM;gBACrB,qDAAqD;gBACrD,wCAAwC;gBACxC,4BAA4B;gBAC5BE,IAAAA,kCAAiB,EAACF;gBAElB,iEAAiE;gBACjE,IAAIA,SAASR,MAAM,KAAKW,kCAAuB,EAAE;oBAC/CP;gBACF;YACF;QACF,GAAG;YAACI;YAAUJ;SAAgB;IAChC;IAEA,OAAO;AACT","ignoreList":[0]}

View File

@@ -0,0 +1,5 @@
export declare function getOwnerStack(error: Error): string | null | undefined;
export declare function setOwnerStack(error: Error, stack: string | null): void;
export declare function coerceError(value: unknown): Error;
export declare function setOwnerStackIfAvailable(error: Error): void;
export declare function decorateDevError(thrownValue: unknown): Error;

View File

@@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
coerceError: null,
decorateDevError: null,
getOwnerStack: null,
setOwnerStack: null,
setOwnerStackIfAvailable: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
coerceError: function() {
return coerceError;
},
decorateDevError: function() {
return decorateDevError;
},
getOwnerStack: function() {
return getOwnerStack;
},
setOwnerStack: function() {
return setOwnerStack;
},
setOwnerStackIfAvailable: function() {
return setOwnerStackIfAvailable;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const _iserror = /*#__PURE__*/ _interop_require_default._(require("../../../../lib/is-error"));
const ownerStacks = new WeakMap();
function getOwnerStack(error) {
return ownerStacks.get(error);
}
function setOwnerStack(error, stack) {
ownerStacks.set(error, stack);
}
function coerceError(value) {
return (0, _iserror.default)(value) ? value : Object.defineProperty(new Error('' + value), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
function setOwnerStackIfAvailable(error) {
// React 18 and prod does not have `captureOwnerStack`
if ('captureOwnerStack' in _react.default) {
setOwnerStack(error, _react.default.captureOwnerStack());
}
}
function decorateDevError(thrownValue) {
const error = coerceError(thrownValue);
setOwnerStackIfAvailable(error);
return error;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=stitched-error.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/next-devtools/userspace/app/errors/stitched-error.ts"],"sourcesContent":["import React from 'react'\nimport isError from '../../../../lib/is-error'\n\nconst ownerStacks = new WeakMap<Error, string | null>()\n\nexport function getOwnerStack(error: Error): string | null | undefined {\n return ownerStacks.get(error)\n}\nexport function setOwnerStack(error: Error, stack: string | null) {\n ownerStacks.set(error, stack)\n}\n\nexport function coerceError(value: unknown): Error {\n return isError(value) ? value : new Error('' + value)\n}\n\nexport function setOwnerStackIfAvailable(error: Error): void {\n // React 18 and prod does not have `captureOwnerStack`\n if ('captureOwnerStack' in React) {\n setOwnerStack(error, React.captureOwnerStack())\n }\n}\n\nexport function decorateDevError(thrownValue: unknown) {\n const error = coerceError(thrownValue)\n setOwnerStackIfAvailable(error)\n return error\n}\n"],"names":["coerceError","decorateDevError","getOwnerStack","setOwnerStack","setOwnerStackIfAvailable","ownerStacks","WeakMap","error","get","stack","set","value","isError","Error","React","captureOwnerStack","thrownValue"],"mappings":";;;;;;;;;;;;;;;;;;IAYgBA,WAAW;eAAXA;;IAWAC,gBAAgB;eAAhBA;;IAlBAC,aAAa;eAAbA;;IAGAC,aAAa;eAAbA;;IAQAC,wBAAwB;eAAxBA;;;;gEAhBE;kEACE;AAEpB,MAAMC,cAAc,IAAIC;AAEjB,SAASJ,cAAcK,KAAY;IACxC,OAAOF,YAAYG,GAAG,CAACD;AACzB;AACO,SAASJ,cAAcI,KAAY,EAAEE,KAAoB;IAC9DJ,YAAYK,GAAG,CAACH,OAAOE;AACzB;AAEO,SAAST,YAAYW,KAAc;IACxC,OAAOC,IAAAA,gBAAO,EAACD,SAASA,QAAQ,qBAAqB,CAArB,IAAIE,MAAM,KAAKF,QAAf,qBAAA;eAAA;oBAAA;sBAAA;IAAoB;AACtD;AAEO,SAASP,yBAAyBG,KAAY;IACnD,sDAAsD;IACtD,IAAI,uBAAuBO,cAAK,EAAE;QAChCX,cAAcI,OAAOO,cAAK,CAACC,iBAAiB;IAC9C;AACF;AAEO,SAASd,iBAAiBe,WAAoB;IACnD,MAAMT,QAAQP,YAAYgB;IAC1BZ,yBAAyBG;IACzB,OAAOA;AACT","ignoreList":[0]}

View File

@@ -0,0 +1,6 @@
type ErrorHandler = (error: Error) => void;
export declare function handleConsoleError(originError: unknown, consoleErrorArgs: any[]): void;
export declare function handleClientError(error: Error): void;
export declare function useErrorHandler(handleOnUnhandledError: ErrorHandler, handleOnUnhandledRejection: ErrorHandler): void;
export declare function handleGlobalErrors(): void;
export {};

View File

@@ -0,0 +1,143 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
handleClientError: null,
handleConsoleError: null,
handleGlobalErrors: null,
useErrorHandler: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
handleClientError: function() {
return handleClientError;
},
handleConsoleError: function() {
return handleConsoleError;
},
handleGlobalErrors: function() {
return handleGlobalErrors;
},
useErrorHandler: function() {
return useErrorHandler;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _react = require("react");
const _isnextroutererror = require("../../../../client/components/is-next-router-error");
const _console = require("../../../../client/lib/console");
const _iserror = /*#__PURE__*/ _interop_require_default._(require("../../../../lib/is-error"));
const _consoleerror = require("../../../shared/console-error");
const _stitchederror = require("./stitched-error");
const _forwardlogs = require("../forward-logs");
const queueMicroTask = globalThis.queueMicrotask || ((cb)=>Promise.resolve().then(cb));
const errorQueue = [];
const errorHandlers = [];
const rejectionQueue = [];
const rejectionHandlers = [];
function handleConsoleError(originError, consoleErrorArgs) {
let error;
const { environmentName } = (0, _console.parseConsoleArgs)(consoleErrorArgs);
if ((0, _iserror.default)(originError)) {
error = (0, _consoleerror.createConsoleError)(originError, environmentName);
} else {
error = (0, _consoleerror.createConsoleError)((0, _console.formatConsoleArgs)(consoleErrorArgs), environmentName);
}
(0, _stitchederror.setOwnerStackIfAvailable)(error);
errorQueue.push(error);
for (const handler of errorHandlers){
// Delayed the error being passed to React Dev Overlay,
// avoid the state being synchronously updated in the component.
queueMicroTask(()=>{
handler(error);
});
}
}
function handleClientError(error) {
errorQueue.push(error);
for (const handler of errorHandlers){
// Delayed the error being passed to React Dev Overlay,
// avoid the state being synchronously updated in the component.
queueMicroTask(()=>{
handler(error);
});
}
}
function useErrorHandler(handleOnUnhandledError, handleOnUnhandledRejection) {
(0, _react.useEffect)(()=>{
// Handle queued errors.
errorQueue.forEach(handleOnUnhandledError);
rejectionQueue.forEach(handleOnUnhandledRejection);
// Listen to new errors.
errorHandlers.push(handleOnUnhandledError);
rejectionHandlers.push(handleOnUnhandledRejection);
return ()=>{
// Remove listeners.
errorHandlers.splice(errorHandlers.indexOf(handleOnUnhandledError), 1);
rejectionHandlers.splice(rejectionHandlers.indexOf(handleOnUnhandledRejection), 1);
// Reset error queues.
errorQueue.splice(0, errorQueue.length);
rejectionQueue.splice(0, rejectionQueue.length);
};
}, [
handleOnUnhandledError,
handleOnUnhandledRejection
]);
}
function onUnhandledError(event) {
const thrownValue = event.error;
if ((0, _isnextroutererror.isNextRouterError)(thrownValue)) {
event.preventDefault();
return false;
}
// When there's an error property present, we log the error to error overlay.
// Otherwise we don't do anything as it's not logging in the console either.
if (thrownValue) {
const error = (0, _stitchederror.coerceError)(thrownValue);
(0, _stitchederror.setOwnerStackIfAvailable)(error);
handleClientError(error);
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.forwardUnhandledError)(error);
}
}
}
function onUnhandledRejection(ev) {
const reason = ev == null ? void 0 : ev.reason;
if ((0, _isnextroutererror.isNextRouterError)(reason)) {
ev.preventDefault();
return;
}
const error = (0, _stitchederror.coerceError)(reason);
(0, _stitchederror.setOwnerStackIfAvailable)(error);
rejectionQueue.push(error);
for (const handler of rejectionHandlers){
handler(error);
}
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.logUnhandledRejection)(reason);
}
}
function handleGlobalErrors() {
if (typeof window !== 'undefined') {
try {
// Increase the number of stack frames on the client
Error.stackTraceLimit = 50;
} catch (e) {}
window.addEventListener('error', onUnhandledError);
window.addEventListener('unhandledrejection', onUnhandledRejection);
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=use-error-handler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
import type { useWebsocket } from '../../../../client/dev/hot-reloader/app/use-websocket';
export declare const useForwardConsoleLog: (socketRef: ReturnType<typeof useWebsocket>) => void;

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useForwardConsoleLog", {
enumerable: true,
get: function() {
return useForwardConsoleLog;
}
});
const _react = require("react");
const _forwardlogs = require("../forward-logs");
const useForwardConsoleLog = (socketRef)=>{
(0, _react.useEffect)(()=>{
if (!_forwardlogs.isTerminalLoggingEnabled) {
return;
}
const socket = socketRef.current;
if (!socket) {
return;
}
const onOpen = ()=>{
_forwardlogs.logQueue.onSocketReady(socket);
};
socket.addEventListener('open', onOpen);
return ()=>{
socket.removeEventListener('open', onOpen);
};
}, [
socketRef
]);
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=use-forward-console-log.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/next-devtools/userspace/app/errors/use-forward-console-log.ts"],"sourcesContent":["import { useEffect } from 'react'\nimport { isTerminalLoggingEnabled, logQueue } from '../forward-logs'\nimport type { useWebsocket } from '../../../../client/dev/hot-reloader/app/use-websocket'\n\nexport const useForwardConsoleLog = (\n socketRef: ReturnType<typeof useWebsocket>\n) => {\n useEffect(() => {\n if (!isTerminalLoggingEnabled) {\n return\n }\n const socket = socketRef.current\n if (!socket) {\n return\n }\n\n const onOpen = () => {\n logQueue.onSocketReady(socket)\n }\n socket.addEventListener('open', onOpen)\n\n return () => {\n socket.removeEventListener('open', onOpen)\n }\n }, [socketRef])\n}\n"],"names":["useForwardConsoleLog","socketRef","useEffect","isTerminalLoggingEnabled","socket","current","onOpen","logQueue","onSocketReady","addEventListener","removeEventListener"],"mappings":";;;;+BAIaA;;;eAAAA;;;uBAJa;6BACyB;AAG5C,MAAMA,uBAAuB,CAClCC;IAEAC,IAAAA,gBAAS,EAAC;QACR,IAAI,CAACC,qCAAwB,EAAE;YAC7B;QACF;QACA,MAAMC,SAASH,UAAUI,OAAO;QAChC,IAAI,CAACD,QAAQ;YACX;QACF;QAEA,MAAME,SAAS;YACbC,qBAAQ,CAACC,aAAa,CAACJ;QACzB;QACAA,OAAOK,gBAAgB,CAAC,QAAQH;QAEhC,OAAO;YACLF,OAAOM,mBAAmB,CAAC,QAAQJ;QACrC;IACF,GAAG;QAACL;KAAU;AAChB","ignoreList":[0]}

View File

@@ -0,0 +1,26 @@
import { type ClientLogEntry } from '../../shared/forward-logs-shared';
export declare const PROMISE_MARKER = "Promise {}";
export declare const UNAVAILABLE_MARKER = "[Unable to view]";
export declare const isTerminalLoggingEnabled: boolean;
/**
* allows us to:
* - revive the undefined log in the server as it would look in the browser
* - not read/attempt to serialize promises (next will console error if you do that, and will cause this program to infinitely recurse)
* - if we read a proxy that throws (no way to detect if something is a proxy), explain to the user we can't read this data
*/
export declare function preLogSerializationClone<T>(value: T, seen?: WeakMap<WeakKey, any>): any;
export declare const logStringify: (data: unknown) => string;
export declare const logQueue: {
entries: Array<ClientLogEntry>;
onSocketReady: (socket: WebSocket) => void;
flushScheduled: boolean;
socket: WebSocket | null;
cancelFlush: (() => void) | null;
sourceType?: 'server' | 'edge-server';
router: 'app' | 'pages' | null;
scheduleLogSend: (entry: ClientLogEntry) => void;
};
export declare const forwardErrorLog: (args: any[]) => void;
export declare function logUnhandledRejection(reason: unknown): void;
export declare function forwardUnhandledError(error: Error): void;
export declare const initializeDebugLogForwarding: (router: "app" | "pages") => void;

View File

@@ -0,0 +1,417 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
PROMISE_MARKER: null,
UNAVAILABLE_MARKER: null,
forwardErrorLog: null,
forwardUnhandledError: null,
initializeDebugLogForwarding: null,
isTerminalLoggingEnabled: null,
logQueue: null,
logStringify: null,
logUnhandledRejection: null,
preLogSerializationClone: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
PROMISE_MARKER: function() {
return PROMISE_MARKER;
},
UNAVAILABLE_MARKER: function() {
return UNAVAILABLE_MARKER;
},
forwardErrorLog: function() {
return forwardErrorLog;
},
forwardUnhandledError: function() {
return forwardUnhandledError;
},
initializeDebugLogForwarding: function() {
return initializeDebugLogForwarding;
},
isTerminalLoggingEnabled: function() {
return isTerminalLoggingEnabled;
},
logQueue: function() {
return logQueue;
},
logStringify: function() {
return logStringify;
},
logUnhandledRejection: function() {
return logUnhandledRejection;
},
preLogSerializationClone: function() {
return preLogSerializationClone;
}
});
const _safestablestringify = require("next/dist/compiled/safe-stable-stringify");
const _stitchederror = require("./errors/stitched-error");
const _errorsource = require("../../../shared/lib/error-source");
const _terminalloggingconfig = require("./terminal-logging-config");
const _forwardlogsshared = require("../../shared/forward-logs-shared");
const terminalLoggingConfig = (0, _terminalloggingconfig.getTerminalLoggingConfig)();
const PROMISE_MARKER = 'Promise {}';
const UNAVAILABLE_MARKER = '[Unable to view]';
const maximumDepth = typeof terminalLoggingConfig === 'object' && terminalLoggingConfig.depthLimit ? terminalLoggingConfig.depthLimit : 5;
const maximumBreadth = typeof terminalLoggingConfig === 'object' && terminalLoggingConfig.edgeLimit ? terminalLoggingConfig.edgeLimit : 100;
const stringify = (0, _safestablestringify.configure)({
maximumDepth,
maximumBreadth
});
const isTerminalLoggingEnabled = (0, _terminalloggingconfig.getIsTerminalLoggingEnabled)();
const methods = [
'log',
'info',
'warn',
'debug',
'table',
'assert',
'dir',
'dirxml',
'group',
'groupCollapsed',
'groupEnd',
'trace'
];
function preLogSerializationClone(value, seen) {
if (seen === void 0) seen = new WeakMap();
if (value === undefined) return _forwardlogsshared.UNDEFINED_MARKER;
if (value === null || typeof value !== 'object') return value;
if (seen.has(value)) return seen.get(value);
try {
Object.keys(value);
} catch (e) {
return UNAVAILABLE_MARKER;
}
try {
if (typeof value.then === 'function') return PROMISE_MARKER;
} catch (e) {
return UNAVAILABLE_MARKER;
}
if (Array.isArray(value)) {
const out = [];
seen.set(value, out);
for (const item of value){
try {
out.push(preLogSerializationClone(item, seen));
} catch (e) {
out.push(UNAVAILABLE_MARKER);
}
}
return out;
}
const proto = Object.getPrototypeOf(value);
if (proto === Object.prototype || proto === null) {
const out = {};
seen.set(value, out);
for (const key of Object.keys(value)){
try {
out[key] = preLogSerializationClone(value[key], seen);
} catch (e) {
out[key] = UNAVAILABLE_MARKER;
}
}
return out;
}
return Object.prototype.toString.call(value);
}
const logStringify = (data)=>{
try {
const result = stringify(data);
return result != null ? result : '"' + UNAVAILABLE_MARKER + '"';
} catch (e) {
return '"' + UNAVAILABLE_MARKER + '"';
}
};
const afterThisFrame = (cb)=>{
let timeout;
const rafId = requestAnimationFrame(()=>{
timeout = setTimeout(()=>{
cb();
});
});
return ()=>{
cancelAnimationFrame(rafId);
clearTimeout(timeout);
};
};
let isPatched = false;
const serializeEntries = (entries)=>entries.map((clientEntry)=>{
switch(clientEntry.kind){
case 'any-logged-error':
case 'console':
{
return {
...clientEntry,
args: clientEntry.args.map(stringifyUserArg)
};
}
case 'formatted-error':
{
return clientEntry;
}
default:
{
return null;
}
}
});
const logQueue = {
entries: [],
flushScheduled: false,
cancelFlush: null,
socket: null,
sourceType: undefined,
router: null,
scheduleLogSend: (entry)=>{
logQueue.entries.push(entry);
if (logQueue.flushScheduled) {
return;
}
// safe to deref and use in setTimeout closure since we cancel on new socket
const socket = logQueue.socket;
if (!socket) {
return;
}
// we probably dont need this
logQueue.flushScheduled = true;
// non blocking log flush, runs at most once per frame
logQueue.cancelFlush = afterThisFrame(()=>{
logQueue.flushScheduled = false;
// just incase
try {
const payload = JSON.stringify({
event: 'browser-logs',
entries: serializeEntries(logQueue.entries),
router: logQueue.router,
// needed for source mapping, we just assign the sourceType from the last error for the whole batch
sourceType: logQueue.sourceType
});
socket.send(payload);
logQueue.entries = [];
logQueue.sourceType = undefined;
} catch (e) {
// error (make sure u don't infinite loop)
/* noop */ }
});
},
onSocketReady: (socket)=>{
if (socket.readyState !== WebSocket.OPEN) {
// invariant
return;
}
// incase an existing timeout was going to run with a stale socket
logQueue.cancelFlush == null ? void 0 : logQueue.cancelFlush.call(logQueue);
logQueue.socket = socket;
try {
const payload = JSON.stringify({
event: 'browser-logs',
entries: serializeEntries(logQueue.entries),
router: logQueue.router,
sourceType: logQueue.sourceType
});
socket.send(payload);
logQueue.entries = [];
logQueue.sourceType = undefined;
} catch (e) {
/** noop just incase */ }
}
};
const stringifyUserArg = (arg)=>{
if (arg.kind !== 'arg') {
return arg;
}
return {
...arg,
data: logStringify(arg.data)
};
};
const createErrorArg = (error)=>{
const stack = stackWithOwners(error);
return {
kind: 'formatted-error-arg',
prefix: error.message ? error.name + ": " + error.message : "" + error.name,
stack
};
};
const createLogEntry = (level, args)=>{
// do not abstract this, it implicitly relies on which functions call it. forcing the inlined implementation makes you think about callers
// error capture stack trace maybe
const stack = stackWithOwners(new Error());
const stackLines = stack == null ? void 0 : stack.split('\n');
const cleanStack = stackLines == null ? void 0 : stackLines.slice(3).join('\n') // this is probably ignored anyways
;
const entry = {
kind: 'console',
consoleMethodStack: cleanStack != null ? cleanStack : null,
method: level,
args: args.map((arg)=>{
if (arg instanceof Error) {
return createErrorArg(arg);
}
return {
kind: 'arg',
data: preLogSerializationClone(arg)
};
})
};
logQueue.scheduleLogSend(entry);
};
const forwardErrorLog = (args)=>{
const errorObjects = args.filter((arg)=>arg instanceof Error);
const first = errorObjects.at(0);
if (first) {
const source = (0, _errorsource.getErrorSource)(first);
if (source) {
logQueue.sourceType = source;
}
}
/**
* browser shows stack regardless of type of data passed to console.error, so we should do the same
*
* do not abstract this, it implicitly relies on which functions call it. forcing the inlined implementation makes you think about callers
*/ const stack = stackWithOwners(new Error());
const stackLines = stack == null ? void 0 : stack.split('\n');
const cleanStack = stackLines == null ? void 0 : stackLines.slice(3).join('\n');
const entry = {
kind: 'any-logged-error',
method: 'error',
consoleErrorStack: cleanStack != null ? cleanStack : '',
args: args.map((arg)=>{
if (arg instanceof Error) {
return createErrorArg(arg);
}
return {
kind: 'arg',
data: preLogSerializationClone(arg)
};
})
};
logQueue.scheduleLogSend(entry);
};
const createUncaughtErrorEntry = (errorName, errorMessage, fullStack)=>{
const entry = {
kind: 'formatted-error',
prefix: "Uncaught " + errorName + ": " + errorMessage,
stack: fullStack,
method: 'error'
};
logQueue.scheduleLogSend(entry);
};
const stackWithOwners = (error)=>{
let ownerStack = '';
(0, _stitchederror.setOwnerStackIfAvailable)(error);
ownerStack = (0, _stitchederror.getOwnerStack)(error) || '';
const stack = (error.stack || '') + ownerStack;
return stack;
};
function logUnhandledRejection(reason) {
if (reason instanceof Error) {
createUnhandledRejectionErrorEntry(reason, stackWithOwners(reason));
return;
}
createUnhandledRejectionNonErrorEntry(reason);
}
const createUnhandledRejectionErrorEntry = (error, fullStack)=>{
const source = (0, _errorsource.getErrorSource)(error);
if (source) {
logQueue.sourceType = source;
}
const entry = {
kind: 'formatted-error',
prefix: " unhandledRejection: " + error.name + ": " + error.message,
stack: fullStack,
method: 'error'
};
logQueue.scheduleLogSend(entry);
};
const createUnhandledRejectionNonErrorEntry = (reason)=>{
const entry = {
kind: 'any-logged-error',
// we can't access the stack since the event is dispatched async and creating an inline error would be meaningless
consoleErrorStack: '',
method: 'error',
args: [
{
kind: 'arg',
data: " unhandledRejection:",
isRejectionMessage: true
},
{
kind: 'arg',
data: preLogSerializationClone(reason)
}
]
};
logQueue.scheduleLogSend(entry);
};
const isHMR = (args)=>{
const firstArg = args[0];
if (typeof firstArg !== 'string') {
return false;
}
if (firstArg.startsWith('[Fast Refresh]')) {
return true;
}
if (firstArg.startsWith('[HMR]')) {
return true;
}
return false;
};
const isIgnoredLog = (args)=>{
if (args.length < 3) {
return false;
}
const [format, styles, label] = args;
if (typeof format !== 'string' || typeof styles !== 'string' || typeof label !== 'string') {
return false;
}
// kinda hacky, we should define a common format for these strings so we can safely ignore
return format.startsWith('%c%s%c') && styles.includes('background:');
};
function forwardUnhandledError(error) {
createUncaughtErrorEntry(error.name, error.message, stackWithOwners(error));
}
const initializeDebugLogForwarding = (router)=>{
// probably don't need this
if (isPatched) {
return;
}
// TODO(rob): why does this break rendering on server, important to know incase the same bug appears in browser
if (typeof window === 'undefined') {
return;
}
// better to be safe than sorry
try {
methods.forEach((method)=>(0, _forwardlogsshared.patchConsoleMethod)(method, function(_) {
for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
args[_key - 1] = arguments[_key];
}
if (isHMR(args)) {
return;
}
if (isIgnoredLog(args)) {
return;
}
createLogEntry(method, args);
}));
} catch (e) {}
logQueue.router = router;
isPatched = true;
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=forward-logs.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
import type { ReactNode } from 'react';
export type SegmentBoundaryType = 'not-found' | 'error' | 'loading' | 'global-error';
export declare const SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE = "NEXT_DEVTOOLS_SIMULATED_ERROR";
export type SegmentNodeState = {
type: string;
pagePath: string;
boundaryType: string | null;
setBoundaryType: (type: SegmentBoundaryType | null) => void;
};
export declare function SegmentViewStateNode({ page }: {
page: string;
}): null;
export declare function SegmentBoundaryTriggerNode(): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
export declare function SegmentViewNode({ type, pagePath, children, }: {
type: string;
pagePath: string;
children?: ReactNode;
}): React.ReactNode;
export declare function SegmentStateProvider({ children }: {
children: ReactNode;
}): import("react/jsx-runtime").JSX.Element;
export declare function useSegmentState(): {
boundaryType: SegmentBoundaryType | null;
setBoundaryType: (type: SegmentBoundaryType | null) => void;
};

View File

@@ -0,0 +1,160 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE: null,
SegmentBoundaryTriggerNode: null,
SegmentStateProvider: null,
SegmentViewNode: null,
SegmentViewStateNode: null,
useSegmentState: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE: function() {
return SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE;
},
SegmentBoundaryTriggerNode: function() {
return SegmentBoundaryTriggerNode;
},
SegmentStateProvider: function() {
return SegmentStateProvider;
},
SegmentViewNode: function() {
return SegmentViewNode;
},
SegmentViewStateNode: function() {
return SegmentViewStateNode;
},
useSegmentState: function() {
return useSegmentState;
}
});
const _jsxruntime = require("react/jsx-runtime");
const _react = require("react");
const _nextdevtools = require("next/dist/compiled/next-devtools");
const _notfound = require("../../../client/components/not-found");
const SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE = 'NEXT_DEVTOOLS_SIMULATED_ERROR';
function SegmentTrieNode(param) {
let { type, pagePath } = param;
const { boundaryType, setBoundaryType } = useSegmentState();
const nodeState = (0, _react.useMemo)(()=>{
return {
type,
pagePath,
boundaryType,
setBoundaryType
};
}, [
type,
pagePath,
boundaryType,
setBoundaryType
]);
// Use `useLayoutEffect` to ensure the state is updated during suspense.
// `useEffect` won't work as the state is preserved during suspense.
(0, _react.useLayoutEffect)(()=>{
_nextdevtools.dispatcher.segmentExplorerNodeAdd(nodeState);
return ()=>{
_nextdevtools.dispatcher.segmentExplorerNodeRemove(nodeState);
};
}, [
nodeState
]);
return null;
}
function NotFoundSegmentNode() {
(0, _notfound.notFound)();
}
function ErrorSegmentNode() {
throw Object.defineProperty(new Error(SEGMENT_EXPLORER_SIMULATED_ERROR_MESSAGE), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
const forever = new Promise(()=>{});
function LoadingSegmentNode() {
(0, _react.use)(forever);
return null;
}
function SegmentViewStateNode(param) {
let { page } = param;
(0, _react.useLayoutEffect)(()=>{
_nextdevtools.dispatcher.segmentExplorerUpdateRouteState(page);
return ()=>{
_nextdevtools.dispatcher.segmentExplorerUpdateRouteState('');
};
}, [
page
]);
return null;
}
function SegmentBoundaryTriggerNode() {
const { boundaryType } = useSegmentState();
let segmentNode = null;
if (boundaryType === 'loading') {
segmentNode = /*#__PURE__*/ (0, _jsxruntime.jsx)(LoadingSegmentNode, {});
} else if (boundaryType === 'not-found') {
segmentNode = /*#__PURE__*/ (0, _jsxruntime.jsx)(NotFoundSegmentNode, {});
} else if (boundaryType === 'error') {
segmentNode = /*#__PURE__*/ (0, _jsxruntime.jsx)(ErrorSegmentNode, {});
}
return segmentNode;
}
function SegmentViewNode(param) {
let { type, pagePath, children } = param;
const segmentNode = /*#__PURE__*/ (0, _jsxruntime.jsx)(SegmentTrieNode, {
type: type,
pagePath: pagePath
}, type);
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
children: [
segmentNode,
children
]
});
}
const SegmentStateContext = /*#__PURE__*/ (0, _react.createContext)({
boundaryType: null,
setBoundaryType: ()=>{}
});
function SegmentStateProvider(param) {
let { children } = param;
const [boundaryType, setBoundaryType] = (0, _react.useState)(null);
const [errorBoundaryKey, setErrorBoundaryKey] = (0, _react.useState)(0);
const reloadBoundary = (0, _react.useCallback)(()=>setErrorBoundaryKey((prev)=>prev + 1), []);
const setBoundaryTypeAndReload = (0, _react.useCallback)((type)=>{
if (type === null) {
reloadBoundary();
}
setBoundaryType(type);
}, [
reloadBoundary
]);
return /*#__PURE__*/ (0, _jsxruntime.jsx)(SegmentStateContext.Provider, {
value: {
boundaryType,
setBoundaryType: setBoundaryTypeAndReload
},
children: children
}, errorBoundaryKey);
}
function useSegmentState() {
return (0, _react.useContext)(SegmentStateContext);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=segment-explorer-node.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
export declare function getTerminalLoggingConfig(): false | boolean | {
depthLimit?: number;
edgeLimit?: number;
showSourceLocation?: boolean;
};
export declare function getIsTerminalLoggingEnabled(): boolean;

View File

@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getIsTerminalLoggingEnabled: null,
getTerminalLoggingConfig: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getIsTerminalLoggingEnabled: function() {
return getIsTerminalLoggingEnabled;
},
getTerminalLoggingConfig: function() {
return getTerminalLoggingConfig;
}
});
function getTerminalLoggingConfig() {
try {
return JSON.parse(process.env.__NEXT_BROWSER_DEBUG_INFO_IN_TERMINAL || 'false');
} catch (e) {
return false;
}
}
function getIsTerminalLoggingEnabled() {
const config = getTerminalLoggingConfig();
return Boolean(config);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=terminal-logging-config.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/next-devtools/userspace/app/terminal-logging-config.ts"],"sourcesContent":["export function getTerminalLoggingConfig():\n | false\n | boolean\n | {\n depthLimit?: number\n edgeLimit?: number\n showSourceLocation?: boolean\n } {\n try {\n return JSON.parse(\n process.env.__NEXT_BROWSER_DEBUG_INFO_IN_TERMINAL || 'false'\n )\n } catch {\n return false\n }\n}\n\nexport function getIsTerminalLoggingEnabled(): boolean {\n const config = getTerminalLoggingConfig()\n return Boolean(config)\n}\n"],"names":["getIsTerminalLoggingEnabled","getTerminalLoggingConfig","JSON","parse","process","env","__NEXT_BROWSER_DEBUG_INFO_IN_TERMINAL","config","Boolean"],"mappings":";;;;;;;;;;;;;;;IAiBgBA,2BAA2B;eAA3BA;;IAjBAC,wBAAwB;eAAxBA;;;AAAT,SAASA;IAQd,IAAI;QACF,OAAOC,KAAKC,KAAK,CACfC,QAAQC,GAAG,CAACC,qCAAqC,IAAI;IAEzD,EAAE,UAAM;QACN,OAAO;IACT;AACF;AAEO,SAASN;IACd,MAAMO,SAASN;IACf,OAAOO,QAAQD;AACjB","ignoreList":[0]}

View File

@@ -0,0 +1,4 @@
import type { HydrationErrorState } from '../../shared/hydration-error';
export declare function getSquashedHydrationErrorDetails(error: Error): HydrationErrorState | null;
export declare function attachHydrationErrorState(error: Error): void;
export declare function storeHydrationErrorStateFromConsoleArgs(...args: any[]): void;

View File

@@ -0,0 +1,164 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
attachHydrationErrorState: null,
getSquashedHydrationErrorDetails: null,
storeHydrationErrorStateFromConsoleArgs: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
attachHydrationErrorState: function() {
return attachHydrationErrorState;
},
getSquashedHydrationErrorDetails: function() {
return getSquashedHydrationErrorDetails;
},
storeHydrationErrorStateFromConsoleArgs: function() {
return storeHydrationErrorStateFromConsoleArgs;
}
});
const _react18hydrationerror = require("../../shared/react-18-hydration-error");
const _react19hydrationerror = require("../../shared/react-19-hydration-error");
// We only need this for React 18 or hydration console errors in React 19.
// Once we surface console.error in the dev overlay in pages router, we should only
// use this for React 18.
let hydrationErrorState = {};
const squashedHydrationErrorDetails = new WeakMap();
function getSquashedHydrationErrorDetails(error) {
return squashedHydrationErrorDetails.has(error) ? squashedHydrationErrorDetails.get(error) : null;
}
function attachHydrationErrorState(error) {
if (!(0, _react18hydrationerror.isHydrationError)(error) && !(0, _react19hydrationerror.isHydrationError)(error)) {
return;
}
let parsedHydrationErrorState = {};
// If there's any extra information in the error message to display,
// append it to the error message details property
if (hydrationErrorState.warning) {
// The patched console.error found hydration errors logged by React
// Append the logged warning to the error message
parsedHydrationErrorState = {
// It contains the warning, component stack, server and client tag names
...hydrationErrorState
};
// Consume the cached hydration diff.
// This is only required for now when we still squashed the hydration diff log into hydration error.
// Once the all error is logged to dev overlay in order, this will go away.
if (hydrationErrorState.reactOutputComponentDiff) {
parsedHydrationErrorState.reactOutputComponentDiff = hydrationErrorState.reactOutputComponentDiff;
}
squashedHydrationErrorDetails.set(error, parsedHydrationErrorState);
}
}
function storeHydrationErrorStateFromConsoleArgs() {
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
args[_key] = arguments[_key];
}
let [message, firstContent, secondContent, ...rest] = args;
if ((0, _react18hydrationerror.isHydrationWarning)(message)) {
// Some hydration warnings has 4 arguments, some has 3, fallback to the last argument
// when the 3rd argument is not the component stack but an empty string
// For some warnings, there's only 1 argument for template.
// The second argument is the diff or component stack.
if (args.length === 3) {
secondContent = '';
}
const warning = message.replace(/Warning: /, '').replace('%s', firstContent).replace('%s', secondContent)// remove the last %s from the message
.replace(/%s/g, '');
const lastArg = (rest[rest.length - 1] || '').trim();
hydrationErrorState.reactOutputComponentDiff = generateHydrationDiffReact18(message, firstContent, secondContent, lastArg);
hydrationErrorState.warning = warning;
} else if ((0, _react19hydrationerror.isErrorMessageWithComponentStackDiff)(message)) {
// Some hydration warnings has 4 arguments, some has 3, fallback to the last argument
// when the 3rd argument is not the component stack but an empty string
// For some warnings, there's only 1 argument for template.
// The second argument is the diff or component stack.
if (args.length === 3) {
secondContent = '';
}
const warning = message.replace('%s', firstContent).replace('%s', secondContent)// remove the last %s from the message
.replace(/%s/g, '');
const lastArg = (args[args.length - 1] || '').trim();
hydrationErrorState.reactOutputComponentDiff = lastArg;
hydrationErrorState.warning = warning;
}
}
/*
* Some hydration errors in React 18 does not have the diff in the error message.
* Instead it has the error stack trace which is component stack that we can leverage.
* Will parse the diff from the error stack trace
* e.g.
* Warning: Expected server HTML to contain a matching <div> in <p>.
* at div
* at p
* at div
* at div
* at Page
* output:
* <Page>
* <div>
* <p>
* > <div>
*
*/ function generateHydrationDiffReact18(message, firstContent, secondContent, lastArg) {
const componentStack = lastArg;
let firstIndex = -1;
let secondIndex = -1;
const hydrationWarningType = (0, _react18hydrationerror.getHydrationWarningType)(message);
// at div\n at Foo\n at Bar (....)\n -> [div, Foo]
const components = componentStack.split('\n')// .reverse()
.map((line, index)=>{
// `<space>at <component> (<location>)` -> `at <component> (<location>)`
line = line.trim();
// extract `<space>at <component>` to `<<component>>`
// e.g. ` at Foo` -> `<Foo>`
const [, component, location] = /at (\w+)( \((.*)\))?/.exec(line) || [];
// If there's no location then it's user-land stack frame
if (!location) {
if (component === firstContent && firstIndex === -1) {
firstIndex = index;
} else if (component === secondContent && secondIndex === -1) {
secondIndex = index;
}
}
return location ? '' : component;
}).filter(Boolean).reverse();
let diff = '';
for(let i = 0; i < components.length; i++){
const component = components[i];
const matchFirstContent = hydrationWarningType === 'tag' && i === components.length - firstIndex - 1;
const matchSecondContent = hydrationWarningType === 'tag' && i === components.length - secondIndex - 1;
if (matchFirstContent || matchSecondContent) {
const spaces = ' '.repeat(Math.max(i * 2 - 2, 0) + 2);
diff += "> " + spaces + "<" + component + ">\n";
} else {
const spaces = ' '.repeat(i * 2 + 2);
diff += spaces + "<" + component + ">\n";
}
}
if (hydrationWarningType === 'text') {
const spaces = ' '.repeat(components.length * 2);
diff += "+ " + spaces + '"' + firstContent + '"\n';
diff += "- " + spaces + '"' + secondContent + '"\n';
} else if (hydrationWarningType === 'text-in-tag') {
const spaces = ' '.repeat(components.length * 2);
diff += "> " + spaces + "<" + secondContent + ">\n";
diff += "> " + spaces + '"' + firstContent + '"\n';
}
return diff;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=hydration-error-state.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
import React from 'react';
type PagesDevOverlayErrorBoundaryProps = {
children?: React.ReactNode;
};
type PagesDevOverlayErrorBoundaryState = {
error: Error | null;
};
export declare class PagesDevOverlayErrorBoundary extends React.PureComponent<PagesDevOverlayErrorBoundaryProps, PagesDevOverlayErrorBoundaryState> {
state: {
error: null;
};
static getDerivedStateFromError(error: Error): {
error: Error;
};
render(): React.ReactNode;
}
export {};

View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "PagesDevOverlayErrorBoundary", {
enumerable: true,
get: function() {
return PagesDevOverlayErrorBoundary;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
class PagesDevOverlayErrorBoundary extends _react.default.PureComponent {
static getDerivedStateFromError(error) {
return {
error
};
}
// Explicit type is needed to avoid the generated `.d.ts` having a wide return type that could be specific to the `@types/react` version.
render() {
// The component has to be unmounted or else it would continue to error
return this.state.error ? null : this.props.children;
}
constructor(...args){
super(...args), this.state = {
error: null
};
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=pages-dev-overlay-error-boundary.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/next-devtools/userspace/pages/pages-dev-overlay-error-boundary.tsx"],"sourcesContent":["import React from 'react'\n\ntype PagesDevOverlayErrorBoundaryProps = {\n children?: React.ReactNode\n}\ntype PagesDevOverlayErrorBoundaryState = { error: Error | null }\n\nexport class PagesDevOverlayErrorBoundary extends React.PureComponent<\n PagesDevOverlayErrorBoundaryProps,\n PagesDevOverlayErrorBoundaryState\n> {\n state = { error: null }\n\n static getDerivedStateFromError(error: Error) {\n return { error }\n }\n\n // Explicit type is needed to avoid the generated `.d.ts` having a wide return type that could be specific to the `@types/react` version.\n render(): React.ReactNode {\n // The component has to be unmounted or else it would continue to error\n return this.state.error ? null : this.props.children\n }\n}\n"],"names":["PagesDevOverlayErrorBoundary","React","PureComponent","getDerivedStateFromError","error","render","state","props","children"],"mappings":";;;;+BAOaA;;;eAAAA;;;;gEAPK;AAOX,MAAMA,qCAAqCC,cAAK,CAACC,aAAa;IAMnE,OAAOC,yBAAyBC,KAAY,EAAE;QAC5C,OAAO;YAAEA;QAAM;IACjB;IAEA,yIAAyI;IACzIC,SAA0B;QACxB,uEAAuE;QACvE,OAAO,IAAI,CAACC,KAAK,CAACF,KAAK,GAAG,OAAO,IAAI,CAACG,KAAK,CAACC,QAAQ;IACtD;;QAdK,qBAILF,QAAQ;YAAEF,OAAO;QAAK;;AAWxB","ignoreList":[0]}

View File

@@ -0,0 +1,8 @@
import React from 'react';
export type PagesDevOverlayBridgeType = typeof PagesDevOverlayBridge;
interface PagesDevOverlayBridgeProps {
children?: React.ReactNode;
}
export declare function PagesDevOverlayBridge({ children, }: PagesDevOverlayBridgeProps): import("react/jsx-runtime").JSX.Element;
export declare function register(): void;
export {};

View File

@@ -0,0 +1,122 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
PagesDevOverlayBridge: null,
register: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
PagesDevOverlayBridge: function() {
return PagesDevOverlayBridge;
},
register: function() {
return register;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const _nextdevtools = require("next/dist/compiled/next-devtools");
const _hydrationerrorstate = require("./hydration-error-state");
const _router = require("../../../client/router");
const _stitchederror = require("../app/errors/stitched-error");
const _onrecoverableerror = require("../../../client/react-client-callbacks/on-recoverable-error");
const _pagesdevoverlayerrorboundary = require("./pages-dev-overlay-error-boundary");
const _forwardlogs = require("../app/forward-logs");
const usePagesDevOverlayBridge = ()=>{
_react.default.useInsertionEffect(()=>{
// NDT uses a different React instance so it's not technically a state update
// scheduled from useInsertionEffect.
(0, _nextdevtools.renderPagesDevOverlay)(_stitchederror.getOwnerStack, _hydrationerrorstate.getSquashedHydrationErrorDetails, _onrecoverableerror.isRecoverableError);
}, []);
_react.default.useEffect(()=>{
const { handleStaticIndicator } = require('../../../client/dev/hot-reloader/pages/hot-reloader-pages');
_router.Router.events.on('routeChangeComplete', handleStaticIndicator);
return function() {
_router.Router.events.off('routeChangeComplete', handleStaticIndicator);
};
}, []);
};
function PagesDevOverlayBridge(param) {
let { children } = param;
usePagesDevOverlayBridge();
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_pagesdevoverlayerrorboundary.PagesDevOverlayErrorBoundary, {
children: children
});
}
let isRegistered = false;
function handleError(error) {
if (!error || !(error instanceof Error) || typeof error.stack !== 'string') {
// A non-error was thrown, we don't have anything to show. :-(
return;
}
(0, _hydrationerrorstate.attachHydrationErrorState)(error);
// Skip ModuleBuildError and ModuleNotFoundError, as it will be sent through onBuildError callback.
// This is to avoid same error as different type showing up on client to cause flashing.
if (error.name !== 'ModuleBuildError' && error.name !== 'ModuleNotFoundError') {
_nextdevtools.dispatcher.onUnhandledError(error);
}
}
let origConsoleError = console.error;
function nextJsHandleConsoleError() {
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
args[_key] = arguments[_key];
}
// See https://github.com/facebook/react/blob/d50323eb845c5fde0d720cae888bf35dedd05506/packages/react-reconciler/src/ReactFiberErrorLogger.js#L78
const maybeError = process.env.NODE_ENV !== 'production' ? args[1] : args[0];
(0, _hydrationerrorstate.storeHydrationErrorStateFromConsoleArgs)(...args);
// TODO: Surfaces non-errors logged via `console.error`.
handleError(maybeError);
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.forwardErrorLog)(args);
}
origConsoleError.apply(window.console, args);
}
function onUnhandledError(event) {
const error = event == null ? void 0 : event.error;
handleError(error);
if (error && _forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.forwardUnhandledError)(error);
}
}
function onUnhandledRejection(ev) {
const reason = ev == null ? void 0 : ev.reason;
if (!reason || !(reason instanceof Error) || typeof reason.stack !== 'string') {
// A non-error was thrown, we don't have anything to show. :-(
return;
}
_nextdevtools.dispatcher.onUnhandledRejection(reason);
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.logUnhandledRejection)(reason);
}
}
function register() {
if (isRegistered) {
return;
}
isRegistered = true;
try {
Error.stackTraceLimit = 50;
} catch (e) {}
if (_forwardlogs.isTerminalLoggingEnabled) {
(0, _forwardlogs.initializeDebugLogForwarding)('pages');
}
window.addEventListener('error', onUnhandledError);
window.addEventListener('unhandledrejection', onUnhandledRejection);
window.console.error = nextJsHandleConsoleError;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=pages-dev-overlay-setup.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
export declare const useAppDevRenderingIndicator: () => import("react").TransitionStartFunction;

View File

@@ -0,0 +1,34 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useAppDevRenderingIndicator", {
enumerable: true,
get: function() {
return useAppDevRenderingIndicator;
}
});
const _react = require("react");
const _nextdevtools = require("next/dist/compiled/next-devtools");
const useAppDevRenderingIndicator = ()=>{
const [isPending, startTransition] = (0, _react.useTransition)();
(0, _react.useEffect)(()=>{
if (isPending) {
_nextdevtools.dispatcher.renderingIndicatorShow();
} else {
_nextdevtools.dispatcher.renderingIndicatorHide();
}
}, [
isPending
]);
return startTransition;
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=use-app-dev-rendering-indicator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/next-devtools/userspace/use-app-dev-rendering-indicator.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useTransition } from 'react'\nimport { dispatcher } from 'next/dist/compiled/next-devtools'\n\nexport const useAppDevRenderingIndicator = () => {\n const [isPending, startTransition] = useTransition()\n\n useEffect(() => {\n if (isPending) {\n dispatcher.renderingIndicatorShow()\n } else {\n dispatcher.renderingIndicatorHide()\n }\n }, [isPending])\n\n return startTransition\n}\n"],"names":["useAppDevRenderingIndicator","isPending","startTransition","useTransition","useEffect","dispatcher","renderingIndicatorShow","renderingIndicatorHide"],"mappings":"AAAA;;;;;+BAKaA;;;eAAAA;;;uBAH4B;8BACd;AAEpB,MAAMA,8BAA8B;IACzC,MAAM,CAACC,WAAWC,gBAAgB,GAAGC,IAAAA,oBAAa;IAElDC,IAAAA,gBAAS,EAAC;QACR,IAAIH,WAAW;YACbI,wBAAU,CAACC,sBAAsB;QACnC,OAAO;YACLD,wBAAU,CAACE,sBAAsB;QACnC;IACF,GAAG;QAACN;KAAU;IAEd,OAAOC;AACT","ignoreList":[0]}