almostnode 0.2.3 → 0.2.5
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/__sw__.js +23 -1
- package/dist/assets/{runtime-worker-D9x_Ddwz.js → runtime-worker-B8_LZkBX.js} +85 -32
- package/dist/assets/runtime-worker-B8_LZkBX.js.map +1 -0
- package/dist/frameworks/next-dev-server.d.ts +7 -0
- package/dist/frameworks/next-dev-server.d.ts.map +1 -1
- package/dist/frameworks/vite-dev-server.d.ts +1 -0
- package/dist/frameworks/vite-dev-server.d.ts.map +1 -1
- package/dist/index.cjs +253 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +258 -44
- package/dist/index.mjs.map +1 -1
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/types/package-json.d.ts +16 -0
- package/dist/types/package-json.d.ts.map +1 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/virtual-fs.d.ts +1 -0
- package/dist/virtual-fs.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/frameworks/next-dev-server.ts +162 -8
- package/src/frameworks/vite-dev-server.ts +25 -0
- package/src/runtime.ts +84 -25
- package/src/types/package-json.ts +15 -0
- package/src/utils/hash.ts +12 -0
- package/src/virtual-fs.ts +14 -10
- package/dist/assets/runtime-worker-D9x_Ddwz.js.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -39,7 +39,8 @@ let __tla = (async () => {
|
|
|
39
39
|
__publicField(this, "eventListeners", /* @__PURE__ */ new Map());
|
|
40
40
|
this.root = {
|
|
41
41
|
type: "directory",
|
|
42
|
-
children: /* @__PURE__ */ new Map()
|
|
42
|
+
children: /* @__PURE__ */ new Map(),
|
|
43
|
+
mtime: Date.now()
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
on(event, listener) {
|
|
@@ -152,7 +153,8 @@ let __tla = (async () => {
|
|
|
152
153
|
const content = typeof data === "string" ? this.encoder.encode(data) : data;
|
|
153
154
|
parent.children.set(basename2, {
|
|
154
155
|
type: "file",
|
|
155
|
-
content
|
|
156
|
+
content,
|
|
157
|
+
mtime: Date.now()
|
|
156
158
|
});
|
|
157
159
|
if (emitEvent) {
|
|
158
160
|
this.notifyWatchers(normalized, existed ? "change" : "rename");
|
|
@@ -213,7 +215,8 @@ let __tla = (async () => {
|
|
|
213
215
|
if (!child) {
|
|
214
216
|
child = {
|
|
215
217
|
type: "directory",
|
|
216
|
-
children: /* @__PURE__ */ new Map()
|
|
218
|
+
children: /* @__PURE__ */ new Map(),
|
|
219
|
+
mtime: Date.now()
|
|
217
220
|
};
|
|
218
221
|
current.children.set(segment, child);
|
|
219
222
|
} else if (child.type !== "directory") {
|
|
@@ -232,8 +235,8 @@ let __tla = (async () => {
|
|
|
232
235
|
if (!node) {
|
|
233
236
|
throw createNodeError("ENOENT", "stat", path2);
|
|
234
237
|
}
|
|
235
|
-
const now = Date.now();
|
|
236
238
|
const size = node.type === "file" ? ((_a2 = node.content) == null ? void 0 : _a2.length) || 0 : 0;
|
|
239
|
+
const mtime = node.mtime;
|
|
237
240
|
return {
|
|
238
241
|
isFile: () => node.type === "file",
|
|
239
242
|
isDirectory: () => node.type === "directory",
|
|
@@ -244,14 +247,14 @@ let __tla = (async () => {
|
|
|
244
247
|
isSocket: () => false,
|
|
245
248
|
size,
|
|
246
249
|
mode: node.type === "directory" ? 493 : 420,
|
|
247
|
-
mtime: new Date(
|
|
248
|
-
atime: new Date(
|
|
249
|
-
ctime: new Date(
|
|
250
|
-
birthtime: new Date(
|
|
251
|
-
mtimeMs:
|
|
252
|
-
atimeMs:
|
|
253
|
-
ctimeMs:
|
|
254
|
-
birthtimeMs:
|
|
250
|
+
mtime: new Date(mtime),
|
|
251
|
+
atime: new Date(mtime),
|
|
252
|
+
ctime: new Date(mtime),
|
|
253
|
+
birthtime: new Date(mtime),
|
|
254
|
+
mtimeMs: mtime,
|
|
255
|
+
atimeMs: mtime,
|
|
256
|
+
ctimeMs: mtime,
|
|
257
|
+
birthtimeMs: mtime,
|
|
255
258
|
nlink: 1,
|
|
256
259
|
uid: 1e3,
|
|
257
260
|
gid: 1e3,
|
|
@@ -305,7 +308,8 @@ let __tla = (async () => {
|
|
|
305
308
|
}
|
|
306
309
|
parent.children.set(basename2, {
|
|
307
310
|
type: "directory",
|
|
308
|
-
children: /* @__PURE__ */ new Map()
|
|
311
|
+
children: /* @__PURE__ */ new Map(),
|
|
312
|
+
mtime: Date.now()
|
|
309
313
|
});
|
|
310
314
|
}
|
|
311
315
|
readdirSync(path2) {
|
|
@@ -589,6 +593,14 @@ let __tla = (async () => {
|
|
|
589
593
|
};
|
|
590
594
|
}
|
|
591
595
|
};
|
|
596
|
+
function simpleHash(str) {
|
|
597
|
+
let hash = 0;
|
|
598
|
+
for (let i = 0; i < str.length; i++) {
|
|
599
|
+
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
600
|
+
hash |= 0;
|
|
601
|
+
}
|
|
602
|
+
return hash.toString(36);
|
|
603
|
+
}
|
|
592
604
|
class Dirent {
|
|
593
605
|
constructor(name, isDirectory, isFile) {
|
|
594
606
|
__publicField(this, "name");
|
|
@@ -9188,7 +9200,23 @@ let __tla = (async () => {
|
|
|
9188
9200
|
"@sentry/node": sentryShim,
|
|
9189
9201
|
"@sentry/core": sentryShim
|
|
9190
9202
|
};
|
|
9191
|
-
function createRequire(vfs, fsShim, process, currentDir, moduleCache, options) {
|
|
9203
|
+
function createRequire(vfs, fsShim, process, currentDir, moduleCache, options, processedCodeCache) {
|
|
9204
|
+
const resolutionCache = /* @__PURE__ */ new Map();
|
|
9205
|
+
const packageJsonCache = /* @__PURE__ */ new Map();
|
|
9206
|
+
const getParsedPackageJson = (pkgPath) => {
|
|
9207
|
+
if (packageJsonCache.has(pkgPath)) {
|
|
9208
|
+
return packageJsonCache.get(pkgPath);
|
|
9209
|
+
}
|
|
9210
|
+
try {
|
|
9211
|
+
const content = vfs.readFileSync(pkgPath, "utf8");
|
|
9212
|
+
const parsed = JSON.parse(content);
|
|
9213
|
+
packageJsonCache.set(pkgPath, parsed);
|
|
9214
|
+
return parsed;
|
|
9215
|
+
} catch {
|
|
9216
|
+
packageJsonCache.set(pkgPath, null);
|
|
9217
|
+
return null;
|
|
9218
|
+
}
|
|
9219
|
+
};
|
|
9192
9220
|
const resolveModule = (id, fromDir) => {
|
|
9193
9221
|
if (id.startsWith("node:")) {
|
|
9194
9222
|
id = id.slice(5);
|
|
@@ -9196,15 +9224,25 @@ let __tla = (async () => {
|
|
|
9196
9224
|
if (builtinModules[id] || id === "fs" || id === "process" || id === "url" || id === "querystring" || id === "util") {
|
|
9197
9225
|
return id;
|
|
9198
9226
|
}
|
|
9227
|
+
const cacheKey = `${fromDir}|${id}`;
|
|
9228
|
+
const cached = resolutionCache.get(cacheKey);
|
|
9229
|
+
if (cached !== void 0) {
|
|
9230
|
+
if (cached === null) {
|
|
9231
|
+
throw new Error(`Cannot find module '${id}'`);
|
|
9232
|
+
}
|
|
9233
|
+
return cached;
|
|
9234
|
+
}
|
|
9199
9235
|
if (id.startsWith("./") || id.startsWith("../") || id.startsWith("/")) {
|
|
9200
9236
|
const resolved = id.startsWith("/") ? id : resolve$2(fromDir, id);
|
|
9201
9237
|
if (vfs.existsSync(resolved)) {
|
|
9202
9238
|
const stats = vfs.statSync(resolved);
|
|
9203
9239
|
if (stats.isFile()) {
|
|
9240
|
+
resolutionCache.set(cacheKey, resolved);
|
|
9204
9241
|
return resolved;
|
|
9205
9242
|
}
|
|
9206
9243
|
const indexPath = join(resolved, "index.js");
|
|
9207
9244
|
if (vfs.existsSync(indexPath)) {
|
|
9245
|
+
resolutionCache.set(cacheKey, indexPath);
|
|
9208
9246
|
return indexPath;
|
|
9209
9247
|
}
|
|
9210
9248
|
}
|
|
@@ -9215,9 +9253,11 @@ let __tla = (async () => {
|
|
|
9215
9253
|
for (const ext of extensions) {
|
|
9216
9254
|
const withExt = resolved + ext;
|
|
9217
9255
|
if (vfs.existsSync(withExt)) {
|
|
9256
|
+
resolutionCache.set(cacheKey, withExt);
|
|
9218
9257
|
return withExt;
|
|
9219
9258
|
}
|
|
9220
9259
|
}
|
|
9260
|
+
resolutionCache.set(cacheKey, null);
|
|
9221
9261
|
throw new Error(`Cannot find module '${id}' from '${fromDir}'`);
|
|
9222
9262
|
}
|
|
9223
9263
|
const tryResolveFile = (basePath) => {
|
|
@@ -9252,9 +9292,8 @@ let __tla = (async () => {
|
|
|
9252
9292
|
const pkgName = parts[0].startsWith("@") && parts.length > 1 ? `${parts[0]}/${parts[1]}` : parts[0];
|
|
9253
9293
|
const pkgRoot = join(nodeModulesDir, pkgName);
|
|
9254
9294
|
const pkgPath = join(pkgRoot, "package.json");
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
const pkg = JSON.parse(pkgContent);
|
|
9295
|
+
const pkg = getParsedPackageJson(pkgPath);
|
|
9296
|
+
if (pkg) {
|
|
9258
9297
|
if (pkg.exports) {
|
|
9259
9298
|
try {
|
|
9260
9299
|
const resolved2 = resolve$3(pkg, moduleId, {
|
|
@@ -9282,11 +9321,18 @@ let __tla = (async () => {
|
|
|
9282
9321
|
while (searchDir !== "/") {
|
|
9283
9322
|
const nodeModulesDir = join(searchDir, "node_modules");
|
|
9284
9323
|
const resolved = tryResolveFromNodeModules(nodeModulesDir, id);
|
|
9285
|
-
if (resolved)
|
|
9324
|
+
if (resolved) {
|
|
9325
|
+
resolutionCache.set(cacheKey, resolved);
|
|
9326
|
+
return resolved;
|
|
9327
|
+
}
|
|
9286
9328
|
searchDir = dirname(searchDir);
|
|
9287
9329
|
}
|
|
9288
9330
|
const rootResolved = tryResolveFromNodeModules("/node_modules", id);
|
|
9289
|
-
if (rootResolved)
|
|
9331
|
+
if (rootResolved) {
|
|
9332
|
+
resolutionCache.set(cacheKey, rootResolved);
|
|
9333
|
+
return rootResolved;
|
|
9334
|
+
}
|
|
9335
|
+
resolutionCache.set(cacheKey, null);
|
|
9290
9336
|
throw new Error(`Cannot find module '${id}'`);
|
|
9291
9337
|
};
|
|
9292
9338
|
const loadModule = (resolvedPath) => {
|
|
@@ -9308,19 +9354,25 @@ let __tla = (async () => {
|
|
|
9308
9354
|
module.loaded = true;
|
|
9309
9355
|
return module;
|
|
9310
9356
|
}
|
|
9311
|
-
|
|
9357
|
+
const rawCode = vfs.readFileSync(resolvedPath, "utf8");
|
|
9312
9358
|
const dirname$1 = dirname(resolvedPath);
|
|
9313
|
-
const
|
|
9314
|
-
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
|
|
9359
|
+
const codeCacheKey = `${resolvedPath}|${simpleHash(rawCode)}`;
|
|
9360
|
+
let code = processedCodeCache == null ? void 0 : processedCodeCache.get(codeCacheKey);
|
|
9361
|
+
if (!code) {
|
|
9362
|
+
code = rawCode;
|
|
9363
|
+
const isCjsFile = resolvedPath.endsWith(".cjs");
|
|
9364
|
+
const isAlreadyBundledCjs = code.startsWith('"use strict";\nvar __') || code.startsWith("'use strict';\nvar __");
|
|
9365
|
+
const hasEsmImport = /\bimport\s+[\w{*'"]/m.test(code);
|
|
9366
|
+
const hasEsmExport = /\bexport\s+(?:default|const|let|var|function|class|{|\*)/m.test(code);
|
|
9367
|
+
if (!isCjsFile && !isAlreadyBundledCjs) {
|
|
9368
|
+
if (resolvedPath.endsWith(".mjs") || resolvedPath.includes("/esm/") || hasEsmImport || hasEsmExport) {
|
|
9369
|
+
code = transformEsmToCjs(code, resolvedPath);
|
|
9370
|
+
}
|
|
9371
|
+
}
|
|
9372
|
+
code = transformDynamicImports(code);
|
|
9373
|
+
processedCodeCache == null ? void 0 : processedCodeCache.set(codeCacheKey, code);
|
|
9374
|
+
}
|
|
9375
|
+
const moduleRequire = createRequire(vfs, fsShim, process, dirname$1, moduleCache, options, processedCodeCache);
|
|
9324
9376
|
moduleRequire.cache = moduleCache;
|
|
9325
9377
|
const consoleWrapper = createConsoleWrapper(options.onConsole);
|
|
9326
9378
|
try {
|
|
@@ -9492,6 +9544,7 @@ ${code}
|
|
|
9492
9544
|
__publicField(this, "process");
|
|
9493
9545
|
__publicField(this, "moduleCache", {});
|
|
9494
9546
|
__publicField(this, "options");
|
|
9547
|
+
__publicField(this, "processedCodeCache", /* @__PURE__ */ new Map());
|
|
9495
9548
|
__publicField(this, "executeSync", this.execute);
|
|
9496
9549
|
__publicField(this, "runFileSync", this.runFile);
|
|
9497
9550
|
this.vfs = vfs2;
|
|
@@ -9576,7 +9629,7 @@ ${code}
|
|
|
9576
9629
|
execute(code, filename = "/index.js") {
|
|
9577
9630
|
const dirname$1 = dirname(filename);
|
|
9578
9631
|
this.vfs.writeFileSync(filename, code);
|
|
9579
|
-
const require = createRequire(this.vfs, this.fsShim, this.process, dirname$1, this.moduleCache, this.options);
|
|
9632
|
+
const require = createRequire(this.vfs, this.fsShim, this.process, dirname$1, this.moduleCache, this.options, this.processedCodeCache);
|
|
9580
9633
|
const module = {
|
|
9581
9634
|
id: filename,
|
|
9582
9635
|
filename,
|
|
@@ -9658,7 +9711,7 @@ ${code}
|
|
|
9658
9711
|
__publicField(this, "deleteListener", null);
|
|
9659
9712
|
this.vfs = vfs2;
|
|
9660
9713
|
this.options = options2;
|
|
9661
|
-
this.worker = new Worker(new URL("/assets/runtime-worker-
|
|
9714
|
+
this.worker = new Worker(new URL("/assets/runtime-worker-B8_LZkBX.js", import.meta.url), {
|
|
9662
9715
|
type: "module"
|
|
9663
9716
|
});
|
|
9664
9717
|
this.workerApi = wrap(this.worker);
|
|
@@ -11626,6 +11679,7 @@ console.log('[HMR] React Refresh initialized');
|
|
|
11626
11679
|
__publicField(this, "watcherCleanup", null);
|
|
11627
11680
|
__publicField(this, "options");
|
|
11628
11681
|
__publicField(this, "hmrTargetWindow", null);
|
|
11682
|
+
__publicField(this, "transformCache", /* @__PURE__ */ new Map());
|
|
11629
11683
|
this.options = {
|
|
11630
11684
|
jsx: true,
|
|
11631
11685
|
jsxFactory: "React.createElement",
|
|
@@ -11742,7 +11796,28 @@ console.log('[HMR] React Refresh initialized');
|
|
|
11742
11796
|
async transformAndServe(filePath, urlPath) {
|
|
11743
11797
|
try {
|
|
11744
11798
|
const content = this.vfs.readFileSync(filePath, "utf8");
|
|
11799
|
+
const hash = simpleHash(content);
|
|
11800
|
+
const cached = this.transformCache.get(filePath);
|
|
11801
|
+
if (cached && cached.hash === hash) {
|
|
11802
|
+
const buffer22 = BufferPolyfill.from(cached.code);
|
|
11803
|
+
return {
|
|
11804
|
+
statusCode: 200,
|
|
11805
|
+
statusMessage: "OK",
|
|
11806
|
+
headers: {
|
|
11807
|
+
"Content-Type": "application/javascript; charset=utf-8",
|
|
11808
|
+
"Content-Length": String(buffer22.length),
|
|
11809
|
+
"Cache-Control": "no-cache",
|
|
11810
|
+
"X-Transformed": "true",
|
|
11811
|
+
"X-Cache": "hit"
|
|
11812
|
+
},
|
|
11813
|
+
body: buffer22
|
|
11814
|
+
};
|
|
11815
|
+
}
|
|
11745
11816
|
const transformed = await this.transformCode(content, urlPath);
|
|
11817
|
+
this.transformCache.set(filePath, {
|
|
11818
|
+
code: transformed,
|
|
11819
|
+
hash
|
|
11820
|
+
});
|
|
11746
11821
|
const buffer2 = BufferPolyfill.from(transformed);
|
|
11747
11822
|
return {
|
|
11748
11823
|
statusCode: 200,
|
|
@@ -12493,6 +12568,7 @@ export default function Head({ children }) {
|
|
|
12493
12568
|
__publicField(this, "watcherCleanup", null);
|
|
12494
12569
|
__publicField(this, "hmrTargetWindow", null);
|
|
12495
12570
|
__publicField(this, "options");
|
|
12571
|
+
__publicField(this, "transformCache", /* @__PURE__ */ new Map());
|
|
12496
12572
|
this.options = options2;
|
|
12497
12573
|
this.pagesDir = options2.pagesDir || "/pages";
|
|
12498
12574
|
this.appDir = options2.appDir || "/app";
|
|
@@ -12557,6 +12633,9 @@ export default function Head({ children }) {
|
|
|
12557
12633
|
if (pathname.startsWith("/_next/pages/")) {
|
|
12558
12634
|
return this.servePageComponent(pathname);
|
|
12559
12635
|
}
|
|
12636
|
+
if (pathname.startsWith("/_next/app/")) {
|
|
12637
|
+
return this.serveAppComponent(pathname);
|
|
12638
|
+
}
|
|
12560
12639
|
if (pathname.startsWith("/_next/static/")) {
|
|
12561
12640
|
return this.serveStaticAsset(pathname);
|
|
12562
12641
|
}
|
|
@@ -12621,6 +12700,22 @@ export default function Head({ children }) {
|
|
|
12621
12700
|
}
|
|
12622
12701
|
return this.transformAndServe(pageFile, pageFile);
|
|
12623
12702
|
}
|
|
12703
|
+
async serveAppComponent(pathname) {
|
|
12704
|
+
const filePath = pathname.replace("/_next/app", "").replace(/\.js$/, "");
|
|
12705
|
+
const extensions = [
|
|
12706
|
+
".tsx",
|
|
12707
|
+
".jsx",
|
|
12708
|
+
".ts",
|
|
12709
|
+
".js"
|
|
12710
|
+
];
|
|
12711
|
+
for (const ext of extensions) {
|
|
12712
|
+
const fullPath = filePath + ext;
|
|
12713
|
+
if (this.exists(fullPath)) {
|
|
12714
|
+
return this.transformAndServe(fullPath, fullPath);
|
|
12715
|
+
}
|
|
12716
|
+
}
|
|
12717
|
+
return this.notFound(pathname);
|
|
12718
|
+
}
|
|
12624
12719
|
async handleApiRoute(method, pathname, headers, body) {
|
|
12625
12720
|
const apiFile = this.resolveApiFile(pathname);
|
|
12626
12721
|
if (!apiFile) {
|
|
@@ -13177,11 +13272,9 @@ export default function Head({ children }) {
|
|
|
13177
13272
|
globalCssLinks.push(`<link rel="stylesheet" href="${virtualPrefix}${cssPath}">`);
|
|
13178
13273
|
}
|
|
13179
13274
|
}
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
let nestedJsx = "React.createElement(Page)";
|
|
13275
|
+
virtualPrefix + route.page;
|
|
13276
|
+
route.layouts.map((layout, i) => `import Layout${i} from '${virtualPrefix}${layout}';`).join("\n ");
|
|
13183
13277
|
for (let i = route.layouts.length - 1; i >= 0; i--) {
|
|
13184
|
-
nestedJsx = `React.createElement(Layout${i}, null, ${nestedJsx})`;
|
|
13185
13278
|
}
|
|
13186
13279
|
const envScript = this.generateEnvScript();
|
|
13187
13280
|
return `<!DOCTYPE html>
|
|
@@ -13225,17 +13318,117 @@ export default function Head({ children }) {
|
|
|
13225
13318
|
<script type="module">
|
|
13226
13319
|
import React from 'react';
|
|
13227
13320
|
import ReactDOM from 'react-dom/client';
|
|
13228
|
-
import Page from '${pageModulePath}';
|
|
13229
|
-
${layoutImports}
|
|
13230
13321
|
|
|
13231
|
-
|
|
13232
|
-
|
|
13322
|
+
const virtualBase = '${virtualPrefix}';
|
|
13323
|
+
|
|
13324
|
+
// Convert URL path to app router page module path
|
|
13325
|
+
function getAppPageModulePath(pathname) {
|
|
13326
|
+
let route = pathname;
|
|
13327
|
+
if (route.startsWith(virtualBase)) {
|
|
13328
|
+
route = route.slice(virtualBase.length);
|
|
13329
|
+
}
|
|
13330
|
+
route = route.replace(/^\\/+/, '/') || '/';
|
|
13331
|
+
// App Router: / -> /app/page, /about -> /app/about/page
|
|
13332
|
+
const pagePath = route === '/' ? '/app/page' : '/app' + route + '/page';
|
|
13333
|
+
return virtualBase + '/_next/app' + pagePath + '.js';
|
|
13334
|
+
}
|
|
13335
|
+
|
|
13336
|
+
// Get layout paths for a route
|
|
13337
|
+
function getLayoutPaths(pathname) {
|
|
13338
|
+
let route = pathname;
|
|
13339
|
+
if (route.startsWith(virtualBase)) {
|
|
13340
|
+
route = route.slice(virtualBase.length);
|
|
13341
|
+
}
|
|
13342
|
+
route = route.replace(/^\\/+/, '/') || '/';
|
|
13343
|
+
|
|
13344
|
+
// Build layout paths from root to current route
|
|
13345
|
+
const layouts = [virtualBase + '/_next/app/app/layout.js'];
|
|
13346
|
+
if (route !== '/') {
|
|
13347
|
+
const segments = route.split('/').filter(Boolean);
|
|
13348
|
+
let currentPath = '/app';
|
|
13349
|
+
for (const segment of segments) {
|
|
13350
|
+
currentPath += '/' + segment;
|
|
13351
|
+
layouts.push(virtualBase + '/_next/app' + currentPath + '/layout.js');
|
|
13352
|
+
}
|
|
13353
|
+
}
|
|
13354
|
+
return layouts;
|
|
13233
13355
|
}
|
|
13234
13356
|
|
|
13357
|
+
// Dynamic page loader
|
|
13358
|
+
async function loadPage(pathname) {
|
|
13359
|
+
const modulePath = getAppPageModulePath(pathname);
|
|
13360
|
+
try {
|
|
13361
|
+
const module = await import(/* @vite-ignore */ modulePath);
|
|
13362
|
+
return module.default;
|
|
13363
|
+
} catch (e) {
|
|
13364
|
+
console.error('[Navigation] Failed to load page:', modulePath, e);
|
|
13365
|
+
return null;
|
|
13366
|
+
}
|
|
13367
|
+
}
|
|
13368
|
+
|
|
13369
|
+
// Load layouts (with caching)
|
|
13370
|
+
const layoutCache = new Map();
|
|
13371
|
+
async function loadLayouts(pathname) {
|
|
13372
|
+
const layoutPaths = getLayoutPaths(pathname);
|
|
13373
|
+
const layouts = [];
|
|
13374
|
+
for (const path of layoutPaths) {
|
|
13375
|
+
if (layoutCache.has(path)) {
|
|
13376
|
+
layouts.push(layoutCache.get(path));
|
|
13377
|
+
} else {
|
|
13378
|
+
try {
|
|
13379
|
+
const module = await import(/* @vite-ignore */ path);
|
|
13380
|
+
layoutCache.set(path, module.default);
|
|
13381
|
+
layouts.push(module.default);
|
|
13382
|
+
} catch (e) {
|
|
13383
|
+
// Layout might not exist for this segment, skip
|
|
13384
|
+
}
|
|
13385
|
+
}
|
|
13386
|
+
}
|
|
13387
|
+
return layouts;
|
|
13388
|
+
}
|
|
13389
|
+
|
|
13390
|
+
// Router component
|
|
13391
|
+
function Router() {
|
|
13392
|
+
const [Page, setPage] = React.useState(null);
|
|
13393
|
+
const [layouts, setLayouts] = React.useState([]);
|
|
13394
|
+
const [path, setPath] = React.useState(window.location.pathname);
|
|
13395
|
+
|
|
13396
|
+
React.useEffect(() => {
|
|
13397
|
+
Promise.all([loadPage(path), loadLayouts(path)]).then(([P, L]) => {
|
|
13398
|
+
if (P) setPage(() => P);
|
|
13399
|
+
setLayouts(L);
|
|
13400
|
+
});
|
|
13401
|
+
}, []);
|
|
13402
|
+
|
|
13403
|
+
React.useEffect(() => {
|
|
13404
|
+
const handleNavigation = async () => {
|
|
13405
|
+
const newPath = window.location.pathname;
|
|
13406
|
+
if (newPath !== path) {
|
|
13407
|
+
setPath(newPath);
|
|
13408
|
+
const [P, L] = await Promise.all([loadPage(newPath), loadLayouts(newPath)]);
|
|
13409
|
+
if (P) setPage(() => P);
|
|
13410
|
+
setLayouts(L);
|
|
13411
|
+
}
|
|
13412
|
+
};
|
|
13413
|
+
window.addEventListener('popstate', handleNavigation);
|
|
13414
|
+
return () => window.removeEventListener('popstate', handleNavigation);
|
|
13415
|
+
}, [path]);
|
|
13416
|
+
|
|
13417
|
+
if (!Page) return null;
|
|
13418
|
+
|
|
13419
|
+
// Build nested layout structure
|
|
13420
|
+
let content = React.createElement(Page);
|
|
13421
|
+
for (let i = layouts.length - 1; i >= 0; i--) {
|
|
13422
|
+
content = React.createElement(layouts[i], null, content);
|
|
13423
|
+
}
|
|
13424
|
+
return content;
|
|
13425
|
+
}
|
|
13426
|
+
|
|
13427
|
+
// Mark that we've initialized (for testing no-reload)
|
|
13428
|
+
window.__NEXT_INITIALIZED__ = Date.now();
|
|
13429
|
+
|
|
13235
13430
|
ReactDOM.createRoot(document.getElementById('__next')).render(
|
|
13236
|
-
React.createElement(React.StrictMode, null,
|
|
13237
|
-
React.createElement(App)
|
|
13238
|
-
)
|
|
13431
|
+
React.createElement(React.StrictMode, null, React.createElement(Router))
|
|
13239
13432
|
);
|
|
13240
13433
|
<\/script>
|
|
13241
13434
|
</body>
|
|
@@ -13490,7 +13683,28 @@ export default function Head({ children }) {
|
|
|
13490
13683
|
async transformAndServe(filePath, urlPath) {
|
|
13491
13684
|
try {
|
|
13492
13685
|
const content = this.vfs.readFileSync(filePath, "utf8");
|
|
13686
|
+
const hash = simpleHash(content);
|
|
13687
|
+
const cached = this.transformCache.get(filePath);
|
|
13688
|
+
if (cached && cached.hash === hash) {
|
|
13689
|
+
const buffer22 = BufferPolyfill.from(cached.code);
|
|
13690
|
+
return {
|
|
13691
|
+
statusCode: 200,
|
|
13692
|
+
statusMessage: "OK",
|
|
13693
|
+
headers: {
|
|
13694
|
+
"Content-Type": "application/javascript; charset=utf-8",
|
|
13695
|
+
"Content-Length": String(buffer22.length),
|
|
13696
|
+
"Cache-Control": "no-cache",
|
|
13697
|
+
"X-Transformed": "true",
|
|
13698
|
+
"X-Cache": "hit"
|
|
13699
|
+
},
|
|
13700
|
+
body: buffer22
|
|
13701
|
+
};
|
|
13702
|
+
}
|
|
13493
13703
|
const transformed = await this.transformCode(content, urlPath);
|
|
13704
|
+
this.transformCache.set(filePath, {
|
|
13705
|
+
code: transformed,
|
|
13706
|
+
hash
|
|
13707
|
+
});
|
|
13494
13708
|
const buffer2 = BufferPolyfill.from(transformed);
|
|
13495
13709
|
return {
|
|
13496
13710
|
statusCode: 200,
|