almostnode 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frameworks/next-dev-server.d.ts +5 -0
- package/dist/frameworks/next-dev-server.d.ts.map +1 -1
- package/dist/index.cjs +127 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +128 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/frameworks/next-dev-server.ts +135 -8
package/dist/index.mjs
CHANGED
|
@@ -12557,6 +12557,9 @@ export default function Head({ children }) {
|
|
|
12557
12557
|
if (pathname.startsWith("/_next/pages/")) {
|
|
12558
12558
|
return this.servePageComponent(pathname);
|
|
12559
12559
|
}
|
|
12560
|
+
if (pathname.startsWith("/_next/app/")) {
|
|
12561
|
+
return this.serveAppComponent(pathname);
|
|
12562
|
+
}
|
|
12560
12563
|
if (pathname.startsWith("/_next/static/")) {
|
|
12561
12564
|
return this.serveStaticAsset(pathname);
|
|
12562
12565
|
}
|
|
@@ -12621,6 +12624,22 @@ export default function Head({ children }) {
|
|
|
12621
12624
|
}
|
|
12622
12625
|
return this.transformAndServe(pageFile, pageFile);
|
|
12623
12626
|
}
|
|
12627
|
+
async serveAppComponent(pathname) {
|
|
12628
|
+
const filePath = pathname.replace("/_next/app", "").replace(/\.js$/, "");
|
|
12629
|
+
const extensions = [
|
|
12630
|
+
".tsx",
|
|
12631
|
+
".jsx",
|
|
12632
|
+
".ts",
|
|
12633
|
+
".js"
|
|
12634
|
+
];
|
|
12635
|
+
for (const ext of extensions) {
|
|
12636
|
+
const fullPath = filePath + ext;
|
|
12637
|
+
if (this.exists(fullPath)) {
|
|
12638
|
+
return this.transformAndServe(fullPath, fullPath);
|
|
12639
|
+
}
|
|
12640
|
+
}
|
|
12641
|
+
return this.notFound(pathname);
|
|
12642
|
+
}
|
|
12624
12643
|
async handleApiRoute(method, pathname, headers, body) {
|
|
12625
12644
|
const apiFile = this.resolveApiFile(pathname);
|
|
12626
12645
|
if (!apiFile) {
|
|
@@ -13177,11 +13196,9 @@ export default function Head({ children }) {
|
|
|
13177
13196
|
globalCssLinks.push(`<link rel="stylesheet" href="${virtualPrefix}${cssPath}">`);
|
|
13178
13197
|
}
|
|
13179
13198
|
}
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
let nestedJsx = "React.createElement(Page)";
|
|
13199
|
+
virtualPrefix + route.page;
|
|
13200
|
+
route.layouts.map((layout, i) => `import Layout${i} from '${virtualPrefix}${layout}';`).join("\n ");
|
|
13183
13201
|
for (let i = route.layouts.length - 1; i >= 0; i--) {
|
|
13184
|
-
nestedJsx = `React.createElement(Layout${i}, null, ${nestedJsx})`;
|
|
13185
13202
|
}
|
|
13186
13203
|
const envScript = this.generateEnvScript();
|
|
13187
13204
|
return `<!DOCTYPE html>
|
|
@@ -13225,17 +13242,117 @@ export default function Head({ children }) {
|
|
|
13225
13242
|
<script type="module">
|
|
13226
13243
|
import React from 'react';
|
|
13227
13244
|
import ReactDOM from 'react-dom/client';
|
|
13228
|
-
import Page from '${pageModulePath}';
|
|
13229
|
-
${layoutImports}
|
|
13230
13245
|
|
|
13231
|
-
|
|
13232
|
-
|
|
13246
|
+
const virtualBase = '${virtualPrefix}';
|
|
13247
|
+
|
|
13248
|
+
// Convert URL path to app router page module path
|
|
13249
|
+
function getAppPageModulePath(pathname) {
|
|
13250
|
+
let route = pathname;
|
|
13251
|
+
if (route.startsWith(virtualBase)) {
|
|
13252
|
+
route = route.slice(virtualBase.length);
|
|
13253
|
+
}
|
|
13254
|
+
route = route.replace(/^\\/+/, '/') || '/';
|
|
13255
|
+
// App Router: / -> /app/page, /about -> /app/about/page
|
|
13256
|
+
const pagePath = route === '/' ? '/app/page' : '/app' + route + '/page';
|
|
13257
|
+
return virtualBase + '/_next/app' + pagePath + '.js';
|
|
13258
|
+
}
|
|
13259
|
+
|
|
13260
|
+
// Get layout paths for a route
|
|
13261
|
+
function getLayoutPaths(pathname) {
|
|
13262
|
+
let route = pathname;
|
|
13263
|
+
if (route.startsWith(virtualBase)) {
|
|
13264
|
+
route = route.slice(virtualBase.length);
|
|
13265
|
+
}
|
|
13266
|
+
route = route.replace(/^\\/+/, '/') || '/';
|
|
13267
|
+
|
|
13268
|
+
// Build layout paths from root to current route
|
|
13269
|
+
const layouts = [virtualBase + '/_next/app/app/layout.js'];
|
|
13270
|
+
if (route !== '/') {
|
|
13271
|
+
const segments = route.split('/').filter(Boolean);
|
|
13272
|
+
let currentPath = '/app';
|
|
13273
|
+
for (const segment of segments) {
|
|
13274
|
+
currentPath += '/' + segment;
|
|
13275
|
+
layouts.push(virtualBase + '/_next/app' + currentPath + '/layout.js');
|
|
13276
|
+
}
|
|
13277
|
+
}
|
|
13278
|
+
return layouts;
|
|
13279
|
+
}
|
|
13280
|
+
|
|
13281
|
+
// Dynamic page loader
|
|
13282
|
+
async function loadPage(pathname) {
|
|
13283
|
+
const modulePath = getAppPageModulePath(pathname);
|
|
13284
|
+
try {
|
|
13285
|
+
const module = await import(/* @vite-ignore */ modulePath);
|
|
13286
|
+
return module.default;
|
|
13287
|
+
} catch (e) {
|
|
13288
|
+
console.error('[Navigation] Failed to load page:', modulePath, e);
|
|
13289
|
+
return null;
|
|
13290
|
+
}
|
|
13291
|
+
}
|
|
13292
|
+
|
|
13293
|
+
// Load layouts (with caching)
|
|
13294
|
+
const layoutCache = new Map();
|
|
13295
|
+
async function loadLayouts(pathname) {
|
|
13296
|
+
const layoutPaths = getLayoutPaths(pathname);
|
|
13297
|
+
const layouts = [];
|
|
13298
|
+
for (const path of layoutPaths) {
|
|
13299
|
+
if (layoutCache.has(path)) {
|
|
13300
|
+
layouts.push(layoutCache.get(path));
|
|
13301
|
+
} else {
|
|
13302
|
+
try {
|
|
13303
|
+
const module = await import(/* @vite-ignore */ path);
|
|
13304
|
+
layoutCache.set(path, module.default);
|
|
13305
|
+
layouts.push(module.default);
|
|
13306
|
+
} catch (e) {
|
|
13307
|
+
// Layout might not exist for this segment, skip
|
|
13308
|
+
}
|
|
13309
|
+
}
|
|
13310
|
+
}
|
|
13311
|
+
return layouts;
|
|
13312
|
+
}
|
|
13313
|
+
|
|
13314
|
+
// Router component
|
|
13315
|
+
function Router() {
|
|
13316
|
+
const [Page, setPage] = React.useState(null);
|
|
13317
|
+
const [layouts, setLayouts] = React.useState([]);
|
|
13318
|
+
const [path, setPath] = React.useState(window.location.pathname);
|
|
13319
|
+
|
|
13320
|
+
React.useEffect(() => {
|
|
13321
|
+
Promise.all([loadPage(path), loadLayouts(path)]).then(([P, L]) => {
|
|
13322
|
+
if (P) setPage(() => P);
|
|
13323
|
+
setLayouts(L);
|
|
13324
|
+
});
|
|
13325
|
+
}, []);
|
|
13326
|
+
|
|
13327
|
+
React.useEffect(() => {
|
|
13328
|
+
const handleNavigation = async () => {
|
|
13329
|
+
const newPath = window.location.pathname;
|
|
13330
|
+
if (newPath !== path) {
|
|
13331
|
+
setPath(newPath);
|
|
13332
|
+
const [P, L] = await Promise.all([loadPage(newPath), loadLayouts(newPath)]);
|
|
13333
|
+
if (P) setPage(() => P);
|
|
13334
|
+
setLayouts(L);
|
|
13335
|
+
}
|
|
13336
|
+
};
|
|
13337
|
+
window.addEventListener('popstate', handleNavigation);
|
|
13338
|
+
return () => window.removeEventListener('popstate', handleNavigation);
|
|
13339
|
+
}, [path]);
|
|
13340
|
+
|
|
13341
|
+
if (!Page) return null;
|
|
13342
|
+
|
|
13343
|
+
// Build nested layout structure
|
|
13344
|
+
let content = React.createElement(Page);
|
|
13345
|
+
for (let i = layouts.length - 1; i >= 0; i--) {
|
|
13346
|
+
content = React.createElement(layouts[i], null, content);
|
|
13347
|
+
}
|
|
13348
|
+
return content;
|
|
13233
13349
|
}
|
|
13234
13350
|
|
|
13351
|
+
// Mark that we've initialized (for testing no-reload)
|
|
13352
|
+
window.__NEXT_INITIALIZED__ = Date.now();
|
|
13353
|
+
|
|
13235
13354
|
ReactDOM.createRoot(document.getElementById('__next')).render(
|
|
13236
|
-
React.createElement(React.StrictMode, null,
|
|
13237
|
-
React.createElement(App)
|
|
13238
|
-
)
|
|
13355
|
+
React.createElement(React.StrictMode, null, React.createElement(Router))
|
|
13239
13356
|
);
|
|
13240
13357
|
<\/script>
|
|
13241
13358
|
</body>
|