aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-07 22:08:18 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-07 22:08:18 -0700
commit2a6edf00cdb1326267d9099adc2986c94f048134 (patch)
tree827830dd77e1feb5fe5b292b2a1f755442bdd400 /examples
parentcbd2c56a1fb0fd36f34af20a38e681d6e5e9d64b (diff)
downloadbun-2a6edf00cdb1326267d9099adc2986c94f048134.tar.gz
bun-2a6edf00cdb1326267d9099adc2986c94f048134.tar.zst
bun-2a6edf00cdb1326267d9099adc2986c94f048134.zip
lotta changes
Diffstat (limited to 'examples')
-rw-r--r--examples/hello-next/bun-framework-next/.npmignore2
-rw-r--r--examples/hello-next/bun-framework-next/bun-error.css288
-rw-r--r--examples/hello-next/bun-framework-next/bun-error.tsx783
-rw-r--r--examples/hello-next/bun-framework-next/bun-error/close.pngbin0 -> 757 bytes
-rw-r--r--examples/hello-next/bun-framework-next/bun-error/error.pngbin0 -> 717 bytes
-rw-r--r--examples/hello-next/bun-framework-next/client.development.tsx416
-rw-r--r--examples/hello-next/bun-framework-next/fallback.development.tsx82
-rw-r--r--examples/hello-next/bun-framework-next/index.js0
-rw-r--r--examples/hello-next/bun-framework-next/next-server.tsx0
-rw-r--r--examples/hello-next/bun-framework-next/package.json81
-rw-r--r--examples/hello-next/bun-framework-next/page-loader.ts147
-rw-r--r--examples/hello-next/bun-framework-next/render.tsx0
-rw-r--r--examples/hello-next/bun-framework-next/renderDocument.tsx722
-rw-r--r--examples/hello-next/bun-framework-next/route-loader.ts0
-rw-r--r--examples/hello-next/bun-framework-next/server.development.tsx79
-rw-r--r--examples/hello-next/bun-framework-next/server.production.tsx0
-rw-r--r--examples/hello-next/bun-framework-next/tsconfig.json21
-rw-r--r--examples/hello-next/package.json3
-rw-r--r--examples/hello-next/pages/errortest.tsx14
-rw-r--r--examples/hello-next/pages/index.tsx13
-rw-r--r--examples/hello-next/styles/2.css3
-rw-r--r--examples/hello-next/styles/globals.css5
-rw-r--r--examples/hello-next/tsconfig.json12
-rw-r--r--examples/lotta-modules/index.js652
-rw-r--r--examples/lotta-modules/public/index.html6
25 files changed, 2669 insertions, 660 deletions
diff --git a/examples/hello-next/bun-framework-next/.npmignore b/examples/hello-next/bun-framework-next/.npmignore
new file mode 100644
index 000000000..dc0954477
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/.npmignore
@@ -0,0 +1,2 @@
+*.bun
+node_modules \ No newline at end of file
diff --git a/examples/hello-next/bun-framework-next/bun-error.css b/examples/hello-next/bun-framework-next/bun-error.css
new file mode 100644
index 000000000..64801411f
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/bun-error.css
@@ -0,0 +1,288 @@
+:host {
+ --bun-error-color: #e33737;
+ --bun-error-monospace: ui-monospace, Menlo, Monaco, "Cascadia Mono",
+ "Segoe UI Mono", "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace",
+ "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New", monospace;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+#BunErrorOverlay-container {
+ box-shadow: 0px 16px 24px rgba(0, 0, 0, 0.06), 0px 2px 6px rgba(0, 0, 0, 0.1),
+ 0px 0px 1px rgba(0, 0, 0, 0.04);
+ backdrop-filter: blur(42px);
+ backface-visibility: visible;
+ border: inset 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 17px;
+ background-color: rgba(255, 255, 255, 0.92);
+ width: 480px;
+
+ position: fixed;
+ top: 120px;
+ right: 48px;
+ z-index: 999999;
+
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
+ Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+}
+
+#BunErrorOverlay-container a {
+ color: inherit;
+}
+
+.BunError-Summary-ErrorIcon {
+ content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAgCAYAAAB3j6rJAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJiSURBVHgBzZdLUttAEIa7RwpVeKUD4Ip8hFSB7V3kG8AJgBPgG+CcAG4QcwPfIFpiigU5gRWcqmy1AVwVaTo9Y+yyiEeakc3jX7j0GEmfe7r/6QH4IELYUJNuN/LyPMwRU2g04lYcp1BDtUEYIPSJvvNhtHI5QcTB3vX1FThKQE0xxI8XEEohEQ2n+/sROKoWyP3BwYn6qHGA553DW4CgEFUfin6328fwmiDTbldBhFXjiHNlEkUBWMoJRCUoSNm3HB6Kx0fbsW4gnpQDQLT/l4hntlGxBlHR4NJ0mndW4D08WCWuNYgv5YXhVsJmNASi0bqbnNj9P2pKtwGiyxXxcM2tJNvd/bI3Hp82b26OJOK3dc9nc+PbHMRUrhyJgqV7QowMr4iqTK4SpNK8VvRXSnNiVphcKYhO0BLzIkvAZ5WaXCmID6AeDGFLYpO7NJWzEUSbF9EAHKTagYohgcnkjCDavKoVgqNMJrcWpKZ5AQlh46LBp6enCysQ36LuFy8tnBFZ2Tkn+cnLcv6vQ1PlypViC6I+PsiEUB3ZomMLLZ+Mm+Nxzwgy7XQmsMVKKVWe95q3t7E6LEyNi3ktRZSWrTWl8rxl5JcgVeZlUJI1Gq3FWsM+cQpuCn91Ov0CiEd0Bo7RkERXq2tNPps5R4UBzlU5axAdDQDrbmr5EsSvhQs7OxG4S5ucTtb7dntYxzeeNWLzi3MhWpwnxy4d3IpSX/0yxGeor0OGmPcqWHu/FixypNY2cZvSINxZ/YT3VTIHmc0u1Qm8k9R+WYO07u7SDLHH+1bnzfNGYjPkhfJIbdr/AfAS02LsKGiuAAAAAElFTkSuQmCC");
+ width: 20px;
+ height: 19px;
+
+ margin-right: 6px;
+ display: block;
+}
+
+.BunError-Summary-CloseIcon {
+ content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAYAAACoPemuAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKKSURBVHgBxZjpTsMwEISnaTmLKLf4AX94/7fiFlRcJaUKl6exK8e1k7XTY6QVUbDjj/V4bdNBe2Uquio2nPdfKn6RqA7StKuir2JHxXZNO4LlKkb65zeWBLavYxdpelMxhABQCkaQI6QDuRrqCEoCdqjiFItXoeIagex1Gzqfo8zUMsSxByo+Vfz4fokaqH0sVx09xhxcCOwY5RSuQgbuHVZ58YGx0RlWK8LtoYT74wsXjEXyHM3eW4Y4JgFZ76ZV2xancAPrE+3T44MNRiCp2bnd5MK29A0rfyFsP7VRz3pxLOxoF8ctFZeYz7wRPfOgn/mHX6B5Rui1zP7gDmQaWc8TlEXytwGKKpy+dRoYMG41Um+52fHBuVBG0jH6ZpAtyMVV20MYLgRFq+xBpm1TFrjtbAo7dfUAI1SzxMr9ocF8UFIPUx2TsQxx4pTQ9G7migVAVYBiwagQnK0kKBsotdITblDz7eRDgAH7QZrop9CBj/67gbywVmTAxGdxVKEeGtoQKgkusz4QoxDUbK+zZOCibkzGW/yYtMawTNx73tPkJ/CXEj7zMEjPSY7zRWYNJtUwAGVWX2i1sgi/QabcgJn7X4p8JSEEJ139467TqS/oxAvup34+QrhOmR1ijHLV89uS2xY9+WjPN7N3hbRiu0hNj1U2BKfzGesVs/XCBzc7r0j32iLEbE1Xs2/aHtHivzQtxEzNTia+VUIoGnaA1Yl3iEptDC1fblGcb2nRbSNC3cGZpbq6MtGdCJf6f7Qm0c+38BwiJANKbzexeoJegT7FZOIA5SbdFjDXUJO6RrFTRChe82Jv7PQPbcFyMJZ0aOMd3qx47SMoyw5B6VnjF2aECyjXMFEl6B+GYop4atKAigAAAABJRU5ErkJggg==");
+ width: 22px;
+ height: 22px;
+ border-radius: 50%;
+ cursor: pointer;
+}
+
+.BunError-Summary-CloseIcon:hover {
+ transform: scale(1.2);
+
+ background-color: rgb(255, 255, 255);
+}
+
+.BunError-Summary {
+ display: grid;
+ grid-template-columns: min-content auto min-content;
+ grid-template-rows: 46px;
+ align-items: center;
+ padding: 0 18px;
+ border-bottom: 1px solid rgb(220, 220, 220);
+}
+
+.BunError-footer {
+ display: grid;
+ padding: 12px 18px;
+ justify-content: flex-end;
+ border-top: 1px solid rgb(220, 220, 220);
+ align-items: center;
+}
+
+.BunError-Summary-Title {
+ font-weight: 500;
+ letter-spacing: 0.36px;
+}
+
+.BunError-ErrorTag,
+.BunError-error-code {
+ color: rgb(165, 165, 165);
+ font-weight: 500;
+ font-size: 12pt;
+}
+
+.BunError-ErrorTag {
+ font-size: 14px;
+ text-transform: uppercase;
+ font-weight: 300;
+}
+
+.BunError-error-header {
+ display: flex;
+ align-items: center;
+ gap: 0.5ch;
+}
+
+.BunError-error-message {
+ color: var(--bun-error-color);
+ font-size: 16pt;
+ font-weight: bold;
+}
+
+.BunError-list {
+ margin-top: 14px;
+ gap: 14px;
+}
+
+.BunError-error-subtitle,
+.BunError-error-header,
+.BunError-error-message {
+ padding-left: 18px;
+ padding-right: 18px;
+}
+
+.BunError-error-subtitle {
+ font-size: 500;
+}
+
+.BunError-NativeStackTrace {
+ margin-top: 0;
+}
+
+.BunError-NativeStackTrace-filename {
+ padding: 8px 18px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ font-weight: 500;
+ letter-spacing: 0.36px;
+ margin-bottom: 8px;
+ display: block;
+}
+
+.BunError-NativeStackTrace-filename:hover {
+ text-decoration: underline;
+}
+
+.BunError-SourceLines-lines {
+}
+
+.BunError-SourceLines {
+ display: grid;
+ grid-template-columns: min-content auto;
+ grid-template-rows: repeat(16px, 6);
+ column-gap: 13px;
+ font-size: 14px;
+ padding-left: 24px;
+ align-items: center;
+ position: relative;
+ overflow-x: auto;
+}
+
+.BunError-SourceLine-text {
+ white-space: pre;
+ display: block;
+
+ font-family: var(--bun-error-monospace);
+}
+
+.BunError-SourceLine-number {
+ font-variant: tabular-nums;
+ text-align: right;
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.BunError-SourceLine-number--empty {
+ color: rgb(165, 165, 165);
+}
+
+.BunError-SourceLine-number,
+.BunError-SourceLine-text {
+ height: 18px;
+}
+
+.BunError-SourceLines-highlighter--0,
+.BunError-SourceLines-highlighter--1,
+.BunError-SourceLines-highlighter--2,
+.BunError-SourceLines-highlighter--3,
+.BunError-SourceLines-highlighter--4,
+.BunError-SourceLines-highlighter--5 {
+ position: absolute;
+}
+
+.BunError-SourceLine-text--highlight {
+ color: #e33737;
+}
+
+#BunError-poweredBy {
+ height: 16px;
+
+ content: url("data:image/webp;base64,UklGRhwFAABXRUJQVlA4TBAFAAAv3MAHEBeioG0jx3f8MY+fGAgkbdz7Zz4Ekjbu/TMftpEkOaFfC5vgSJ4sHswjm7TZk7R34AJUQAFAQwYAQAUkQAZUAFTUz5XDIaPd77AAN2DlBrAAG/Ai8CFwcKICP6L+BzgTEBEBp6xqWyZJejDAWERMQEwHEuEip1yEmPDc/w1qRs7/OqL/EyBbtu22bQ4ViCHTKM0gUUNmIjMmZfu6s7nz3v//KwIgRfe3iP5PAP9bdVNLfR/hfdqK3bxLjDgr9Q4JGpfk7xHxPPu8KRdApEaiIpdSr8iU9id7Cn+vE6WbWqRuTORqm7pujCV+LKW8jyymEZHGALqpRer76LU4NXya9fhb5XgQZ2ks02uxtgBmtXSrBEAr1jO04mxfiazx06Lp71TgQXzbzoPYWSMoxV4pGLEWaMXz/xuHIyPevACm4r6BEXcaNBZeGPGt1NvmKij9pFL47cE48TgLaksRlF6SgnhtsKbrV/w0rVdO2yhdg+lKg+naB9OvK/+Ko+2KrNfeTfuV0/pp2q5rj3/G9OtK22C7ou3Laj6EXEvfHMYnOvM4D8R+Lf434PQ9/din0Vrt6wYsundZj+7QABzNPoeumpMa4Gj2JQ7mqlq3735vqjUCWmxzoq9D9C/217cCWbOtVPXsNvXOt7pD0NxVLV2xAklbflW9A6BF/YFD/clVawBi1XYX3+WbrHdRa4SiE8uWaDJcXbo4GhmrzhM41BWo+jtw6DtAsQJRfQegmSFqjcCpaeC9ALFaI5A0AVnvCWL1G2uEeOsJSXUnJFpjuI1xyWZsUVfok56wa6ZPesChEXZLc4VFN8ga6Zt1FAF23emL70DQGgGW7yJAbL4DQbedOdGvceRjyE2vbRD0hpfOg6h/wKw7vDyyJxwa4PZmmDV2hb74Zph0ZtHM8P6mMMw6Q5EmAA4pwzhOxrDpNw9oVijKWCtQzVCddwsUC6DWYfvi1jpsurLrMcrfnKOkOyySBkKi9UjOnkUcVd9QvzqtzFaCBprH6HPlSfVhjd3+J6VnNNoCmih8weaRVigaPhVg0XiYobgvOgPNm8dPKk93PUavb/KDDUhEExzSFiPJ/e7GcgwWLXDqOlg0A6G5FzdInocV4Pb9YYuPXhpGa4RZy6h+8x4VnYGZSIdE87GkPnJbj6WG7qU7LFoGWTeAYtYAi7WYu6THIHk/OjQNkm+g6dolv/HoVq30W9pqosleymsXay/vPVnXuL60RqDoayaeWukPtQA0detC831MxFPzo1A1RaZTbyBp3eeYbF+Z5pia7gNNlNEae/EtMHsOp+MNIFbHNQ6imrqsho7f/FjjI+bquEaA4rDmb87q8IfhZEdEP8ZyimkfHkXcq/qzMIy5qe2aGBdb7BY9GcfStTQBFM8RMXftFRmmpv7Ewxo+heYWs9oSH5dEGQa6mPXhCEHjdzkbZOGjBjAvkafzMk88XCaGcebhtCwzH2eeLss88XCeJ2CZeBhnYFrmic+a6M8AdaeaNj2OAeRenPy1HQeNi/U3jwIf/sszorAfTjqSf6u8rgBgWnrwcVBaOELuKhA0ruzVW7d/RGsMGJedKklKF5+rDuLSwad4ki4fA8G1jRdAUtkKZQn/Xb8pURYOgbhgEb5BfMYsIlwdwBmfMYtwdYBpwSLCxwCgzpiFCw0AScEsfB4BxHLw3x1vs1WIgXWaagBQOs1NAu94kadaAUCS5hsFe7wwCZx6sVF4/wI=");
+}
+
+#BunError-SourceLine-text-highlightExpression {
+ font-weight: bold;
+ text-decoration-style: wavy;
+}
+
+.BunError-JSException--TypeError #BunError-SourceLine-text-highlightExpression {
+ border: 1px solid rgba(0, 0, 0, 0.2);
+}
+.BunError-Indented {
+ display: inline-block;
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.BunError-divet {
+ vertical-align: bottom;
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.BunError-error-typename {
+ font-family: var(--bun-error-monospace);
+ color: #e39437;
+ font-weight: bold;
+}
+
+.BunError-error-muted {
+ font-weight: normal;
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.BunError-error-muted,
+.BunError-StackFrame--muted {
+ color: rgb(165, 165, 165);
+}
+
+.BunError-NativeStackTrace .BunError-error-typename {
+ user-select: none;
+ -webkit-user-select: none;
+}
+
+.BunError-StackFrame-link {
+}
+
+.BunError-StackFrame-link-content {
+ display: flex;
+ gap: 0.25ch;
+ white-space: nowrap;
+}
+
+.BunError-StackFrame {
+ display: table-row;
+}
+
+.BunError-StackFrame-identifier {
+ padding-right: 18px;
+ font-size: 0.8em;
+ font-family: var(--bun-error-monospace);
+ letter-spacing: 0.49px;
+}
+
+.BunError-error-message--mono {
+ font-family: var(--bun-error-monospace);
+}
+.BunError-StackFrame-identifier,
+.BunError-StackFrame-link {
+ display: table-cell;
+ font-weight: 500;
+}
+
+.BunError-BuildError {
+ padding-bottom: 18px;
+}
+
+.BunError-StackFrame-link-content {
+ font-size: 0.8em;
+}
+
+.BunError-StackFrames {
+ display: table;
+ table-layout: auto;
+ padding: 13px 10px;
+ margin: 8px auto;
+ border-radius: 4px;
+
+ background-color: rgb(244, 244, 244);
+}
diff --git a/examples/hello-next/bun-framework-next/bun-error.tsx b/examples/hello-next/bun-framework-next/bun-error.tsx
new file mode 100644
index 000000000..5702f66e6
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/bun-error.tsx
@@ -0,0 +1,783 @@
+import type {
+ FallbackMessageContainer,
+ JSException as JSExceptionType,
+ Message,
+ SourceLine,
+ StackFrame,
+ Problems,
+ FallbackStep,
+ StackTrace,
+ Location,
+ JSException,
+ WebsocketMessageBuildFailure,
+} from "../../../src/api/schema";
+
+import ReactDOM from "react-dom";
+import {
+ useCallback,
+ useState,
+ useEffect,
+ useLayoutEffect,
+ createContext,
+ useContext,
+ Children,
+} from "react";
+
+enum StackFrameScope {
+ Eval = 1,
+ Module = 2,
+ Function = 3,
+ Global = 4,
+ Wasm = 5,
+ Constructor = 6,
+}
+
+enum JSErrorCode {
+ Error = 0,
+ EvalError = 1,
+ RangeError = 2,
+ ReferenceError = 3,
+ SyntaxError = 4,
+ TypeError = 5,
+ URIError = 6,
+ AggregateError = 7,
+
+ // StackOverflow & OutOfMemoryError is not an ErrorType in <JavaScriptCore/ErrorType.h> within JSC, so the number here is just totally made up
+ OutOfMemoryError = 8,
+ BundlerError = 252,
+ StackOverflow = 253,
+ UserErrorCode = 254,
+}
+
+const JSErrorCodeLabel = {
+ 0: "Error",
+ 1: "EvalError",
+ 2: "RangeError",
+ 3: "ReferenceError",
+ 4: "SyntaxError",
+ 5: "TypeError",
+ 6: "URIError",
+ 7: "AggregateError",
+ 253: "StackOverflow",
+ 8: "OutOfMemory",
+};
+
+const BUN_ERROR_CONTAINER_ID = "__bun-error__";
+
+enum RuntimeType {
+ Nothing = 0x0,
+ Function = 0x1,
+ Undefined = 0x2,
+ Null = 0x4,
+ Boolean = 0x8,
+ AnyInt = 0x10,
+ Number = 0x20,
+ String = 0x40,
+ Object = 0x80,
+ Symbol = 0x100,
+ BigInt = 0x200,
+}
+
+enum ErrorTagType {
+ build,
+ resolve,
+ server,
+ client,
+ hmr,
+}
+
+const ErrorTag = ({ type }: { type: ErrorTagType }) => (
+ <div className={`BunError-ErrorTag BunError-ErrorTag--${ErrorTagType[type]}`}>
+ {ErrorTagType[type]}
+ </div>
+);
+
+const errorTags = [
+ <ErrorTag type={ErrorTagType.build}></ErrorTag>,
+ <ErrorTag type={ErrorTagType.resolve}></ErrorTag>,
+ <ErrorTag type={ErrorTagType.server}></ErrorTag>,
+ <ErrorTag type={ErrorTagType.client}></ErrorTag>,
+ <ErrorTag type={ErrorTagType.hmr}></ErrorTag>,
+];
+
+const normalizedFilename = (filename: string, cwd: string): string => {
+ if (filename.startsWith(cwd)) {
+ return filename.substring(cwd.length);
+ }
+
+ return filename;
+};
+
+const blobFileURL = (filename: string): string => {
+ return new URL("/blob:" + filename, location.href).href;
+};
+
+const srcFileURL = (filename: string, line: number, column: number): string => {
+ if (filename.endsWith(".bun")) {
+ return new URL("/" + filename, location.href).href;
+ }
+
+ var base = `/src:${filename}`;
+ if (line > -1) {
+ base = base + `:${line}`;
+
+ if (column > -1) {
+ base = base + `:${column}`;
+ }
+ }
+
+ return new URL(base, location.href).href;
+};
+
+class FancyTypeError {
+ constructor(exception: JSException) {
+ this.runtimeType = exception.runtime_type || 0;
+ this.runtimeTypeName = RuntimeType[this.runtimeType] || "undefined";
+ this.message = exception.message;
+ this.explain = "";
+
+ this.normalize(exception);
+ }
+
+ runtimeType: RuntimeType;
+ explain: string;
+ runtimeTypeName: string;
+ message: string;
+
+ normalize(exception: JSException) {
+ let i = exception.message.lastIndexOf(" is ");
+ if (i === -1) return;
+ const partial = exception.message.substring(i + " is ".length);
+ const nextWord = /(["a-zA-Z0-9_\.]+)\)$/.exec(partial);
+ if (nextWord && nextWord[0]) {
+ this.runtimeTypeName = nextWord[0];
+ this.runtimeTypeName = this.runtimeTypeName.substring(
+ 0,
+ this.runtimeTypeName.length - 1
+ );
+ switch (this.runtimeTypeName.toLowerCase()) {
+ case "undefined": {
+ this.runtimeType = RuntimeType.Undefined;
+ break;
+ }
+ case "null": {
+ this.runtimeType = RuntimeType.Null;
+ break;
+ }
+ case "string": {
+ this.runtimeType = RuntimeType.String;
+ break;
+ }
+ case "true":
+ case "false": {
+ this.runtimeType = RuntimeType.Boolean;
+ break;
+ }
+
+ case "number":
+ this.runtimeType = RuntimeType.Number;
+ break;
+
+ case "bigint":
+ this.runtimeType = RuntimeType.BigInt;
+ break;
+
+ case "symbol":
+ this.runtimeType = RuntimeType.Symbol;
+ break;
+ default: {
+ this.runtimeType = RuntimeType.Object;
+ break;
+ }
+ }
+ this.message = exception.message.substring(0, i);
+ this.message = this.message.substring(
+ 0,
+ this.message.lastIndexOf("(In ")
+ );
+ }
+ }
+}
+
+var onClose = dismissError;
+
+const IndentationContext = createContext(0);
+const SourceLines = ({
+ sourceLines,
+ highlight = -1,
+ highlightColumnStart = 0,
+ highlightColumnEnd = Infinity,
+ children,
+}: {
+ sourceLines: SourceLine[];
+ highlightColumnStart: number;
+ highlightColumnEnd: number;
+ highlight: number;
+}) => {
+ let start = sourceLines.length;
+ let end = 0;
+ let dedent = Infinity;
+ let originalLines = new Array(sourceLines.length);
+ let _i = 0;
+ for (let i = 0; i < sourceLines.length; i++) {
+ // bun only prints \n, no \r\n, so this should work fine
+ sourceLines[i].text = sourceLines[i].text.replaceAll("\n", "");
+
+ // This will now only trim spaces (and vertical tab character which never prints)
+ const left = sourceLines[i].text.trimLeft();
+
+ if (left.length > 0) {
+ start = Math.min(start, i);
+ end = Math.max(end, i + 1);
+
+ dedent = Math.min(sourceLines[i].text.length - left.length, dedent);
+ }
+ }
+
+ const _sourceLines = sourceLines.slice(start, end);
+ const childrenArray = children || [];
+ const numbers = new Array(_sourceLines.length + childrenArray.length);
+ const lines = new Array(_sourceLines.length + childrenArray.length);
+
+ let highlightI = 0;
+ for (let i = 0; i < _sourceLines.length; i++) {
+ const { line, text } = _sourceLines[i];
+ const classes = {
+ empty: text.trim().length === 0,
+ highlight: highlight + 1 === line || _sourceLines.length === 1,
+ };
+ if (classes.highlight) highlightI = i;
+ const _text = classes.empty ? "" : text.substring(dedent);
+ lines[i] = (
+ <div
+ key={i}
+ className={`BunError-SourceLine-text ${
+ classes.empty ? "BunError-SourceLine-text--empty" : ""
+ } ${classes.highlight ? "BunError-SourceLine-text--highlight" : ""}`}
+ >
+ {classes.highlight ? (
+ <>
+ {_text.substring(0, highlightColumnStart - dedent)}
+ <span id="BunError-SourceLine-text-highlightExpression">
+ {_text.substring(
+ highlightColumnStart - dedent,
+ highlightColumnEnd - dedent
+ )}
+ </span>
+ {_text.substring(highlightColumnEnd - dedent)}
+ </>
+ ) : (
+ _text
+ )}
+ </div>
+ );
+ numbers[i] = (
+ <div
+ key={line}
+ className={`BunError-SourceLine-number ${
+ classes.empty ? "BunError-SourceLine-number--empty" : ""
+ } ${classes.highlight ? "BunError-SourceLine-number--highlight" : ""}`}
+ >
+ {line}
+ </div>
+ );
+
+ if (classes.highlight && children) {
+ i++;
+
+ numbers.push(
+ ...childrenArray.map((child, index) => (
+ <div
+ key={"highlight-number-" + index}
+ className={`BunError-SourceLine-number ${
+ classes.empty ? "BunError-SourceLine-number--empty" : ""
+ } ${
+ classes.highlight ? "BunError-SourceLine-number--highlight" : ""
+ }`}
+ ></div>
+ ))
+ );
+ lines.push(
+ ...childrenArray.map((child, index) => (
+ <div
+ key={"highlight-line-" + index}
+ className={`BunError-SourceLine-text`}
+ >
+ {childrenArray[index]}
+ </div>
+ ))
+ );
+ }
+ }
+
+ return (
+ <IndentationContext.Provider value={dedent}>
+ <div className="BunError-SourceLines">
+ <div
+ className={`BunError-SourceLines-highlighter--${highlightI}`}
+ ></div>
+
+ <div className="BunError-SourceLines-numbers">{numbers}</div>
+ <div className="BunError-SourceLines-lines">{lines}</div>
+ </div>
+ </IndentationContext.Provider>
+ );
+};
+
+const BuildErrorSourceLines = ({ location }: { location: Location }) => {
+ const { line, line_text, column, file } = location;
+ const sourceLines: SourceLine[] = [{ line, text: line_text }];
+ return (
+ <SourceLines
+ sourceLines={sourceLines}
+ highlight={line}
+ highlightColumnStart={column}
+ highlightColumnEnd={column}
+ />
+ );
+};
+
+const BuildErrorStackTrace = ({ location }: { location: Location }) => {
+ const { cwd } = useContext(ErrorGroupContext);
+ const filename = normalizedFilename(location.file, cwd);
+ const { line, column } = location;
+ return (
+ <div className={`BunError-NativeStackTrace`}>
+ <a
+ href={srcFileURL(filename, line, column)}
+ target="_blank"
+ className="BunError-NativeStackTrace-filename"
+ >
+ {filename}:{line}:{column}
+ </a>
+ <BuildErrorSourceLines location={location} />
+ </div>
+ );
+};
+
+const StackFrameIdentifier = ({
+ functionName,
+ scope,
+}: {
+ functionName?: string;
+ scope: StackFrameScope;
+}) => {
+ switch (scope) {
+ case StackFrameScope.Constructor: {
+ return functionName ? `new ${functionName}` : "new (anonymous)";
+ break;
+ }
+
+ case StackFrameScope.Eval: {
+ return "eval";
+ break;
+ }
+
+ case StackFrameScope.Module: {
+ return "(esm)";
+ break;
+ }
+
+ case StackFrameScope.Global: {
+ return "(global)";
+ break;
+ }
+
+ case StackFrameScope.Wasm: {
+ return "(wasm)";
+ break;
+ }
+
+ default: {
+ return functionName ? functionName : "λ()";
+ break;
+ }
+ }
+};
+
+const NativeStackFrame = ({
+ frame,
+ isTop,
+}: {
+ frame: StackFrame;
+ isTop: boolean;
+}) => {
+ const { cwd } = useContext(ErrorGroupContext);
+ const {
+ file,
+ function_name: functionName,
+ position: { line, column_start: column },
+ scope,
+ } = frame;
+ const fileName = normalizedFilename(file, cwd);
+ return (
+ <div
+ className={`BunError-StackFrame ${
+ fileName.endsWith(".bun") ? "BunError-StackFrame--muted" : ""
+ }`}
+ >
+ <div
+ title={StackFrameScope[scope]}
+ className="BunError-StackFrame-identifier"
+ >
+ <StackFrameIdentifier functionName={functionName} scope={scope} />
+ </div>
+
+ <a
+ target="_blank"
+ href={blobFileURL(fileName)}
+ className="BunError-StackFrame-link"
+ >
+ <div className="BunError-StackFrame-link-content">
+ <div className={`BunError-StackFrame-file`}>{fileName}</div>
+ {line > -1 && (
+ <div className="BunError-StackFrame-line">:{line + 1}</div>
+ )}
+ {column > -1 && (
+ <div className="BunError-StackFrame-column">:{column}</div>
+ )}
+ </div>
+ </a>
+ </div>
+ );
+};
+
+const NativeStackFrames = ({ frames }) => {
+ const items = new Array(frames.length);
+ for (let i = 0; i < frames.length; i++) {
+ items[i] = <NativeStackFrame key={i} frame={frames[i]} />;
+ }
+
+ return <div className="BunError-StackFrames">{items}</div>;
+};
+
+const NativeStackTrace = ({
+ frames,
+ sourceLines,
+ children,
+}: {
+ frames: StackFrame[];
+ sourceLines: SourceLine[];
+}) => {
+ const { file = "", position } = frames[0];
+ const { cwd } = useContext(ErrorGroupContext);
+ const filename = normalizedFilename(file, cwd);
+ return (
+ <div className={`BunError-NativeStackTrace`}>
+ <a
+ href={blobFileURL(filename)}
+ target="_blank"
+ className="BunError-NativeStackTrace-filename"
+ >
+ {filename}:{position.line + 1}:{position.column_start}
+ </a>
+ {sourceLines.length > 0 && (
+ <SourceLines
+ highlight={position.line}
+ sourceLines={sourceLines}
+ highlightColumnStart={position.column_start}
+ highlightColumnEnd={position.column_stop}
+ >
+ {children}
+ </SourceLines>
+ )}
+ {frames.length > 0 && <NativeStackFrames frames={frames} />}
+ </div>
+ );
+};
+
+const divet = <span className="BunError-divet">^</span>;
+const DivetRange = ({ start, stop }) => {
+ const length = Math.max(stop - start, 0);
+ if (length === 0) return null;
+ return (
+ <span
+ className="BunError-DivetRange"
+ style={{ width: `${length - 1}ch` }}
+ ></span>
+ );
+};
+
+const Indent = ({ by, children }) => {
+ const amount = useContext(IndentationContext);
+ return (
+ <>
+ {` `.repeat(by - amount)}
+ {children}
+ </>
+ );
+};
+
+const JSException = ({ value }: { value: JSExceptionType }) => {
+ switch (value.code) {
+ case JSErrorCode.TypeError: {
+ const fancyTypeError = new FancyTypeError(value);
+
+ if (fancyTypeError.runtimeType !== RuntimeType.Nothing) {
+ return (
+ <div
+ className={`BunError-JSException BunError-JSException--TypeError`}
+ >
+ <div className="BunError-error-header">
+ <div className={`BunError-error-code`}>TypeError</div>
+ {errorTags[ErrorTagType.server]}
+ </div>
+
+ <div className={`BunError-error-message`}>
+ {fancyTypeError.message}
+ </div>
+
+ {fancyTypeError.runtimeTypeName.length && (
+ <div className={`BunError-error-subtitle`}>
+ It's{" "}
+ <span className="BunError-error-typename">
+ {fancyTypeError.runtimeTypeName}
+ </span>
+ .
+ </div>
+ )}
+
+ {value.stack && (
+ <NativeStackTrace
+ frames={value.stack.frames}
+ sourceLines={value.stack.source_lines}
+ >
+ <Indent by={value.stack.frames[0].position.column_start}>
+ <span className="BunError-error-typename">
+ {fancyTypeError.runtimeTypeName}
+ </span>
+ </Indent>
+ </NativeStackTrace>
+ )}
+ </div>
+ );
+ }
+ }
+
+ default: {
+ return (
+ <div className={`BunError-JSException`}>
+ <div className="BunError-error-header">
+ <div className={`BunError-error-code`}>{value.name}</div>
+ {errorTags[ErrorTagType.server]}
+ </div>
+
+ <div className={`BunError-error-message`}>{value.message}</div>
+
+ {value.stack && (
+ <NativeStackTrace
+ frames={value.stack.frames}
+ sourceLines={value.stack.source_lines}
+ />
+ )}
+ </div>
+ );
+ }
+ }
+};
+
+const Summary = ({
+ errorCount,
+ onClose,
+}: {
+ errorCount: number;
+ onClose: Function;
+}) => {
+ return (
+ <div className="BunError-Summary">
+ <div className="BunError-Summary-ErrorIcon"></div>
+ <div className="BunError-Summary-Title">
+ {errorCount}&nbsp;error{errorCount > 1 ? "s" : ""}&nbsp;on this page
+ </div>
+
+ <div onClick={onClose} className="BunError-Summary-CloseButton">
+ <div className="BunError-Summary-CloseIcon"></div>
+ </div>
+ </div>
+ );
+};
+
+const BuildError = ({ message }: { message: Message }) => {
+ let title = (message.data.text || "").trim();
+ const newline = title.indexOf("\n");
+ let subtitle = "";
+ if (newline > -1) {
+ subtitle = title.slice(newline + 1).trim();
+ title = title.slice(0, newline);
+ }
+ return (
+ <div className={`BunError-BuildError BunError-BuildError--build`}>
+ <div className="BunError-error-header">
+ <div className={`BunError-error-code`}>BuildError</div>
+ </div>
+
+ <div className={`BunError-error-message`}>{title}</div>
+
+ {subtitle.length > 0 && (
+ <div className={`BunError-error-subtitle`}>{subtitle}</div>
+ )}
+
+ {message.data.location && (
+ <BuildErrorStackTrace location={message.data.location} />
+ )}
+ </div>
+ );
+};
+
+const ResolveError = ({ message }: { message: Message }) => {
+ const { cwd } = useContext(ErrorGroupContext);
+ let title = (message.data.text || "").trim();
+ const newline = title.indexOf("\n");
+ let subtitle = null;
+ if (newline > -1) {
+ subtitle = title.slice(newline + 1).trim();
+ title = title.slice(0, newline);
+ }
+
+ return (
+ <div className={`BunError-BuildError BunError-BuildError--resolve`}>
+ <div className="BunError-error-header">
+ <div className={`BunError-error-code`}>ResolveError</div>
+ </div>
+
+ <div className={`BunError-error-message`}>
+ Can't import{" "}
+ <span className="BunError-error-message--mono">
+ {message.on.resolve}
+ </span>
+ </div>
+
+ {subtitle && <div className={`BunError-error-subtitle`}>{subtitle}</div>}
+
+ {message.data.location && (
+ <BuildErrorStackTrace location={message.data.location} />
+ )}
+ </div>
+ );
+};
+const OverlayMessageContainer = ({
+ problems,
+ reason,
+ router,
+}: FallbackMessageContainer) => {
+ return (
+ <div id="BunErrorOverlay-container">
+ <div className="BunError-content">
+ <div className="BunError-header">
+ <Summary
+ errorCount={problems.exceptions.length + problems.build.errors}
+ onClose={onClose}
+ problems={problems}
+ reason={reason}
+ />
+ </div>
+ <div className={`BunError-list`}>
+ {problems.exceptions.map((problem, index) => (
+ <JSException key={index} value={problem} />
+ ))}
+ {problems.build.msgs.map((buildMessage, index) => {
+ if (buildMessage.on.build) {
+ return <BuildError key={index} message={buildMessage} />;
+ } else if (buildMessage.on.resolve) {
+ return <ResolveError key={index} message={buildMessage} />;
+ } else {
+ throw new Error("Unknown build message type");
+ }
+ })}
+ </div>
+ <div className="BunError-footer">
+ <div id="BunError-poweredBy"></div>
+ </div>
+ </div>
+ </div>
+ );
+};
+
+const BuildFailureMessageContainer = ({
+ messages,
+}: {
+ messages: Message[];
+}) => {
+ return (
+ <div id="BunErrorOverlay-container">
+ <div className="BunError-content">
+ <div className="BunError-header">
+ <Summary onClose={onClose} errorCount={messages.length} />
+ </div>
+ <div className={`BunError-list`}>
+ {messages.map((buildMessage, index) => {
+ if (buildMessage.on.build) {
+ return <BuildError key={index} message={buildMessage} />;
+ } else if (buildMessage.on.resolve) {
+ return <ResolveError key={index} message={buildMessage} />;
+ } else {
+ throw new Error("Unknown build message type");
+ }
+ })}
+ </div>
+ <div className="BunError-footer">
+ <div id="BunError-poweredBy"></div>
+ </div>
+ </div>
+ </div>
+ );
+};
+
+const ErrorGroupContext = createContext<{ cwd: string }>(null);
+var reactRoot;
+
+function renderWithFunc(func) {
+ if (!reactRoot) {
+ const root = document.createElement("div");
+ root.id = "__bun__error-root";
+
+ reactRoot = document.createElement("div");
+ reactRoot.id = BUN_ERROR_CONTAINER_ID;
+ reactRoot.style.visibility = "hidden";
+ const link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.href = new URL("/bun:erro.css", document.baseURI).href;
+ link.onload = () => {
+ reactRoot.style.visibility = "visible";
+ };
+
+ const shadowRoot = root.attachShadow({ mode: "open" });
+ shadowRoot.appendChild(link);
+ shadowRoot.appendChild(reactRoot);
+
+ document.body.appendChild(root);
+ ReactDOM.render(func(), reactRoot);
+
+ debugger;
+ } else {
+ ReactDOM.render(func(), reactRoot);
+ }
+}
+
+export function renderFallbackError(fallback: FallbackMessageContainer) {
+ return renderWithFunc(() => (
+ <ErrorGroupContext.Provider value={fallback}>
+ <OverlayMessageContainer {...fallback} />
+ </ErrorGroupContext.Provider>
+ ));
+}
+
+export function dismissError() {
+ if (reactRoot) {
+ ReactDOM.unmountComponentAtNode(reactRoot);
+ const root = document.getElementById("__bun__error-root");
+ if (root) root.remove();
+ reactRoot = null;
+ }
+}
+
+globalThis.renderBuildFailure = (
+ failure: WebsocketMessageBuildFailure,
+ cwd: string
+) => {
+ renderWithFunc(() => (
+ <ErrorGroupContext.Provider value={{ cwd }}>
+ <BuildFailureMessageContainer messages={failure.log.msgs} />
+ </ErrorGroupContext.Provider>
+ ));
+};
diff --git a/examples/hello-next/bun-framework-next/bun-error/close.png b/examples/hello-next/bun-framework-next/bun-error/close.png
new file mode 100644
index 000000000..11e513a1b
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/bun-error/close.png
Binary files differ
diff --git a/examples/hello-next/bun-framework-next/bun-error/error.png b/examples/hello-next/bun-framework-next/bun-error/error.png
new file mode 100644
index 000000000..c35e01a2b
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/bun-error/error.png
Binary files differ
diff --git a/examples/hello-next/bun-framework-next/client.development.tsx b/examples/hello-next/bun-framework-next/client.development.tsx
new file mode 100644
index 000000000..0d019e175
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/client.development.tsx
@@ -0,0 +1,416 @@
+import "./bun-error";
+globalThis.global = globalThis;
+globalThis.Bun_disableCSSImports = true;
+
+import * as React from "react";
+var onlyChildPolyfill = React.Children.only;
+React.Children.only = function (children) {
+ if (children && typeof children === "object" && children.length == 1) {
+ return onlyChildPolyfill(children[0]);
+ }
+
+ return onlyChildPolyfill(children);
+};
+
+import * as ReactDOM from "react-dom";
+import App from "next/app";
+import mitt, { MittEmitter } from "next/dist/shared/lib/mitt";
+import { RouterContext } from "next/dist/shared/lib/router-context";
+import Router, {
+ AppComponent,
+ AppProps,
+ delBasePath,
+ hasBasePath,
+ PrivateRouteInfo,
+} from "next/dist/shared/lib/router/router";
+
+import * as NextRouteLoader from "next/dist/client/route-loader";
+import { isDynamicRoute } from "next/dist/shared/lib/router/utils/is-dynamic";
+import {
+ urlQueryToSearchParams,
+ assign,
+} from "next/dist/shared/lib/router/utils/querystring";
+import { setConfig } from "next/dist/shared/lib/runtime-config";
+import {
+ getURL,
+ loadGetInitialProps,
+ NEXT_DATA,
+ ST,
+} from "next/dist/shared/lib/utils";
+// import { Portal } from "next/dist/client/portal";
+import initHeadManager from "next/dist/client/head-manager";
+import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context";
+import PageLoader from "./page-loader";
+import measureWebVitals from "next/dist/client/performance-relayer";
+import { RouteAnnouncer } from "next/dist/client/route-announcer";
+import {
+ createRouter,
+ makePublicRouterInstance,
+} from "next/dist/client/router";
+export const emitter: MittEmitter<string> = mitt();
+
+declare global {
+ interface Window {
+ /* test fns */
+ __NEXT_HYDRATED?: boolean;
+ __NEXT_HYDRATED_CB?: () => void;
+
+ /* prod */
+ __NEXT_PRELOADREADY?: (ids?: (string | number)[]) => void;
+ __NEXT_DATA__: NEXT_DATA;
+ __NEXT_P: any[];
+ }
+}
+
+function nextDataFromBunData() {
+ const {
+ router: { routes, route, params: paramsList },
+ problems,
+ } = globalThis.__BUN_DATA__;
+
+ const paramsMap = new Map();
+ for (let i = 0; i < paramsList.keys.length; i++) {
+ paramsMap.set(
+ decodeURIComponent(paramsList.keys[i]),
+ decodeURIComponent(paramsList.values[i])
+ );
+ }
+
+ const params = {};
+ var url = new URL(location.href);
+ Object.assign(params, Object.fromEntries(url.searchParams.entries()));
+ Object.assign(params, Object.fromEntries(paramsMap.entries()));
+
+ const pages = routes.reduce((acc, route) => {
+ var name = route.substring(route.indexOf("_next") + "_next/".length);
+
+ while (name.startsWith("/")) {
+ name = name.substring(1);
+ }
+
+ if (name.startsWith("pages")) {
+ name = name.substring("pages".length);
+ }
+
+ while (name.startsWith("/")) {
+ name = name.substring(1);
+ }
+
+ if (name.endsWith(".jsx")) {
+ name = name.substring(0, name.length - ".jsx".length);
+ }
+
+ if (name.endsWith(".tsx")) {
+ name = name.substring(0, name.length - ".tsx".length);
+ }
+
+ if (name.endsWith(".ts")) {
+ name = name.substring(0, name.length - ".ts".length);
+ }
+
+ if (name.endsWith(".js")) {
+ name = name.substring(0, name.length - ".js".length);
+ }
+
+ acc["/" + name] = [route];
+ return acc;
+ }, {});
+
+ return {
+ page: routes[route],
+ buildId: "1234",
+ assetPrefix: "",
+ isPreview: false,
+ locale: null,
+ locales: [],
+ isFallback: false,
+ err: null,
+ props: {},
+ query: params,
+ pages,
+ };
+}
+
+type RenderRouteInfo = PrivateRouteInfo & {
+ App: AppComponent;
+ scroll?: { x: number; y: number } | null;
+};
+type RenderErrorProps = Omit<RenderRouteInfo, "Component" | "styleSheets">;
+
+const nextDataTag = document.getElementById("__NEXT_DATA__");
+
+const data: typeof window["__NEXT_DATA__"] = nextDataTag
+ ? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!)
+ : nextDataFromBunData();
+window.__NEXT_DATA__ = data;
+
+const {
+ props: hydrateProps,
+ err: hydrateErr,
+ page,
+ query,
+ buildId,
+ assetPrefix,
+ runtimeConfig,
+ dynamicIds,
+ isFallback,
+ locale,
+ locales,
+ domainLocales,
+ isPreview,
+} = data;
+
+const prefix: string = assetPrefix || "";
+
+setConfig({
+ serverRuntimeConfig: {},
+ publicRuntimeConfig: runtimeConfig || {},
+});
+
+let asPath: string = getURL();
+
+// make sure not to attempt stripping basePath for 404s
+if (hasBasePath(asPath)) {
+ asPath = delBasePath(asPath);
+}
+
+export const pageLoader: PageLoader = new PageLoader(
+ buildId,
+ prefix,
+ data.pages
+);
+
+const headManager: {
+ mountedInstances: Set<unknown>;
+ updateHead: (head: JSX.Element[]) => void;
+} = initHeadManager();
+const appElement: HTMLElement | null = document.getElementById("__next");
+
+let lastRenderReject: (() => void) | null;
+let webpackHMR: any;
+export let router: Router;
+let CachedApp: AppComponent, onPerfEntry: (metric: any) => void;
+
+export default function boot(EntryPointNamespace, loader) {
+ _boot(EntryPointNamespace).then(() => {}, false);
+}
+
+class Container extends React.Component<{
+ fn: (err: Error, info?: any) => void;
+}> {
+ componentDidCatch(componentErr: Error, info: any) {
+ this.props.fn(componentErr, info);
+ }
+
+ componentDidMount() {
+ this.scrollToHash();
+
+ // We need to replace the router state if:
+ // - the page was (auto) exported and has a query string or search (hash)
+ // - it was auto exported and is a dynamic route (to provide params)
+ // - if it is a client-side skeleton (fallback render)
+ if (
+ router.isSsr &&
+ // We don't update for 404 requests as this can modify
+ // the asPath unexpectedly e.g. adding basePath when
+ // it wasn't originally present
+ page !== "/404" &&
+ page !== "/_error" &&
+ (isFallback ||
+ (data.nextExport &&
+ (isDynamicRoute(router.pathname) ||
+ location.search ||
+ process.env.__NEXT_HAS_REWRITES)) ||
+ (hydrateProps &&
+ hydrateProps.__N_SSG &&
+ (location.search || process.env.__NEXT_HAS_REWRITES)))
+ ) {
+ // update query on mount for exported pages
+ router.replace(
+ router.pathname +
+ "?" +
+ String(
+ assign(
+ urlQueryToSearchParams(router.query),
+ new URLSearchParams(location.search)
+ )
+ ),
+ asPath,
+ {
+ // @ts-ignore
+ // WARNING: `_h` is an internal option for handing Next.js
+ // client-side hydration. Your app should _never_ use this property.
+ // It may change at any time without notice.
+ _h: 1,
+ // Fallback pages must trigger the data fetch, so the transition is
+ // not shallow.
+ // Other pages (strictly updating query) happens shallowly, as data
+ // requirements would already be present.
+ shallow: !isFallback,
+ }
+ );
+ }
+ }
+
+ componentDidUpdate() {
+ this.scrollToHash();
+ }
+
+ scrollToHash() {
+ let { hash } = location;
+ hash = hash && hash.substring(1);
+ if (!hash) return;
+
+ const el: HTMLElement | null = document.getElementById(hash);
+ if (!el) return;
+
+ // If we call scrollIntoView() in here without a setTimeout
+ // it won't scroll properly.
+ setTimeout(() => el.scrollIntoView(), 0);
+ }
+
+ render() {
+ return this.props.children;
+ }
+}
+
+let CachedComponent: React.ComponentType;
+
+const wrapApp =
+ (App: AppComponent) =>
+ (wrappedAppProps: Record<string, any>): JSX.Element => {
+ const appProps: AppProps = {
+ ...wrappedAppProps,
+ Component: CachedComponent,
+ err: hydrateErr,
+ router,
+ };
+ return (
+ <AppContainer>
+ <App {...appProps} />
+ </AppContainer>
+ );
+ };
+
+function AppContainer({
+ children,
+}: React.PropsWithChildren<{}>): React.ReactElement {
+ return (
+ <Container fn={(error) => <div>{JSON.stringify(error)}</div>}>
+ <RouterContext.Provider value={makePublicRouterInstance(router)}>
+ <HeadManagerContext.Provider value={headManager}>
+ {children}
+ </HeadManagerContext.Provider>
+ </RouterContext.Provider>
+ </Container>
+ );
+}
+
+export async function _boot(EntryPointNamespace, isError) {
+ NextRouteLoader.default.getClientBuildManifest = () => Promise.resolve({});
+
+ const PageComponent = EntryPointNamespace.default;
+
+ const appScripts = globalThis.__NEXT_DATA__.pages["/_app"];
+ if (appScripts && appScripts.length > 0) {
+ let appSrc;
+ for (let asset of appScripts) {
+ if (!asset.endsWith(".css")) {
+ appSrc = asset;
+ break;
+ }
+ }
+
+ if (appSrc) {
+ const AppModule = await import(appSrc);
+ console.assert(
+ AppModule.default,
+ appSrc + " must have a default export'd React component"
+ );
+
+ CachedApp = AppModule.default;
+ } else {
+ CachedApp = App;
+ }
+ }
+
+ router = createRouter(page, query, asPath, {
+ initialProps: hydrateProps,
+ pageLoader,
+ App: CachedApp,
+ Component: CachedComponent,
+ wrapApp,
+ err: null,
+ isFallback: Boolean(isFallback),
+ subscription: async (info, App, scroll) => {
+ return render(
+ Object.assign<
+ {},
+ Omit<RenderRouteInfo, "App" | "scroll">,
+ Pick<RenderRouteInfo, "App" | "scroll">
+ >({}, info, {
+ App,
+ scroll,
+ })
+ );
+ },
+ locale,
+ locales,
+ defaultLocale: "",
+ domainLocales,
+ isPreview,
+ });
+
+ globalThis.next.router = router;
+
+ if (isError) {
+ ReactDOM.render(
+ <TopLevelRender
+ App={CachedApp}
+ Component={PageComponent}
+ props={{ pageProps: hydrateProps }}
+ />,
+ document.querySelector("#__next")
+ );
+ } else {
+ ReactDOM.hydrate(
+ <TopLevelRender
+ App={CachedApp}
+ Component={PageComponent}
+ props={{ pageProps: hydrateProps }}
+ />,
+ document.querySelector("#__next")
+ );
+ }
+}
+
+function TopLevelRender({ App, Component, props, scroll }) {
+ return (
+ <AppContainer scroll={scroll}>
+ <App Component={Component} {...props}></App>
+ </AppContainer>
+ );
+}
+
+export function render(props) {
+ ReactDOM.render(
+ <TopLevelRender {...props} />,
+ document.querySelector("#__next")
+ );
+}
+
+export function renderError(e) {
+ ReactDOM.render(
+ <AppContainer>
+ <App Component={<div>UH OH!!!!</div>} pageProps={data.props}></App>
+ </AppContainer>,
+ document.querySelector("#__next")
+ );
+}
+
+globalThis.next = {
+ version: "11.1.0",
+ emitter,
+ render,
+ renderError,
+};
diff --git a/examples/hello-next/bun-framework-next/fallback.development.tsx b/examples/hello-next/bun-framework-next/fallback.development.tsx
new file mode 100644
index 000000000..1cd5f847e
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/fallback.development.tsx
@@ -0,0 +1,82 @@
+import { insertStyleSheet } from "./page-loader";
+import type {
+ FallbackMessageContainer,
+ FallbackStep,
+} from "../../../src/api/schema";
+
+var once = false;
+function insertGlobalStyleSheet(detail) {
+ if (!once) {
+ document.head.insertAdjacentHTML(
+ "beforeend",
+ `<meta name="next-head-count" content="${document.head.childElementCount}">`
+ );
+ once = true;
+ }
+ pageLoader.cssQueue.push(insertStyleSheet(detail).then(() => {}));
+}
+
+[...globalThis["__BUN"].allImportedStyles].map((detail) =>
+ insertGlobalStyleSheet(detail)
+);
+
+document.addEventListener("onimportcss", insertGlobalStyleSheet, {
+ passive: true,
+});
+
+import { renderError, _boot, pageLoader } from "./client.development";
+import { renderFallbackError } from "bun-error";
+
+function renderFallback({
+ router,
+ reason,
+ problems,
+}: FallbackMessageContainer) {
+ const route = router.routes[router.route];
+
+ if (!document.getElementById("__next")) {
+ const next = document.createElement("div");
+ next.id = "__next";
+ document.body.prepend(next);
+ }
+
+ document.removeEventListener("onimportcss", insertGlobalStyleSheet);
+ document.addEventListener("onimportcss", pageLoader.onImportCSS, {
+ passive: true,
+ });
+
+ globalThis.__NEXT_DATA__.pages["/_app"] = [
+ ...globalThis.__NEXT_DATA__.pages["/_app"],
+ ...globalThis["__BUN"].allImportedStyles,
+ ];
+
+ return import(route)
+ .then((Namespace) => {
+ return _boot(Namespace, true);
+ })
+ .then(() => {
+ const cssQueue = pageLoader.cssQueue.slice();
+ pageLoader.cssQueue = [];
+ return Promise.all([...cssQueue]);
+ })
+ .finally(() => {
+ document.body.style.visibility = "visible";
+ document.removeEventListener("onimportcss", pageLoader.onImportCSS);
+ });
+}
+
+export default function render(props: FallbackMessageContainer) {
+ renderFallback(props).then(
+ () => {
+ Promise.all(pageLoader.cssQueue).finally(() => {
+ renderFallbackError(props);
+ document.body.style.visibility = "visible";
+ });
+ },
+ (err) => {
+ Promise.all(pageLoader.cssQueue).finally(() => {
+ renderFallbackError(props);
+ });
+ }
+ );
+}
diff --git a/examples/hello-next/bun-framework-next/index.js b/examples/hello-next/bun-framework-next/index.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/index.js
diff --git a/examples/hello-next/bun-framework-next/next-server.tsx b/examples/hello-next/bun-framework-next/next-server.tsx
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/next-server.tsx
diff --git a/examples/hello-next/bun-framework-next/package.json b/examples/hello-next/bun-framework-next/package.json
new file mode 100644
index 000000000..af6286343
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "bun-framework-next",
+ "version": "0.0.0-18",
+ "description": "",
+ "framework": {
+ "displayName": "Next.js",
+ "static": "public",
+ "assetPrefix": "_next/",
+ "router": {
+ "dir": [
+ "pages",
+ "src/pages"
+ ],
+ "extensions": [
+ ".js",
+ ".ts",
+ ".tsx",
+ ".jsx"
+ ]
+ },
+ "css": "onimportcss",
+ "development": {
+ "client": "client.development.tsx",
+ "fallback": "fallback.development.tsx",
+ "server": "server.development.tsx",
+ "css": "onimportcss",
+ "define": {
+ "client": {
+ ".env": "NEXT_PUBLIC_",
+ "defaults": {
+ "process.env.__NEXT_TRAILING_SLASH": "false",
+ "process.env.NODE_ENV": "\"development\"",
+ "process.env.__NEXT_ROUTER_BASEPATH": "''",
+ "process.env.__NEXT_SCROLL_RESTORATION": "false",
+ "process.env.__NEXT_I18N_SUPPORT": "false",
+ "process.env.__NEXT_HAS_REWRITES": "false",
+ "process.env.__NEXT_ANALYTICS_ID": "null",
+ "process.env.__NEXT_OPTIMIZE_CSS": "false",
+ "process.env.__NEXT_CROSS_ORIGIN": "''",
+ "process.env.__NEXT_STRICT_MODE": "false",
+ "process.env.__NEXT_IMAGE_OPTS": "null"
+ }
+ },
+ "server": {
+ ".env": "NEXT_",
+ "defaults": {
+ "process.env.__NEXT_TRAILING_SLASH": "false",
+ "process.env.__NEXT_OPTIMIZE_FONTS": "false",
+ "process.env.NODE_ENV": "\"development\"",
+ "process.env.__NEXT_OPTIMIZE_IMAGES": "false",
+ "process.env.__NEXT_OPTIMIZE_CSS": "false",
+ "process.env.__NEXT_ROUTER_BASEPATH": "''",
+ "process.env.__NEXT_SCROLL_RESTORATION": "false",
+ "process.env.__NEXT_I18N_SUPPORT": "false",
+ "process.env.__NEXT_HAS_REWRITES": "false",
+ "process.env.__NEXT_ANALYTICS_ID": "null",
+ "process.env.__NEXT_CROSS_ORIGIN": "''",
+ "process.env.__NEXT_STRICT_MODE": "false",
+ "process.env.__NEXT_IMAGE_OPTS": "null",
+ "global": "globalThis",
+ "window": "undefined"
+ }
+ }
+ }
+ },
+ "production": {
+ "client": "client.production.tsx",
+ "server": "server.production.tsx",
+ "fallback": "fallback.production.tsx",
+ "css": "onimportcss"
+ }
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "react-is": "^17.0.2"
+ }
+}
diff --git a/examples/hello-next/bun-framework-next/page-loader.ts b/examples/hello-next/bun-framework-next/page-loader.ts
new file mode 100644
index 000000000..fc07578db
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/page-loader.ts
@@ -0,0 +1,147 @@
+import NextPageLoader from "next/dist/client/page-loader";
+import getAssetPathFromRoute from "next/dist/shared/lib/router/utils/get-asset-path-from-route";
+// import createRouteLoader from "./route-loader";
+
+export function insertStyleSheet(url: string) {
+ if (document.querySelector(`link[href="${url}"]`)) {
+ return Promise.resolve();
+ }
+
+ return new Promise((resolve, reject) => {
+ const link = document.createElement("link");
+ link.rel = "stylesheet";
+
+ link.onload = () => resolve();
+ link.onerror = () => reject();
+
+ link.href = url;
+
+ // if (headCount) {
+ // document.head.insertBefore(headCount, link);
+ // } else {
+ document.head.appendChild(link);
+ // }
+ });
+}
+
+export default class PageLoader extends NextPageLoader {
+ public routeLoader: RouteLoader;
+
+ constructor(_, __, pages) {
+ super(_, __);
+
+ // TODO: assetPrefix?
+ // this.routeLoader = {}; //createRouteLoader("");
+
+ // Rewrite the pages object to omit the entry script
+ // At this point, the entry point has been loaded so we don't want to do that again.
+ for (let name in pages) {
+ for (let i = 0; i < pages[name].length; i += 1) {
+ const lastDot = pages[name][i].lastIndexOf(".");
+ if (lastDot == -1) continue;
+ if (
+ pages[name][i].substring(lastDot - ".entry".length, lastDot) !==
+ ".entry"
+ )
+ continue;
+
+ pages[name][i] =
+ pages[name][i].substring(0, lastDot - ".entry".length) +
+ pages[name][i].substring(lastDot);
+ }
+ }
+
+ this.pages = pages;
+ this.pageList = Object.keys(this.pages);
+ }
+
+ pageList: string[];
+ pages: Record<string, string[]>;
+
+ getPageList() {
+ return this.pageList;
+ }
+
+ cssQueue = [];
+
+ onImportCSS = (event) => {
+ this.cssQueue.push(
+ insertStyleSheet(event.detail).then(
+ () => {},
+ () => {}
+ )
+ );
+ };
+
+ prefetch(route) {
+ return Promise.resolve({});
+ }
+
+ async loadPage(route: string): Promise<GoodPageCache> {
+ const assets =
+ this.pages[route] || this.pages[getAssetPathFromRoute(route)];
+
+ var src;
+ console.log(getAssetPathFromRoute(route), assets);
+ for (let asset of assets) {
+ if (!asset.endsWith(".css")) {
+ src = asset;
+ break;
+ }
+ }
+ console.assert(src, "Invalid or unknown route passed to loadPage");
+
+ document.removeEventListener("onimportcss", this.onImportCSS);
+ this.cssQueue.length = 0;
+ document.addEventListener("onimportcss", this.onImportCSS, {
+ passive: true,
+ });
+
+ try {
+ const res = await import(src);
+
+ if (this.cssQueue.length > 0) {
+ await Promise.all(this.cssQueue);
+ this.cssQueue.length = 0;
+ }
+
+ document.removeEventListener("onimportcss", this.onImportCSS);
+
+ if (this.cssQueue.length > 0) {
+ await Promise.all(this.cssQueue);
+
+ this.cssQueue.length = 0;
+ }
+
+ return {
+ page: res.default,
+ mod: res,
+ styleSheets: [],
+ __N_SSG: false,
+ __N_SSP: false,
+ };
+ } catch (exception) {
+ console.error({ exception });
+ }
+
+ // return this.routeLoader.loadRoute(route).then((res) => {
+ // debugger;
+ // if ("component" in res) {
+ // return {
+ // page: res.component,
+ // mod: res.exports,
+ // styleSheets: res.styles.map((o) => ({
+ // href: o.href,
+ // text: o.content,
+ // })),
+ // };
+ // }
+ // throw res.error;
+ // });
+ }
+
+ // not used in development!
+ // prefetch(route: string): Promise<void> {
+ // return this.routeLoader.prefetch(route);
+ // }
+}
diff --git a/examples/hello-next/bun-framework-next/render.tsx b/examples/hello-next/bun-framework-next/render.tsx
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/render.tsx
diff --git a/examples/hello-next/bun-framework-next/renderDocument.tsx b/examples/hello-next/bun-framework-next/renderDocument.tsx
new file mode 100644
index 000000000..356ff788b
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/renderDocument.tsx
@@ -0,0 +1,722 @@
+import * as App from "next/app";
+import { AmpStateContext } from "next/dist/shared/lib/amp-context";
+import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context";
+import Loadable from "next/dist/shared/lib/loadable";
+import { LoadableContext } from "next/dist/shared/lib/loadable-context";
+import { RouterContext } from "next/dist/shared/lib/router-context";
+import { NextRouter } from "next/dist/shared/lib/router/router";
+import {
+ AppType,
+ ComponentsEnhancer,
+ DocumentInitialProps,
+ DocumentProps,
+ DocumentType,
+ getDisplayName,
+ loadGetInitialProps,
+ NextComponentType,
+ RenderPage,
+ RenderPageResult,
+ HtmlContext,
+} from "next/dist/shared/lib/utils";
+import * as NextDocument from "next/document";
+import * as ReactDOMServer from "react-dom/server.browser";
+import * as url from "url";
+import * as React from "react";
+import * as ReactIs from "react-is";
+import { BODY_RENDER_TARGET } from "next/constants";
+
+const dev = process.env.NODE_ENV === "development";
+
+type ParsedUrlQuery = Record<string, string | string[]>;
+
+const isJSFile = (file: string) =>
+ file.endsWith(".js") ||
+ file.endsWith(".jsx") ||
+ file.endsWith(".mjs") ||
+ file.endsWith(".ts") ||
+ file.endsWith(".tsx");
+
+const notImplementedProxy = (base) =>
+ new Proxy(
+ {},
+ {
+ deleteProperty: function (target, prop) {
+ return undefined;
+ },
+ enumerate: function (oTarget, sKey) {
+ return [].entries();
+ },
+ ownKeys: function (oTarget, sKey) {
+ return [].values();
+ },
+ has: function (oTarget, sKey) {
+ return false;
+ },
+ defineProperty: function (oTarget, sKey, oDesc) {
+ return undefined;
+ },
+ getOwnPropertyDescriptor: function (oTarget, sKey) {
+ return undefined;
+ },
+ get(this, prop) {
+ throw new ReferenceError(
+ `${base} is not available for this environment.`
+ );
+ },
+ set(this, prop, value) {
+ throw new ReferenceError(
+ `${base} is not available for this environment.`
+ );
+ },
+ }
+ );
+
+globalThis.fetch = (url, options) => {
+ return Promise.reject(new Error(`fetch is not implemented yet. sorry!!`));
+};
+
+function getScripts(files: DocumentFiles) {
+ const { context, props } = this;
+ const {
+ assetPrefix,
+ buildManifest,
+ isDevelopment,
+ devOnlyCacheBusterQueryString,
+ disableOptimizedLoading,
+ } = context;
+ const normalScripts = files.allFiles.filter(isJSFile);
+ const lowPriorityScripts = buildManifest.lowPriorityFiles?.filter(isJSFile);
+
+ return [...normalScripts, ...lowPriorityScripts].map((file) => {
+ return (
+ <script
+ key={file}
+ src={`${encodeURI(file)}${devOnlyCacheBusterQueryString}`}
+ nonce={props.nonce}
+ async
+ crossOrigin={props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN}
+ type="module"
+ />
+ );
+ });
+}
+
+// function fixLink(from: string) {
+// if (from.startsWith("/_next/http://") || from.startsWith("/_next/https://"))
+// return from.substring("/_next".length);
+// return from;
+// }
+
+// function cloneWithOverwrittenLink(element: React.ReactElement<any>) {
+// const props = { ...element.props };
+// if ("href" in element.props) {
+// props.href = fixLink(props.href);
+// }
+
+// if ("n-href" in element.props) {
+// props["n-href"] = fixLink(props["n-href"]);
+// }
+
+// if ("n-src" in element.props) {
+// props["n-src"] = fixLink(props["n-src"]);
+// }
+
+// if ("src" in element.props) {
+// props["src"] = fixLink(props.src);
+// }
+
+// return React.cloneElement(element, props);
+// }
+
+interface DomainLocale {
+ defaultLocale: string;
+ domain: string;
+ http?: true;
+ locales?: string[];
+}
+
+function renderDocument(
+ Document: DocumentType,
+ {
+ buildManifest,
+ docComponentsRendered,
+ props,
+ docProps,
+ pathname,
+ query,
+ buildId,
+ canonicalBase,
+ assetPrefix,
+ runtimeConfig,
+ nextExport,
+ autoExport,
+ isFallback,
+ dynamicImportsIds,
+ dangerousAsPath,
+ err,
+ dev,
+ ampPath,
+ ampState,
+ inAmpMode,
+ hybridAmp,
+ dynamicImports,
+ headTags,
+ gsp,
+ gssp,
+ customServer,
+ gip,
+ appGip,
+ unstable_runtimeJS,
+ unstable_JsPreload,
+ devOnlyCacheBusterQueryString,
+ scriptLoader,
+ locale,
+ locales,
+ defaultLocale,
+ domainLocales,
+ isPreview,
+ disableOptimizedLoading,
+ }: RenderOpts & {
+ props: any;
+ docComponentsRendered: DocumentProps["docComponentsRendered"];
+ docProps: DocumentInitialProps;
+ pathname: string;
+ query: ParsedUrlQuery;
+ dangerousAsPath: string;
+ ampState: any;
+ ampPath: string;
+ inAmpMode: boolean;
+ hybridAmp: boolean;
+ dynamicImportsIds: (string | number)[];
+ dynamicImports: string[];
+ headTags: any;
+ isFallback?: boolean;
+ gsp?: boolean;
+ gssp?: boolean;
+ customServer?: boolean;
+ gip?: boolean;
+ appGip?: boolean;
+ devOnlyCacheBusterQueryString: string;
+ scriptLoader: any;
+ isPreview?: boolean;
+ autoExport?: boolean;
+ }
+): string {
+ const htmlProps = {
+ __NEXT_DATA__: {
+ props, // The result of getInitialProps
+ page: pathname, // The rendered page
+ query, // querystring parsed / passed by the user
+ buildId, // buildId is used to facilitate caching of page bundles, we send it to the client so that pageloader knows where to load bundles
+ assetPrefix: assetPrefix === "" ? undefined : assetPrefix, // send assetPrefix to the client side when configured, otherwise don't sent in the resulting HTML
+ runtimeConfig, // runtimeConfig if provided, otherwise don't sent in the resulting HTML
+ nextExport, // If this is a page exported by `next export`
+ autoExport, // If this is an auto exported page
+ isFallback,
+ dynamicIds:
+ dynamicImportsIds.length === 0 ? undefined : dynamicImportsIds,
+ err: err || undefined, // err: err ? serializeError(dev, err) : undefined, // Error if one happened, otherwise don't sent in the resulting HTML
+ gsp, // whether the page is getStaticProps
+ gssp, // whether the page is getServerSideProps
+ customServer, // whether the user is using a custom server
+ gip, // whether the page has getInitialProps
+ appGip, // whether the _app has getInitialProps
+ locale,
+ locales,
+ defaultLocale,
+ domainLocales,
+ isPreview,
+
+ pages: buildManifest.pages,
+ },
+ buildManifest,
+ docComponentsRendered,
+ dangerousAsPath,
+ canonicalBase,
+ ampPath,
+ inAmpMode,
+ isDevelopment: !!dev,
+ hybridAmp,
+ dynamicImports,
+ assetPrefix,
+ headTags,
+ unstable_runtimeJS,
+ unstable_JsPreload,
+ devOnlyCacheBusterQueryString,
+ scriptLoader,
+ locale,
+ disableOptimizedLoading,
+ ...docProps,
+ };
+ return (
+ "<!DOCTYPE html>" +
+ ReactDOMServer.renderToStaticMarkup(
+ <AmpStateContext.Provider value={ampState}>
+ <HtmlContext.Provider value={htmlProps}>
+ <Document {...htmlProps} {...docProps}></Document>
+ </HtmlContext.Provider>
+ </AmpStateContext.Provider>
+ )
+ );
+}
+
+class ServerRouter implements NextRouter {
+ route: string;
+ pathname: string;
+ query: ParsedUrlQuery;
+ asPath: string;
+ basePath: string;
+ events: any;
+ isFallback: boolean;
+ locale?: string;
+ isReady: boolean;
+ locales?: string[];
+ defaultLocale?: string;
+ domainLocales?: DomainLocale[];
+ isPreview: boolean;
+ isLocaleDomain: boolean;
+
+ constructor(
+ pathname: string,
+ query: ParsedUrlQuery,
+ as: string,
+ { isFallback }: { isFallback: boolean },
+ isReady: boolean,
+ basePath: string,
+ locale?: string,
+ locales?: string[],
+ defaultLocale?: string,
+ domainLocales?: DomainLocale[],
+ isPreview?: boolean,
+ isLocaleDomain?: boolean
+ ) {
+ this.route = pathname.replace(/\/$/, "") || "/";
+ this.pathname = pathname;
+ this.query = query;
+ this.asPath = as;
+ this.isFallback = isFallback;
+ this.basePath = basePath;
+ this.locale = locale;
+ this.locales = locales;
+ this.defaultLocale = defaultLocale;
+ this.isReady = isReady;
+ this.domainLocales = domainLocales;
+ this.isPreview = !!isPreview;
+ this.isLocaleDomain = !!isLocaleDomain;
+ }
+
+ push(): any {
+ noRouter();
+ }
+ replace(): any {
+ noRouter();
+ }
+ reload() {
+ noRouter();
+ }
+ back() {
+ noRouter();
+ }
+ prefetch(): any {
+ noRouter();
+ }
+ beforePopState() {
+ noRouter();
+ }
+}
+
+function noRouter() {
+ const message =
+ 'No router instance found. you should only use "next/router" inside the client side of your app. https://nextjs.org/docs/messages/no-router-instance';
+ throw new Error(message);
+}
+
+function enhanceComponents(
+ options: ComponentsEnhancer,
+ App: AppType,
+ Component: NextComponentType
+): {
+ App: AppType;
+ Component: NextComponentType;
+} {
+ // For backwards compatibility
+ if (typeof options === "function") {
+ return {
+ App,
+ Component: options(Component),
+ };
+ }
+
+ return {
+ App: options.enhanceApp ? options.enhanceApp(App) : App,
+ Component: options.enhanceComponent
+ ? options.enhanceComponent(Component)
+ : Component,
+ };
+}
+
+Object.defineProperty(NextDocument.Head.prototype, "getScripts", {
+ get() {
+ return getScripts;
+ },
+});
+Object.defineProperty(NextDocument.NextScript.prototype, "getScripts", {
+ get() {
+ return getScripts;
+ },
+});
+
+export async function render({
+ route,
+ PageNamespace,
+ AppNamespace,
+ appStylesheets = [],
+ pageStylesheets = [],
+ DocumentNamespace = null,
+ buildId,
+ routePaths = [],
+}: {
+ buildId: number;
+ route: any;
+ PageNamespace: { default: NextComponentType<any> };
+ AppNamespace: { default: NextComponentType<any> } | null;
+ DocumentNamespace: Object | null;
+ appStylesheets: string[];
+ pageStylesheets: string[];
+ routePaths: string[];
+}): Promise<Response> {
+ const { default: Component, getStaticProps = null } = PageNamespace || {};
+ const { default: AppComponent_ } = AppNamespace || {};
+ var query = Object.assign({}, route.query);
+
+ // These are reversed in our Router versus Next.js...mostly due to personal preference.
+ const pathname = "/" + route.name;
+ var asPath = route.pathname;
+ const pages = {};
+
+ for (let path of routePaths) {
+ const filePath = path.substring(
+ path.indexOf("_next/pages/") + "_next/pages".length
+ );
+ const name = filePath.substring(0, filePath.indexOf("."));
+ pages[name] = [path];
+ }
+
+ pages[pathname] = [route.scriptSrc, ...pageStylesheets];
+
+ if (appStylesheets.length > 0) {
+ if (pages["/_app"]) {
+ pages["/_app"].push(...appStylesheets);
+ } else {
+ pages["/_app"] = appStylesheets;
+ }
+ }
+
+ const AppComponent = AppComponent_ || App.default;
+ const Document =
+ (DocumentNamespace && DocumentNamespace.default) || NextDocument.default;
+ // Document.Html.prototype.getScripts = getScripts;
+ // }
+
+ const callMiddleware = async (method: string, args: any[], props = false) => {
+ let results: any = props ? {} : [];
+
+ if ((Document as any)[`${method}Middleware`]) {
+ let middlewareFunc = await (Document as any)[`${method}Middleware`];
+ middlewareFunc = middlewareFunc.default || middlewareFunc;
+
+ const curResults = await middlewareFunc(...args);
+ if (props) {
+ for (const result of curResults) {
+ results = {
+ ...results,
+ ...result,
+ };
+ }
+ } else {
+ results = curResults;
+ }
+ }
+ return results;
+ };
+
+ const headTags = (...args: any) => callMiddleware("headTags", args);
+
+ if (!ReactIs.isValidElementType(Component)) {
+ const exportNames = Object.keys(PageNamespace || {});
+
+ const reactComponents = exportNames.filter(ReactIs.isValidElementType);
+ if (reactComponents.length > 2) {
+ throw new Error(
+ `\"export default\" missing in ${
+ route.filePath
+ }.\nTry exporting one of ${reactComponents.join(", ")}\n`
+ );
+ } else if (reactComponents.length === 2) {
+ throw new Error(
+ `\"export default\" missing in ${route.filePath}.\n\nTry exporting <${reactComponents[0]} /> or <${reactComponents[1]} />\n`
+ );
+ } else if (reactComponents.length == 1) {
+ throw new Error(
+ `\"export default\" missing in ${route.filePath}. Try adding this to the bottom of the file:\n\n export default ${reactComponents[0]};\n`
+ );
+ } else if (reactComponents.length == 0) {
+ throw new Error(
+ `\"export default\" missing in ${route.filePath}. Try exporting a React component.\n`
+ );
+ }
+ }
+
+ const isFallback = !!query.__nextFallback;
+ delete query.__nextFallback;
+ delete query.__nextLocale;
+ delete query.__nextDefaultLocale;
+
+ const isSSG = !!getStaticProps;
+ const isBuildTimeSSG = isSSG && false;
+ const defaultAppGetInitialProps =
+ App.getInitialProps === (App as any).origGetInitialProps;
+
+ const hasPageGetInitialProps = !!(Component as any).getInitialProps;
+ const pageIsDynamic = route.kind === "dynamic";
+ const isAutoExport = false;
+
+ if (isAutoExport || isFallback) {
+ // // remove query values except ones that will be set during export
+ // query = {
+ // ...(query.amp
+ // ? {
+ // amp: query.amp,
+ // }
+ // : {}),
+ // };
+ asPath = `${asPath}${
+ // ensure trailing slash is present for non-dynamic auto-export pages
+ asPath.endsWith("/") && asPath !== "/" && !pageIsDynamic ? "/" : ""
+ }`;
+ }
+
+ let head: JSX.Element[] = [
+ <meta charSet="utf-8" />,
+ <meta name="viewport" content="width=device-width" />,
+ ];
+
+ const nextExport = isAutoExport || isFallback;
+ const reactLoadableModules: string[] = [];
+ var scriptLoader = {};
+ const AppContainer = ({ children }: any) => (
+ <RouterContext.Provider value={router}>
+ {/* <AmpStateContext.Provider value={ampState}> */}
+ <HeadManagerContext.Provider
+ value={{
+ updateHead: (state) => {
+ head = state;
+ },
+ updateScripts: (scripts) => {
+ scriptLoader = scripts;
+ },
+ scripts: {},
+ mountedInstances: new Set(),
+ }}
+ >
+ <LoadableContext.Provider
+ value={(moduleName) => reactLoadableModules.push(moduleName)}
+ >
+ {children}
+ </LoadableContext.Provider>
+ </HeadManagerContext.Provider>
+ {/* </AmpStateContext.Provider> */}
+ </RouterContext.Provider>
+ );
+
+ await Loadable.preloadAll(); // Make sure all dynamic imports are loaded
+
+ const router = new ServerRouter(
+ pathname,
+ query,
+ asPath,
+ {
+ isFallback: isFallback,
+ },
+ true,
+ Bun.origin,
+ null,
+ [], // renderOpts.locales,
+ null, //renderOpts.defaultLocale,
+ [], // renderOpts.domainLocales,
+ false,
+ false
+ );
+
+ const ctx = {
+ err: null,
+ req: undefined,
+ res: undefined,
+ pathname,
+ query,
+ asPath,
+ locale: null,
+ locales: [],
+ defaultLocale: null,
+ AppTree: (props: any) => {
+ return (
+ <AppContainer>
+ <App {...props} Component={Component} router={router} />
+ </AppContainer>
+ );
+ },
+ };
+
+ var props = await loadGetInitialProps(AppComponent, {
+ AppTree: ctx.AppTree,
+ Component,
+ router,
+ ctx,
+ });
+
+ // This isn't correct.
+ // We don't call getServerSideProps on clients.
+ const getServerSideProps = PageNamespace.getServerSideProps;
+ if (typeof getServerSideProps === "function") {
+ const result = await getServerSideProps({
+ params: route.params,
+ query: route.query,
+ req: notImplementedProxy("req"),
+ res: notImplementedProxy("res"),
+ resolvedUrl: route.pathname,
+ preview: false,
+ previewData: null,
+ locale: null,
+ locales: [],
+ defaultLocale: null,
+ });
+
+ if (result) {
+ if ("props" in result) {
+ if (typeof result.props === "object") {
+ Object.assign(props, result.props);
+ }
+ }
+ }
+ }
+
+ const renderToString = ReactDOMServer.renderToString;
+ const ErrorDebug = null;
+
+ const renderPage: RenderPage = (
+ options: ComponentsEnhancer = {}
+ ): RenderPageResult | Promise<RenderPageResult> => {
+ if (ctx.err && ErrorDebug) {
+ const htmlOrPromise = renderToString(<ErrorDebug error={ctx.err} />);
+ return typeof htmlOrPromise === "string"
+ ? { html: htmlOrPromise, head }
+ : htmlOrPromise.then((html) => ({
+ html,
+ head,
+ }));
+ }
+
+ if (dev && (props.router || props.Component)) {
+ throw new Error(
+ `'router' and 'Component' can not be returned in getInitialProps from _app.js https://nextjs.org/docs/messages/cant-override-next-props`
+ );
+ }
+
+ const { App: EnhancedApp, Component: EnhancedComponent } =
+ enhanceComponents(options, AppComponent, Component);
+
+ const htmlOrPromise = renderToString(
+ <AppContainer>
+ <EnhancedApp Component={EnhancedComponent} router={router} {...props} />
+ </AppContainer>
+ );
+ return typeof htmlOrPromise === "string"
+ ? { html: htmlOrPromise, head }
+ : htmlOrPromise.then((html) => ({
+ html,
+ head,
+ }));
+ };
+
+ const documentCtx = { ...ctx, renderPage };
+ const docProps: DocumentInitialProps = await loadGetInitialProps(
+ Document,
+ documentCtx
+ );
+
+ if (!docProps || typeof docProps.html !== "string") {
+ const message = `"${getDisplayName(
+ Document
+ )}.getInitialProps()" should resolve to an object with a "html" prop set with a valid html string`;
+ throw new Error(message);
+ }
+
+ const renderOpts = {
+ params: route.params,
+ };
+ // renderOpts.params = _params || params;
+
+ // parsedUrl.pathname = denormalizePagePath(parsedUrl.pathname!);
+ // renderOpts.resolvedUrl = formatUrl({
+ // ...parsedUrl,
+ // query: origQuery,
+ // });
+ const docComponentsRendered: DocumentProps["docComponentsRendered"] = {};
+
+ const isPreview = false;
+
+ let html = renderDocument(Document, {
+ docComponentsRendered,
+ ...renderOpts,
+ disableOptimizedLoading: false,
+ canonicalBase: Bun.origin,
+ buildManifest: {
+ devFiles: [],
+ allFiles: [],
+ polyfillFiles: [],
+ lowPriorityFiles: [],
+ pages: pages,
+ },
+ // Only enabled in production as development mode has features relying on HMR (style injection for example)
+ unstable_runtimeJS: true,
+ // process.env.NODE_ENV === "production"
+ // ? pageConfig.unstable_runtimeJS
+ // : undefined,
+ // unstable_JsPreload: pageConfig.unstable_JsPreload,
+ unstable_JsPreload: true,
+ dangerousAsPath: router.asPath,
+ ampState: undefined,
+ props,
+ assetPrefix: "",
+ headTags: await headTags(documentCtx),
+ isFallback,
+ docProps,
+ pathname,
+ ampPath: undefined,
+ query,
+ inAmpMode: false,
+ hybridAmp: undefined,
+ dynamicImportsIds: [], // Array.from(dynamicImportsIds),
+ dynamicImports: [], //Array.from(dynamicImports),
+ gsp: !!getStaticProps ? true : undefined,
+ gssp: !!getServerSideProps ? true : undefined,
+ gip: hasPageGetInitialProps ? true : undefined,
+ appGip: !defaultAppGetInitialProps ? true : undefined,
+ devOnlyCacheBusterQueryString: "",
+ scriptLoader,
+ isPreview: isPreview === true ? true : undefined,
+ autoExport: isAutoExport === true ? true : undefined,
+ nextExport: nextExport === true ? true : undefined,
+ });
+ const bodyRenderIdx = html.indexOf(BODY_RENDER_TARGET);
+ html =
+ html.substring(0, bodyRenderIdx) +
+ (false ? "<!-- __NEXT_DATA__ -->" : "") +
+ docProps.html +
+ html.substring(bodyRenderIdx + BODY_RENDER_TARGET.length);
+ return new Response(
+ html
+ .replaceAll("/_next/http://", "http://")
+ .replaceAll("/_next/https://", "https://")
+ );
+}
diff --git a/examples/hello-next/bun-framework-next/route-loader.ts b/examples/hello-next/bun-framework-next/route-loader.ts
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/route-loader.ts
diff --git a/examples/hello-next/bun-framework-next/server.development.tsx b/examples/hello-next/bun-framework-next/server.development.tsx
new file mode 100644
index 000000000..e3cd24e01
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/server.development.tsx
@@ -0,0 +1,79 @@
+import * as React from "react";
+import { Buffer } from "buffer";
+globalThis.Buffer = Buffer;
+
+class URL {
+ constructor(base, source) {
+ this.pathname = source;
+ this.href = base + source;
+ }
+}
+var onlyChildPolyfill = React.Children.only;
+React.Children.only = function (children) {
+ if (children && typeof children === "object" && children.length == 1) {
+ return onlyChildPolyfill(children[0]);
+ }
+
+ return onlyChildPolyfill(children);
+};
+globalThis.URL = URL;
+globalThis.global = globalThis;
+import { render } from "./renderDocument";
+
+let buildId = 0;
+
+var DocumentLoaded = false;
+var DocumentNamespace;
+
+import(Bun.routesDir + "_document").then(
+ (doc) => {
+ DocumentNamespace = doc;
+ DocumentLoaded = true;
+ },
+ (err) => {
+ if (err instanceof ResolveError) {
+ DocumentLoaded = true;
+ } else {
+ console.error(err);
+ }
+ }
+);
+
+addEventListener("fetch", async (event: FetchEvent) => {
+ var route = Bun.match(event);
+
+ // This imports the currently matched route.
+ const PageNamespace = await import(route.filePath);
+
+ // This returns all .css files that were imported in the line above.
+ // It's recursive, so any file that imports a CSS file will be included.
+ const pageStylesheets = (Bun.getImportedStyles() as string[]).slice();
+
+ var appRoute;
+
+ try {
+ appRoute = await import(Bun.routesDir + "_app");
+ } catch (exception) {
+ appRoute = null;
+ }
+ const appStylesheets = (Bun.getImportedStyles() as string[]).slice();
+
+ event.respondWith(
+ render({
+ route,
+ PageNamespace,
+ appStylesheets,
+ pageStylesheets,
+ DocumentNamespace,
+ AppNamespace: appRoute,
+ buildId,
+ routePaths: Bun.getRouteFiles(),
+ })
+ );
+ buildId++;
+});
+
+// typescript isolated modules
+export {};
+
+declare var Bun: any;
diff --git a/examples/hello-next/bun-framework-next/server.production.tsx b/examples/hello-next/bun-framework-next/server.production.tsx
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/server.production.tsx
diff --git a/examples/hello-next/bun-framework-next/tsconfig.json b/examples/hello-next/bun-framework-next/tsconfig.json
new file mode 100644
index 000000000..d14767c9f
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "lib": ["dom", "dom.iterable", "esnext", "WebWorker"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "baseUrl": ".",
+ "paths": {}
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/examples/hello-next/package.json b/examples/hello-next/package.json
index 77ce7b80e..aacc87742 100644
--- a/examples/hello-next/package.json
+++ b/examples/hello-next/package.json
@@ -6,9 +6,10 @@
"dependencies": {
"next": "^11.1.0",
"parcel": "2.0.0-rc.0",
- "path": "^0.12.7",
+ "path-browserify": "^1.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
+ "react-is": "^17.0.2",
"whatwg-url": "^9.1.0"
},
"devDependencies": {
diff --git a/examples/hello-next/pages/errortest.tsx b/examples/hello-next/pages/errortest.tsx
new file mode 100644
index 000000000..49a293df7
--- /dev/null
+++ b/examples/hello-next/pages/errortest.tsx
@@ -0,0 +1,14 @@
+import IndexPage from "pages/index";
+
+export default function ErrorTestPage() {
+ class Wow {}
+
+ const ladee = "",
+ foo = { bar: { boom: new Wow() } };
+
+ if (typeof window === "undefined") {
+ const Doge = import("wow/such-esm/very-import");
+ }
+
+ return <IndexPage />;
+}
diff --git a/examples/hello-next/pages/index.tsx b/examples/hello-next/pages/index.tsx
index dab661672..7a2eb9f64 100644
--- a/examples/hello-next/pages/index.tsx
+++ b/examples/hello-next/pages/index.tsx
@@ -3,10 +3,10 @@ import Image from "next/image";
import styles from "../styles/Home.module.css";
import Link from "next/link";
import { useRouter } from "next/router";
-import Title from "../components/Title";
+import Title, { TitleEnum } from "../components/Title";
import React from "react";
-export default function Home() {
+export default function Home({}) {
const router = useRouter();
return (
@@ -17,11 +17,9 @@ export default function Home() {
<link rel="icon" href="/favicon.ico" />
</Head>
- <Title />
-
<main className={styles.main}>
<h1 className={styles.title}>
- asdasdasd to <a href="https://nextjs.org">Next.js!</a>
+ Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
@@ -37,14 +35,13 @@ export default function Home() {
</div>
</Link>
- <button
+ <a
onClick={() => router.push("/foo/bar/third")}
className={styles.card}
- style={{ backgroundColor: "white" }}
>
<h2>Third Page &rarr;</h2>
<p>button, router.push()</p>
- </button>
+ </a>
<a
href="https://github.com/vercel/next.js/tree/master/examples"
diff --git a/examples/hello-next/styles/2.css b/examples/hello-next/styles/2.css
index 1e30d2166..e69de29bb 100644
--- a/examples/hello-next/styles/2.css
+++ b/examples/hello-next/styles/2.css
@@ -1,3 +0,0 @@
-* {
- background-color: red;
-}
diff --git a/examples/hello-next/styles/globals.css b/examples/hello-next/styles/globals.css
index e5e2dcc23..1abf383f1 100644
--- a/examples/hello-next/styles/globals.css
+++ b/examples/hello-next/styles/globals.css
@@ -14,3 +14,8 @@ a {
* {
box-sizing: border-box;
}
+
+body {
+ background-image: url(https://wompampsupport.azureedge.net/fetchimage?siteId=7575&v=2&jpgQuality=100&width=700&url=https%3A%2F%2Fi.kym-cdn.com%2Fentries%2Ficons%2Foriginal%2F000%2F013%2F564%2Fdoge.jpg);
+ background-size: cover;
+}
diff --git a/examples/hello-next/tsconfig.json b/examples/hello-next/tsconfig.json
index b423bb201..7af6240a5 100644
--- a/examples/hello-next/tsconfig.json
+++ b/examples/hello-next/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
- "target": "esnext",
- "lib": ["dom", "dom.iterable", "esnext", "WebWorker"],
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
@@ -9,15 +9,13 @@
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
- "moduleResolution": "Node",
+ "moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
- "paths": {
- "path": ["node_modules/path-browserify"]
- }
+ "paths": {}
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/index.tsx"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
diff --git a/examples/lotta-modules/index.js b/examples/lotta-modules/index.js
index 4968cac4b..e86d5e2d8 100644
--- a/examples/lotta-modules/index.js
+++ b/examples/lotta-modules/index.js
@@ -1,641 +1,11 @@
-import "lodash/_DataView.js";
-import "lodash/_Hash.js";
-import "lodash/_LazyWrapper.js";
-import "lodash/_ListCache";
-import "lodash/_LodashWrapper.js";
-import "lodash/_Map.js";
-import "lodash/_MapCache.js";
-import "lodash/_Promise.js";
-import "lodash/_Set.js";
-import "lodash/_SetCache.js";
-import "lodash/_Stack.js";
-import "lodash/_Symbol.js";
-import "lodash/_Uint8Array.js";
-import "lodash/_WeakMap.js";
-import "lodash/_apply.js";
-import "lodash/_arrayAggregator.js";
-import "lodash/_arrayEach.js";
-import "lodash/_arrayEachRight.js";
-import "lodash/_arrayEvery.js";
-import "lodash/_arrayFilter.js";
-import "lodash/_arrayIncludes.js";
-import "lodash/_arrayIncludesWith.js";
-import "lodash/_arrayLikeKeys.js";
-import "lodash/_arrayMap.js";
-import "lodash/_arrayPush.js";
-import "lodash/_arrayReduce.js";
-import "lodash/_arrayReduceRight.js";
-import "lodash/_arraySample.js";
-import "lodash/_arraySampleSize.js";
-import "lodash/_arrayShuffle.js";
-import "lodash/_arraySome.js";
-import "lodash/_asciiSize.js";
-import "lodash/_asciiToArray.js";
-import "lodash/_asciiWords.js";
-import "lodash/_assignMergeValue.js";
-import "lodash/_assignValue.js";
-import "lodash/_assocIndexOf.js";
-import "lodash/_baseAggregator.js";
-import "lodash/_baseAssign.js";
-import "lodash/_baseAssignIn.js";
-import "lodash/_baseAssignValue.js";
-import "lodash/_baseAt.js";
-import "lodash/_baseClamp.js";
-import "lodash/_baseClone.js";
-import "lodash/_baseConforms.js";
-import "lodash/_baseConformsTo.js";
-import "lodash/_baseCreate.js";
-import "lodash/_baseDelay.js";
-import "lodash/_baseDifference.js";
-import "lodash/_baseEach.js";
-import "lodash/_baseEachRight.js";
-import "lodash/_baseEvery.js";
-import "lodash/_baseExtremum.js";
-import "lodash/_baseFill.js";
-import "lodash/_baseFilter.js";
-import "lodash/_baseFindIndex.js";
-import "lodash/_baseFindKey.js";
-import "lodash/_baseFlatten.js";
-import "lodash/_baseFor.js";
-import "lodash/_baseForOwn.js";
-import "lodash/_baseForOwnRight.js";
-import "lodash/_baseForRight.js";
-import "lodash/_baseFunctions.js";
-import "lodash/_baseGet.js";
-import "lodash/_baseGetAllKeys.js";
-import "lodash/_baseGetTag.js";
-import "lodash/_baseGt.js";
-import "lodash/_baseHas.js";
-import "lodash/_baseHasIn.js";
-import "lodash/_baseInRange.js";
-import "lodash/_baseIndexOf.js";
-import "lodash/_baseIndexOfWith.js";
-import "lodash/_baseIntersection.js";
-import "lodash/_baseInverter.js";
-import "lodash/_baseInvoke.js";
-import "lodash/_baseIsArguments.js";
-import "lodash/_baseIsArrayBuffer.js";
-import "lodash/_baseIsDate.js";
-import "lodash/_baseIsEqual.js";
-import "lodash/_baseIsEqualDeep.js";
-import "lodash/_baseIsMap.js";
-import "lodash/_baseIsMatch.js";
-import "lodash/_baseIsNaN.js";
-import "lodash/_baseIsNative.js";
-import "lodash/_baseIsRegExp.js";
-import "lodash/_baseIsSet.js";
-import "lodash/_baseIsTypedArray.js";
-import "lodash/_baseIteratee.js";
-import "lodash/_baseKeys.js";
-import "lodash/_baseKeysIn.js";
-import "lodash/_baseLodash.js";
-import "lodash/_baseLt.js";
-import "lodash/_baseMap.js";
-import "lodash/_baseMatches.js";
-import "lodash/_baseMatchesProperty.js";
-import "lodash/_baseMean.js";
-import "lodash/_baseMerge.js";
-import "lodash/_baseMergeDeep.js";
-import "lodash/_baseNth.js";
-import "lodash/_baseOrderBy.js";
-import "lodash/_basePick.js";
-import "lodash/_basePickBy.js";
-import "lodash/_baseProperty.js";
-import "lodash/_basePropertyDeep.js";
-import "lodash/_basePropertyOf.js";
-import "lodash/_basePullAll.js";
-import "lodash/_basePullAt.js";
-import "lodash/_baseRandom.js";
-import "lodash/_baseRange.js";
-import "lodash/_baseReduce.js";
-import "lodash/_baseRepeat.js";
-import "lodash/_baseRest.js";
-import "lodash/_baseSample.js";
-import "lodash/_baseSampleSize.js";
-import "lodash/_baseSet.js";
-import "lodash/_baseSetData.js";
-import "lodash/_baseSetToString.js";
-import "lodash/_baseShuffle.js";
-import "lodash/_baseSlice.js";
-import "lodash/_baseSome.js";
-import "lodash/_baseSortBy.js";
-import "lodash/_baseSortedIndex.js";
-import "lodash/_baseSortedIndexBy.js";
-import "lodash/_baseSortedUniq.js";
-import "lodash/_baseSum.js";
-import "lodash/_baseTimes.js";
-import "lodash/_baseToNumber.js";
-import "lodash/_baseToPairs.js";
-import "lodash/_baseToString.js";
-import "lodash/_baseTrim.js";
-import "lodash/_baseUnary.js";
-import "lodash/_baseUniq.js";
-import "lodash/_baseUnset.js";
-import "lodash/_baseUpdate.js";
-import "lodash/_baseValues.js";
-import "lodash/_baseWhile.js";
-import "lodash/_baseWrapperValue.js";
-import "lodash/_baseXor.js";
-import "lodash/_baseZipObject.js";
-import "lodash/_cacheHas.js";
-import "lodash/_castArrayLikeObject.js";
-import "lodash/_castFunction.js";
-import "lodash/_castPath.js";
-import "lodash/_castRest.js";
-import "lodash/_castSlice.js";
-import "lodash/_charsEndIndex.js";
-import "lodash/_charsStartIndex.js";
-import "lodash/_cloneArrayBuffer.js";
-import "lodash/_cloneBuffer.js";
-import "lodash/_cloneDataView.js";
-import "lodash/_cloneRegExp.js";
-import "lodash/_cloneSymbol.js";
-import "lodash/_cloneTypedArray.js";
-import "lodash/_compareAscending.js";
-import "lodash/_compareMultiple.js";
-import "lodash/_composeArgs.js";
-import "lodash/_composeArgsRight.js";
-import "lodash/_copyArray.js";
-import "lodash/_copyObject.js";
-import "lodash/_copySymbols.js";
-import "lodash/_copySymbolsIn.js";
-import "lodash/_coreJsData.js";
-import "lodash/_countHolders.js";
-import "lodash/_createAggregator.js";
-import "lodash/_createAssigner.js";
-import "lodash/_createBaseEach.js";
-import "lodash/_createBaseFor.js";
-import "lodash/_createBind.js";
-import "lodash/_createCaseFirst.js";
-import "lodash/_createCompounder.js";
-import "lodash/_createCtor.js";
-import "lodash/_createCurry.js";
-import "lodash/_createFind.js";
-import "lodash/_createFlow.js";
-import "lodash/_createHybrid.js";
-import "lodash/_createInverter.js";
-import "lodash/_createMathOperation.js";
-import "lodash/_createOver.js";
-import "lodash/_createPadding.js";
-import "lodash/_createPartial.js";
-import "lodash/_createRange.js";
-import "lodash/_createRecurry.js";
-import "lodash/_createRelationalOperation.js";
-import "lodash/_createRound.js";
-import "lodash/_createSet.js";
-import "lodash/_createToPairs.js";
-import "lodash/_createWrap.js";
-import "lodash/_customDefaultsAssignIn.js";
-import "lodash/_customDefaultsMerge.js";
-import "lodash/_customOmitClone.js";
-import "lodash/_deburrLetter.js";
-import "lodash/_defineProperty.js";
-import "lodash/_equalArrays.js";
-import "lodash/_equalByTag.js";
-import "lodash/_equalObjects.js";
-import "lodash/_escapeHtmlChar.js";
-import "lodash/_escapeStringChar.js";
-import "lodash/_flatRest.js";
-import "lodash/_freeGlobal.js";
-import "lodash/_getAllKeys.js";
-import "lodash/_getAllKeysIn.js";
-import "lodash/_getData.js";
-import "lodash/_getFuncName.js";
-import "lodash/_getHolder.js";
-import "lodash/_getMapData.js";
-import "lodash/_getMatchData.js";
-import "lodash/_getNative.js";
-import "lodash/_getPrototype.js";
-import "lodash/_getRawTag.js";
-import "lodash/_getSymbols.js";
-import "lodash/_getSymbolsIn.js";
-import "lodash/_getTag.js";
-import "lodash/_getValue.js";
-import "lodash/_getView.js";
-import "lodash/_getWrapDetails.js";
-import "lodash/_hasPath.js";
-import "lodash/_hasUnicode.js";
-import "lodash/_hasUnicodeWord.js";
-import "lodash/_hashClear.js";
-import "lodash/_hashDelete.js";
-import "lodash/_hashGet.js";
-import "lodash/_hashHas.js";
-import "lodash/_hashSet.js";
-import "lodash/_initCloneArray.js";
-import "lodash/_initCloneByTag.js";
-import "lodash/_initCloneObject.js";
-import "lodash/_insertWrapDetails.js";
-import "lodash/_isFlattenable.js";
-import "lodash/_isIndex.js";
-import "lodash/_isIterateeCall.js";
-import "lodash/_isKey.js";
-import "lodash/_isKeyable.js";
-import "lodash/_isLaziable.js";
-import "lodash/_isMaskable.js";
-import "lodash/_isMasked.js";
-import "lodash/_isPrototype.js";
-import "lodash/_isStrictComparable.js";
-import "lodash/_iteratorToArray.js";
-import "lodash/_lazyClone.js";
-import "lodash/_lazyReverse.js";
-import "lodash/_lazyValue.js";
-import "lodash/_listCacheClear.js";
-import "lodash/_listCacheDelete.js";
-import "lodash/_listCacheGet.js";
-import "lodash/_listCacheHas.js";
-import "lodash/_listCacheSet.js";
-import "lodash/_mapCacheClear.js";
-import "lodash/_mapCacheDelete.js";
-import "lodash/_mapCacheGet.js";
-import "lodash/_mapCacheHas.js";
-import "lodash/_mapCacheSet.js";
-import "lodash/_mapToArray.js";
-import "lodash/_matchesStrictComparable.js";
-import "lodash/_memoizeCapped.js";
-import "lodash/_mergeData.js";
-import "lodash/_metaMap.js";
-import "lodash/_nativeCreate.js";
-import "lodash/_nativeKeys.js";
-import "lodash/_nativeKeysIn.js";
-import "lodash/_nodeUtil.js";
-import "lodash/_objectToString.js";
-import "lodash/_overArg.js";
-import "lodash/_overRest.js";
-import "lodash/_parent.js";
-import "lodash/_reEscape.js";
-import "lodash/_reEvaluate.js";
-import "lodash/_reInterpolate.js";
-import "lodash/_realNames.js";
-import "lodash/_reorder.js";
-import "lodash/_replaceHolders.js";
-import "lodash/_root.js";
-import "lodash/_safeGet.js";
-import "lodash/_setCacheAdd.js";
-import "lodash/_setCacheHas.js";
-import "lodash/_setData.js";
-import "lodash/_setToArray.js";
-import "lodash/_setToPairs.js";
-import "lodash/_setToString.js";
-import "lodash/_setWrapToString.js";
-import "lodash/_shortOut.js";
-import "lodash/_shuffleSelf.js";
-import "lodash/_stackClear.js";
-import "lodash/_stackDelete.js";
-import "lodash/_stackGet.js";
-import "lodash/_stackHas.js";
-import "lodash/_stackSet.js";
-import "lodash/_strictIndexOf.js";
-import "lodash/_strictLastIndexOf.js";
-import "lodash/_stringSize.js";
-import "lodash/_stringToArray.js";
-import "lodash/_stringToPath.js";
-import "lodash/_toKey.js";
-import "lodash/_toSource.js";
-import "lodash/_trimmedEndIndex.js";
-import "lodash/_unescapeHtmlChar.js";
-import "lodash/_unicodeSize.js";
-import "lodash/_unicodeToArray.js";
-import "lodash/_unicodeWords.js";
-import "lodash/_updateWrapDetails.js";
-import "lodash/_wrapperClone.js";
-import "lodash/add.js";
-import "lodash/after.js";
-import "lodash/array.js";
-import "lodash/ary.js";
-import "lodash/assign.js";
-import "lodash/assignIn.js";
-import "lodash/assignInWith.js";
-import "lodash/assignWith.js";
-import "lodash/at.js";
-import "lodash/attempt.js";
-import "lodash/before.js";
-import "lodash/bind.js";
-import "lodash/bindAll.js";
-import "lodash/bindKey.js";
-import "lodash/camelCase.js";
-import "lodash/capitalize.js";
-import "lodash/castArray.js";
-import "lodash/ceil.js";
-import "lodash/chain.js";
-import "lodash/chunk.js";
-import "lodash/clamp.js";
-import "lodash/clone.js";
-import "lodash/cloneDeep.js";
-import "lodash/cloneDeepWith.js";
-import "lodash/cloneWith.js";
-import "lodash/collection.js";
-import "lodash/commit.js";
-import "lodash/compact.js";
-import "lodash/concat.js";
-import "lodash/cond.js";
-import "lodash/conforms.js";
-import "lodash/conformsTo.js";
-import "lodash/constant.js";
-import "lodash/core.js";
-import "lodash/core.min.js";
-import "lodash/countBy.js";
-import "lodash/create.js";
-import "lodash/curry.js";
-import "lodash/curryRight.js";
-import "lodash/date.js";
-import "lodash/debounce.js";
-import "lodash/deburr.js";
-import "lodash/defaultTo.js";
-import "lodash/defaults.js";
-import "lodash/defaultsDeep.js";
-import "lodash/defer.js";
-import "lodash/delay.js";
-import "lodash/difference.js";
-import "lodash/differenceBy.js";
-import "lodash/differenceWith.js";
-import "lodash/divide.js";
-import "lodash/drop.js";
-import "lodash/dropRight.js";
-import "lodash/dropRightWhile.js";
-import "lodash/dropWhile.js";
-import "lodash/each.js";
-import "lodash/eachRight.js";
-import "lodash/endsWith.js";
-import "lodash/entries.js";
-import "lodash/entriesIn.js";
-import "lodash/eq.js";
-import "lodash/escape.js";
-import "lodash/escapeRegExp.js";
-import "lodash/every.js";
-import "lodash/extend.js";
-import "lodash/extendWith.js";
-import "lodash/fill.js";
-import "lodash/filter.js";
-import "lodash/find.js";
-import "lodash/findIndex.js";
-import "lodash/findKey.js";
-import "lodash/findLast.js";
-import "lodash/findLastIndex.js";
-import "lodash/findLastKey.js";
-import "lodash/first.js";
-import "lodash/flatMap.js";
-import "lodash/flatMapDeep.js";
-import "lodash/flatMapDepth.js";
-import "lodash/flatten.js";
-import "lodash/flattenDeep.js";
-import "lodash/flattenDepth.js";
-import "lodash/flip.js";
-import "lodash/floor.js";
-import "lodash/flow.js";
-import "lodash/flowRight.js";
-import "lodash/forEach.js";
-import "lodash/forEachRight.js";
-import "lodash/forIn.js";
-import "lodash/forInRight.js";
-import "lodash/forOwn.js";
-import "lodash/forOwnRight.js";
-import "lodash/fp";
-import "lodash/fp.js";
-import "lodash/fromPairs.js";
-import "lodash/function.js";
-import "lodash/functions.js";
-import "lodash/functionsIn.js";
-import "lodash/get.js";
-import "lodash/groupBy.js";
-import "lodash/gt.js";
-import "lodash/gte.js";
-import "lodash/has.js";
-import "lodash/hasIn.js";
-import "lodash/head.js";
-import "lodash/identity.js";
-import "lodash/inRange.js";
-import "lodash/includes.js";
-import "lodash/index.js";
-import "lodash/indexOf.js";
-import "lodash/initial.js";
-import "lodash/intersection.js";
-import "lodash/intersectionBy.js";
-import "lodash/intersectionWith.js";
-import "lodash/invert.js";
-import "lodash/invertBy.js";
-import "lodash/invoke.js";
-import "lodash/invokeMap.js";
-import "lodash/isArguments.js";
-import "lodash/isArray.js";
-import "lodash/isArrayBuffer.js";
-import "lodash/isArrayLike.js";
-import "lodash/isArrayLikeObject.js";
-import "lodash/isBoolean.js";
-import "lodash/isBuffer.js";
-import "lodash/isDate.js";
-import "lodash/isElement.js";
-import "lodash/isEmpty.js";
-import "lodash/isEqual.js";
-import "lodash/isEqualWith.js";
-import "lodash/isError.js";
-import "lodash/isFinite.js";
-import "lodash/isFunction.js";
-import "lodash/isInteger.js";
-import "lodash/isLength.js";
-import "lodash/isMap.js";
-import "lodash/isMatch.js";
-import "lodash/isMatchWith.js";
-import "lodash/isNaN.js";
-import "lodash/isNative.js";
-import "lodash/isNil.js";
-import "lodash/isNull.js";
-import "lodash/isNumber.js";
-import "lodash/isObject.js";
-import "lodash/isObjectLike.js";
-import "lodash/isPlainObject.js";
-import "lodash/isRegExp.js";
-import "lodash/isSafeInteger.js";
-import "lodash/isSet.js";
-import "lodash/isString.js";
-import "lodash/isSymbol.js";
-import "lodash/isTypedArray.js";
-import "lodash/isUndefined.js";
-import "lodash/isWeakMap.js";
-import "lodash/isWeakSet.js";
-import "lodash/iteratee.js";
-import "lodash/join.js";
-import "lodash/kebabCase.js";
-import "lodash/keyBy.js";
-import "lodash/keys.js";
-import "lodash/keysIn.js";
-import "lodash/lang.js";
-import "lodash/last.js";
-import "lodash/lastIndexOf.js";
-import "lodash/lodash.js";
-import "lodash/lodash.min.js";
-import "lodash/lowerCase.js";
-import "lodash/lowerFirst.js";
-import "lodash/lt.js";
-import "lodash/lte.js";
-import "lodash/map.js";
-import "lodash/mapKeys.js";
-import "lodash/mapValues.js";
-import "lodash/matches.js";
-import "lodash/matchesProperty.js";
-import "lodash/math.js";
-import "lodash/max.js";
-import "lodash/maxBy.js";
-import "lodash/mean.js";
-import "lodash/meanBy.js";
-import "lodash/memoize.js";
-import "lodash/merge.js";
-import "lodash/mergeWith.js";
-import "lodash/method.js";
-import "lodash/methodOf.js";
-import "lodash/min.js";
-import "lodash/minBy.js";
-import "lodash/mixin.js";
-import "lodash/multiply.js";
-import "lodash/negate.js";
-import "lodash/next.js";
-import "lodash/noop.js";
-import "lodash/now.js";
-import "lodash/nth.js";
-import "lodash/nthArg.js";
-import "lodash/number.js";
-import "lodash/object.js";
-import "lodash/omit.js";
-import "lodash/omitBy.js";
-import "lodash/once.js";
-import "lodash/orderBy.js";
-import "lodash/over.js";
-import "lodash/overArgs.js";
-import "lodash/overEvery.js";
-import "lodash/overSome.js";
-import "lodash/pad.js";
-import "lodash/padEnd.js";
-import "lodash/padStart.js";
-import "lodash/parseInt.js";
-import "lodash/partial.js";
-import "lodash/partialRight.js";
-import "lodash/partition.js";
-import "lodash/pick.js";
-import "lodash/pickBy.js";
-import "lodash/plant.js";
-import "lodash/property.js";
-import "lodash/propertyOf.js";
-import "lodash/pull.js";
-import "lodash/pullAll.js";
-import "lodash/pullAllBy.js";
-import "lodash/pullAllWith.js";
-import "lodash/pullAt.js";
-import "lodash/random.js";
-import "lodash/range.js";
-import "lodash/rangeRight.js";
-import "lodash/rearg.js";
-import "lodash/reduce.js";
-import "lodash/reduceRight.js";
-import "lodash/reject.js";
-import "lodash/remove.js";
-import "lodash/repeat.js";
-import "lodash/replace.js";
-import "lodash/rest.js";
-import "lodash/result.js";
-import "lodash/reverse.js";
-import "lodash/round.js";
-import "lodash/sample.js";
-import "lodash/sampleSize.js";
-import "lodash/seq.js";
-import "lodash/set.js";
-import "lodash/setWith.js";
-import "lodash/shuffle.js";
-import "lodash/size.js";
-import "lodash/slice.js";
-import "lodash/snakeCase.js";
-import "lodash/some.js";
-import "lodash/sortBy.js";
-import "lodash/sortedIndex.js";
-import "lodash/sortedIndexBy.js";
-import "lodash/sortedIndexOf.js";
-import "lodash/sortedLastIndex.js";
-import "lodash/sortedLastIndexBy.js";
-import "lodash/sortedLastIndexOf.js";
-import "lodash/sortedUniq.js";
-import "lodash/sortedUniqBy.js";
-import "lodash/split.js";
-import "lodash/spread.js";
-import "lodash/startCase.js";
-import "lodash/startsWith.js";
-import "lodash/string.js";
-import "lodash/stubArray.js";
-import "lodash/stubFalse.js";
-import "lodash/stubObject.js";
-import "lodash/stubString.js";
-import "lodash/stubTrue.js";
-import "lodash/subtract.js";
-import "lodash/sum.js";
-import "lodash/sumBy.js";
-import "lodash/tail.js";
-import "lodash/take.js";
-import "lodash/takeRight.js";
-import "lodash/takeRightWhile.js";
-import "lodash/takeWhile.js";
-import "lodash/tap.js";
-import "lodash/template.js";
-import "lodash/templateSettings.js";
-import "lodash/throttle.js";
-import "lodash/thru.js";
-import "lodash/times.js";
-import "lodash/toArray.js";
-import "lodash/toFinite.js";
-import "lodash/toInteger.js";
-import "lodash/toIterator.js";
-import "lodash/toJSON.js";
-import "lodash/toLength.js";
-import "lodash/toLower.js";
-import "lodash/toNumber.js";
-import "lodash/toPairs.js";
-import "lodash/toPairsIn.js";
-import "lodash/toPath.js";
-import "lodash/toPlainObject.js";
-import "lodash/toSafeInteger.js";
-import "lodash/toString.js";
-import "lodash/toUpper.js";
-import "lodash/transform.js";
-import "lodash/trim.js";
-import "lodash/trimEnd.js";
-import "lodash/trimStart.js";
-import "lodash/truncate.js";
-import "lodash/unary.js";
-import "lodash/unescape.js";
-import "lodash/union.js";
-import "lodash/unionBy.js";
-import "lodash/unionWith.js";
-import "lodash/uniq.js";
-import "lodash/uniqBy.js";
-import "lodash/uniqWith.js";
-import "lodash/uniqueId.js";
-import "lodash/unset.js";
-import "lodash/unzip.js";
-import "lodash/unzipWith.js";
-import "lodash/update.js";
-import "lodash/updateWith.js";
-import "lodash/upperCase.js";
-import "lodash/upperFirst.js";
-import "lodash/util.js";
-import "lodash/value.js";
-import "lodash/valueOf.js";
-import "lodash/values.js";
-import "lodash/valuesIn.js";
-import "lodash/without.js";
-import "lodash/words.js";
-import "lodash/wrap.js";
-import "lodash/wrapperAt.js";
-import "lodash/wrapperChain.js";
-import "lodash/wrapperLodash.js";
-import "lodash/wrapperReverse.js";
-import "lodash/wrapperValue.js";
-import "lodash/xor.js";
-import "lodash/xorBy.js";
-import "lodash/xorWith.js";
-import "lodash/zip.js";
-import "lodash/zipObject.js";
-import "lodash/zipObjectDeep.js";
-import "lodash/_setToString";
-import "lodash";
-import "lodash/lodash";
-
-import "underscore";
-import "three";
-
-// import "@babel/standalone/babel.js";
+import "three/three1";
+import "three/three2";
+import "three/three3";
+import "three/three4";
+import "three/three5";
+import "three/three6";
+import "three/three7";
+import "three/three8";
+import "three/three9";
+import "three/three10";
+// import "@babel/standalone/babel";
diff --git a/examples/lotta-modules/public/index.html b/examples/lotta-modules/public/index.html
new file mode 100644
index 000000000..bb6a38234
--- /dev/null
+++ b/examples/lotta-modules/public/index.html
@@ -0,0 +1,6 @@
+<html>
+ <head> </head>
+ <body>
+ <script src="/index.js"></script>
+ </body>
+</html>