@absolutejs/absolute 0.19.0-beta.172 → 0.19.0-beta.174
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/ROADMAP.md +0 -23
- package/dist/cli/index.js +47 -15
- package/dist/index.js +160 -11
- package/dist/index.js.map +5 -4
- package/dist/src/core/prerender.d.ts +12 -1
- package/dist/types/build.d.ts +2 -0
- package/package.json +1 -1
- package/types/build.ts +2 -0
package/ROADMAP.md
CHANGED
|
@@ -4,29 +4,6 @@ Features missing from AbsoluteJS that Next.js provides, ordered by priority. Eac
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## P0 — Static Site Generation (SSG)
|
|
8
|
-
|
|
9
|
-
**What Next.js does:**
|
|
10
|
-
Pages can be pre-rendered at build time into static HTML. `generateStaticParams()` tells the framework which dynamic routes to pre-render. The output is plain HTML + JS that can be served from a CDN with zero server runtime. Next.js also supports a full `output: 'export'` mode that produces a completely static site.
|
|
11
|
-
|
|
12
|
-
**What AbsoluteJS has today:**
|
|
13
|
-
Nothing. Every page is rendered at request time via streaming SSR. The `handleHTMLPageRequest` serves pre-written HTML files, but there's no mechanism to run a React/Svelte/Vue component through SSR at build time and save the output.
|
|
14
|
-
|
|
15
|
-
**What needs to be built:**
|
|
16
|
-
- A `static` option per-route or per-page that tells the build to render the component and write the HTML to disk
|
|
17
|
-
- For dynamic routes, a way to declare the set of params to pre-render (equivalent to `generateStaticParams`)
|
|
18
|
-
- A static export mode that produces a directory of HTML/CSS/JS with no server dependency
|
|
19
|
-
- The build pipeline already has streaming SSR for all frameworks — the core work is calling those renderers during `build()` instead of at request time, and writing the output to files
|
|
20
|
-
- Static pages should still hydrate on the client (same as today, just the initial HTML comes from disk instead of runtime SSR)
|
|
21
|
-
|
|
22
|
-
**Files likely involved:**
|
|
23
|
-
- `src/core/build.ts` — add a static rendering pass after bundling
|
|
24
|
-
- Each framework's `pageHandler.ts` — extract the rendering logic so it can be called at build time without an HTTP request
|
|
25
|
-
- `src/build/generateManifest.ts` — static pages need manifest entries pointing to `.html` files
|
|
26
|
-
- New: a config option or per-page export to opt into static rendering
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
7
|
## P0 — Metadata API / SEO
|
|
31
8
|
|
|
32
9
|
**What Next.js does:**
|
package/dist/cli/index.js
CHANGED
|
@@ -529,12 +529,27 @@ var init_devCert = __esm(() => {
|
|
|
529
529
|
// src/core/prerender.ts
|
|
530
530
|
var exports_prerender = {};
|
|
531
531
|
__export(exports_prerender, {
|
|
532
|
+
routeToFilename: () => routeToFilename,
|
|
533
|
+
rerenderRoute: () => rerenderRoute,
|
|
534
|
+
readTimestamp: () => readTimestamp,
|
|
532
535
|
prerenderWithServer: () => prerenderWithServer,
|
|
533
|
-
prerender: () => prerender
|
|
536
|
+
prerender: () => prerender,
|
|
537
|
+
PRERENDER_BYPASS_HEADER: () => PRERENDER_BYPASS_HEADER
|
|
534
538
|
});
|
|
535
539
|
import { mkdirSync as mkdirSync3 } from "fs";
|
|
536
540
|
import { join as join5 } from "path";
|
|
537
|
-
var routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1).replace(/\//g, "-")}.html`,
|
|
541
|
+
var PRERENDER_BYPASS_HEADER = "X-Absolute-Prerender-Bypass", routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1).replace(/\//g, "-")}.html`, writeTimestamp = async (htmlPath) => {
|
|
542
|
+
const metaPath = htmlPath.replace(/\.html$/, ".meta");
|
|
543
|
+
await Bun.write(metaPath, String(Date.now()));
|
|
544
|
+
}, readTimestamp = (htmlPath) => {
|
|
545
|
+
const metaPath = htmlPath.replace(/\.html$/, ".meta");
|
|
546
|
+
try {
|
|
547
|
+
const content = __require("fs").readFileSync(metaPath, "utf-8");
|
|
548
|
+
return Number(content) || 0;
|
|
549
|
+
} catch {
|
|
550
|
+
return 0;
|
|
551
|
+
}
|
|
552
|
+
}, crawlRoutes = async (baseUrl) => {
|
|
538
553
|
const visited = new Set;
|
|
539
554
|
const queue = ["/"];
|
|
540
555
|
const routes = [];
|
|
@@ -563,6 +578,22 @@ var routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1
|
|
|
563
578
|
} catch {}
|
|
564
579
|
}
|
|
565
580
|
return routes;
|
|
581
|
+
}, rerenderRoute = async (route, port, prerenderDir) => {
|
|
582
|
+
try {
|
|
583
|
+
const res = await fetch(`http://localhost:${port}${route}`, {
|
|
584
|
+
headers: { [PRERENDER_BYPASS_HEADER]: "1" }
|
|
585
|
+
});
|
|
586
|
+
if (!res.ok)
|
|
587
|
+
return false;
|
|
588
|
+
const html = await res.text();
|
|
589
|
+
const fileName = routeToFilename(route);
|
|
590
|
+
const filePath = join5(prerenderDir, fileName);
|
|
591
|
+
await Bun.write(filePath, html);
|
|
592
|
+
await writeTimestamp(filePath);
|
|
593
|
+
return true;
|
|
594
|
+
} catch {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
566
597
|
}, prerender = async (port, outDir, staticConfig, log) => {
|
|
567
598
|
const prerenderDir = join5(outDir, "_prerendered");
|
|
568
599
|
mkdirSync3(prerenderDir, { recursive: true });
|
|
@@ -570,7 +601,7 @@ var routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1
|
|
|
570
601
|
let routes;
|
|
571
602
|
if (staticConfig.routes === "all") {
|
|
572
603
|
log?.("Crawling routes...");
|
|
573
|
-
routes = await crawlRoutes(baseUrl
|
|
604
|
+
routes = await crawlRoutes(baseUrl);
|
|
574
605
|
} else {
|
|
575
606
|
routes = staticConfig.routes;
|
|
576
607
|
}
|
|
@@ -589,6 +620,7 @@ var routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1
|
|
|
589
620
|
const fileName = routeToFilename(route);
|
|
590
621
|
const filePath = join5(prerenderDir, fileName);
|
|
591
622
|
await Bun.write(filePath, html);
|
|
623
|
+
await writeTimestamp(filePath);
|
|
592
624
|
result.routes.set(route, filePath);
|
|
593
625
|
log?.(` Pre-rendered ${route} \u2192 ${fileName} (${html.length} bytes)`);
|
|
594
626
|
} catch {
|
|
@@ -637,7 +669,7 @@ import {
|
|
|
637
669
|
readFileSync as readFileSync7,
|
|
638
670
|
unlinkSync
|
|
639
671
|
} from "fs";
|
|
640
|
-
import { basename as
|
|
672
|
+
import { basename as basename2, join as join6, relative, resolve as resolve6 } from "path";
|
|
641
673
|
var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, collectFiles2 = (dir) => {
|
|
642
674
|
const results = [];
|
|
643
675
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
@@ -668,7 +700,7 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
668
700
|
return;
|
|
669
701
|
}, generateEntrypoint = (distDir, serverEntry, prerenderMap, version2) => {
|
|
670
702
|
const allFiles = collectFiles2(distDir);
|
|
671
|
-
const serverBundleName =
|
|
703
|
+
const serverBundleName = basename2(serverEntry).replace(/\.[^.]+$/, "") + ".js";
|
|
672
704
|
const skip = new Set([
|
|
673
705
|
serverBundleName,
|
|
674
706
|
"manifest.json",
|
|
@@ -837,7 +869,7 @@ console.log(\`
|
|
|
837
869
|
}), FRAMEWORK_EXTERNALS, compile = async (serverEntry, outdir, outfile, configPath2) => {
|
|
838
870
|
const prerenderPort = Number(env3.COMPILE_PORT) || Number(env3.PORT) || DEFAULT_PORT + 1;
|
|
839
871
|
killStaleProcesses(prerenderPort);
|
|
840
|
-
const entryName =
|
|
872
|
+
const entryName = basename2(serverEntry).replace(/\.[^.]+$/, "");
|
|
841
873
|
const resolvedOutdir = resolve6(outdir ?? "dist");
|
|
842
874
|
const resolvedOutfile = resolve6(outfile ?? "compiled-server");
|
|
843
875
|
const absoluteVersion = resolvePackageVersion2([
|
|
@@ -886,7 +918,7 @@ console.log(\`
|
|
|
886
918
|
}
|
|
887
919
|
console.log(` \x1B[2m(${getDurationString(performance.now() - bundleStart)})\x1B[0m`);
|
|
888
920
|
const prerenderStart = performance.now();
|
|
889
|
-
|
|
921
|
+
process.stdout.write(cliTag3("\x1B[36m", "Pre-rendering pages"));
|
|
890
922
|
const staticConfig = buildConfig.static ?? { routes: "all" };
|
|
891
923
|
const prerenderResult = await prerenderWithServer(outputPath, prerenderPort, resolvedOutdir, staticConfig, {
|
|
892
924
|
ABSOLUTE_BUILD_DIR: resolvedOutdir,
|
|
@@ -894,9 +926,9 @@ console.log(\`
|
|
|
894
926
|
FORCE_COLOR: "0",
|
|
895
927
|
NODE_ENV: "production",
|
|
896
928
|
...configPath2 ? { ABSOLUTE_CONFIG: configPath2 } : {}
|
|
897
|
-
}
|
|
929
|
+
});
|
|
898
930
|
const prerenderMap = prerenderResult.routes;
|
|
899
|
-
console.log(
|
|
931
|
+
console.log(` \x1B[2m(${prerenderMap.size} pages, ${getDurationString(performance.now() - prerenderStart)})\x1B[0m`);
|
|
900
932
|
const compileStart = performance.now();
|
|
901
933
|
process.stdout.write(cliTag3("\x1B[36m", "Compiling standalone executable"));
|
|
902
934
|
const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion);
|
|
@@ -920,7 +952,7 @@ console.log(\`
|
|
|
920
952
|
const size = (Bun.file(resolvedOutfile).size / 1048576).toFixed(0);
|
|
921
953
|
const totalDuration = getDurationString(performance.now() - totalStart);
|
|
922
954
|
console.log(cliTag3("\x1B[32m", `Compiled to ${resolvedOutfile} (${size}MB) in ${totalDuration}`));
|
|
923
|
-
console.log(cliTag3("\x1B[2m", `Run with: ./${
|
|
955
|
+
console.log(cliTag3("\x1B[2m", `Run with: ./${basename2(resolvedOutfile)}`));
|
|
924
956
|
sendTelemetryEvent("compile:complete", {
|
|
925
957
|
durationMs: Math.round(performance.now() - totalStart),
|
|
926
958
|
entry: serverEntry,
|
|
@@ -1803,7 +1835,7 @@ init_telemetryEvent();
|
|
|
1803
1835
|
init_utils();
|
|
1804
1836
|
var {env: env2 } = globalThis.Bun;
|
|
1805
1837
|
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
1806
|
-
import { basename
|
|
1838
|
+
import { basename, resolve as resolve5 } from "path";
|
|
1807
1839
|
var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`;
|
|
1808
1840
|
var resolvePackageVersion = (candidates) => {
|
|
1809
1841
|
for (const candidate of candidates) {
|
|
@@ -1857,7 +1889,7 @@ var handleBundleFailure = (serverBundle, bundleStart, serverEntry) => {
|
|
|
1857
1889
|
var start = async (serverEntry, outdir, configPath2) => {
|
|
1858
1890
|
const port = Number(env2.PORT) || DEFAULT_PORT;
|
|
1859
1891
|
killStaleProcesses(port);
|
|
1860
|
-
const entryName =
|
|
1892
|
+
const entryName = basename(serverEntry).replace(/\.[^.]+$/, "");
|
|
1861
1893
|
const resolvedOutdir = resolve5(outdir ?? "dist");
|
|
1862
1894
|
const absoluteVersion = resolvePackageVersion([
|
|
1863
1895
|
resolve5(import.meta.dir, "..", "..", "..", "package.json"),
|
|
@@ -1989,7 +2021,7 @@ var start = async (serverEntry, outdir, configPath2) => {
|
|
|
1989
2021
|
});
|
|
1990
2022
|
if (buildConfig.static) {
|
|
1991
2023
|
const prerenderStart = performance.now();
|
|
1992
|
-
|
|
2024
|
+
process.stdout.write(cliTag2("\x1B[36m", "Pre-rendering static pages"));
|
|
1993
2025
|
const { prerenderWithServer: prerenderWithServer2 } = await Promise.resolve().then(() => (init_prerender(), exports_prerender));
|
|
1994
2026
|
const prerenderPort = port + 1;
|
|
1995
2027
|
try {
|
|
@@ -2000,9 +2032,9 @@ var start = async (serverEntry, outdir, configPath2) => {
|
|
|
2000
2032
|
FORCE_COLOR: "0",
|
|
2001
2033
|
NODE_ENV: "production",
|
|
2002
2034
|
...configPath2 ? { ABSOLUTE_CONFIG: configPath2 } : {}
|
|
2003
|
-
}
|
|
2035
|
+
});
|
|
2004
2036
|
const prerenderDuration = getDurationString(performance.now() - prerenderStart);
|
|
2005
|
-
console.log(
|
|
2037
|
+
console.log(` \x1B[2m(${result.routes.size} pages, ${prerenderDuration})\x1B[0m`);
|
|
2006
2038
|
} catch (err) {
|
|
2007
2039
|
console.error(cliTag2("\x1B[33m", "Pre-rendering failed, pages will use SSR."));
|
|
2008
2040
|
console.error(err);
|
package/dist/index.js
CHANGED
|
@@ -205630,6 +205630,137 @@ var init_hmr = __esm(() => {
|
|
|
205630
205630
|
init_webSocket();
|
|
205631
205631
|
});
|
|
205632
205632
|
|
|
205633
|
+
// src/core/prerender.ts
|
|
205634
|
+
var exports_prerender = {};
|
|
205635
|
+
__export(exports_prerender, {
|
|
205636
|
+
routeToFilename: () => routeToFilename,
|
|
205637
|
+
rerenderRoute: () => rerenderRoute,
|
|
205638
|
+
readTimestamp: () => readTimestamp,
|
|
205639
|
+
prerenderWithServer: () => prerenderWithServer,
|
|
205640
|
+
prerender: () => prerender,
|
|
205641
|
+
PRERENDER_BYPASS_HEADER: () => PRERENDER_BYPASS_HEADER
|
|
205642
|
+
});
|
|
205643
|
+
import { mkdirSync as mkdirSync10 } from "fs";
|
|
205644
|
+
import { join as join17 } from "path";
|
|
205645
|
+
var PRERENDER_BYPASS_HEADER = "X-Absolute-Prerender-Bypass", routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1).replace(/\//g, "-")}.html`, writeTimestamp = async (htmlPath) => {
|
|
205646
|
+
const metaPath = htmlPath.replace(/\.html$/, ".meta");
|
|
205647
|
+
await Bun.write(metaPath, String(Date.now()));
|
|
205648
|
+
}, readTimestamp = (htmlPath) => {
|
|
205649
|
+
const metaPath = htmlPath.replace(/\.html$/, ".meta");
|
|
205650
|
+
try {
|
|
205651
|
+
const content = __require("fs").readFileSync(metaPath, "utf-8");
|
|
205652
|
+
return Number(content) || 0;
|
|
205653
|
+
} catch {
|
|
205654
|
+
return 0;
|
|
205655
|
+
}
|
|
205656
|
+
}, crawlRoutes = async (baseUrl) => {
|
|
205657
|
+
const visited = new Set;
|
|
205658
|
+
const queue = ["/"];
|
|
205659
|
+
const routes = [];
|
|
205660
|
+
while (queue.length > 0) {
|
|
205661
|
+
const path = queue.shift();
|
|
205662
|
+
if (visited.has(path))
|
|
205663
|
+
continue;
|
|
205664
|
+
visited.add(path);
|
|
205665
|
+
try {
|
|
205666
|
+
const res = await fetch(`${baseUrl}${path}`);
|
|
205667
|
+
if (!res.ok)
|
|
205668
|
+
continue;
|
|
205669
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
205670
|
+
if (!contentType.includes("text/html"))
|
|
205671
|
+
continue;
|
|
205672
|
+
const html = await res.text();
|
|
205673
|
+
routes.push(path);
|
|
205674
|
+
const linkRegex = /href=["'](\/[^"']*?)["']/g;
|
|
205675
|
+
let match;
|
|
205676
|
+
while ((match = linkRegex.exec(html)) !== null) {
|
|
205677
|
+
const href = match[1] ?? "";
|
|
205678
|
+
if (!href || href.includes(".") || href.includes("#") || visited.has(href))
|
|
205679
|
+
continue;
|
|
205680
|
+
queue.push(href);
|
|
205681
|
+
}
|
|
205682
|
+
} catch {}
|
|
205683
|
+
}
|
|
205684
|
+
return routes;
|
|
205685
|
+
}, rerenderRoute = async (route, port, prerenderDir) => {
|
|
205686
|
+
try {
|
|
205687
|
+
const res = await fetch(`http://localhost:${port}${route}`, {
|
|
205688
|
+
headers: { [PRERENDER_BYPASS_HEADER]: "1" }
|
|
205689
|
+
});
|
|
205690
|
+
if (!res.ok)
|
|
205691
|
+
return false;
|
|
205692
|
+
const html = await res.text();
|
|
205693
|
+
const fileName = routeToFilename(route);
|
|
205694
|
+
const filePath = join17(prerenderDir, fileName);
|
|
205695
|
+
await Bun.write(filePath, html);
|
|
205696
|
+
await writeTimestamp(filePath);
|
|
205697
|
+
return true;
|
|
205698
|
+
} catch {
|
|
205699
|
+
return false;
|
|
205700
|
+
}
|
|
205701
|
+
}, prerender = async (port, outDir, staticConfig, log2) => {
|
|
205702
|
+
const prerenderDir = join17(outDir, "_prerendered");
|
|
205703
|
+
mkdirSync10(prerenderDir, { recursive: true });
|
|
205704
|
+
const baseUrl = `http://localhost:${port}`;
|
|
205705
|
+
let routes;
|
|
205706
|
+
if (staticConfig.routes === "all") {
|
|
205707
|
+
log2?.("Crawling routes...");
|
|
205708
|
+
routes = await crawlRoutes(baseUrl);
|
|
205709
|
+
} else {
|
|
205710
|
+
routes = staticConfig.routes;
|
|
205711
|
+
}
|
|
205712
|
+
const result = {
|
|
205713
|
+
routes: new Map,
|
|
205714
|
+
dir: prerenderDir
|
|
205715
|
+
};
|
|
205716
|
+
for (const route of routes) {
|
|
205717
|
+
try {
|
|
205718
|
+
const res = await fetch(`${baseUrl}${route}`);
|
|
205719
|
+
if (!res.ok) {
|
|
205720
|
+
log2?.(` Skipped ${route} (HTTP ${res.status})`);
|
|
205721
|
+
continue;
|
|
205722
|
+
}
|
|
205723
|
+
const html = await res.text();
|
|
205724
|
+
const fileName = routeToFilename(route);
|
|
205725
|
+
const filePath = join17(prerenderDir, fileName);
|
|
205726
|
+
await Bun.write(filePath, html);
|
|
205727
|
+
await writeTimestamp(filePath);
|
|
205728
|
+
result.routes.set(route, filePath);
|
|
205729
|
+
log2?.(` Pre-rendered ${route} \u2192 ${fileName} (${html.length} bytes)`);
|
|
205730
|
+
} catch {
|
|
205731
|
+
log2?.(` Failed to pre-render ${route}`);
|
|
205732
|
+
}
|
|
205733
|
+
}
|
|
205734
|
+
return result;
|
|
205735
|
+
}, prerenderWithServer = async (serverBundlePath, port, outDir, staticConfig, env3, log2) => {
|
|
205736
|
+
const serverProcess = Bun.spawn(["bun", "run", serverBundlePath], {
|
|
205737
|
+
cwd: process.cwd(),
|
|
205738
|
+
env: { ...process.env, ...env3, PORT: String(port) },
|
|
205739
|
+
stdout: "pipe",
|
|
205740
|
+
stderr: "pipe"
|
|
205741
|
+
});
|
|
205742
|
+
let ready = false;
|
|
205743
|
+
for (let i = 0;i < 50; i++) {
|
|
205744
|
+
try {
|
|
205745
|
+
const res = await fetch(`http://localhost:${port}/`);
|
|
205746
|
+
if (res.ok) {
|
|
205747
|
+
ready = true;
|
|
205748
|
+
break;
|
|
205749
|
+
}
|
|
205750
|
+
} catch {}
|
|
205751
|
+
await Bun.sleep(100);
|
|
205752
|
+
}
|
|
205753
|
+
if (!ready) {
|
|
205754
|
+
serverProcess.kill();
|
|
205755
|
+
throw new Error("Server failed to start for pre-rendering");
|
|
205756
|
+
}
|
|
205757
|
+
const result = await prerender(port, outDir, staticConfig, log2);
|
|
205758
|
+
serverProcess.kill();
|
|
205759
|
+
await serverProcess.exited;
|
|
205760
|
+
return result;
|
|
205761
|
+
};
|
|
205762
|
+
var init_prerender = () => {};
|
|
205763
|
+
|
|
205633
205764
|
// src/dev/devCert.ts
|
|
205634
205765
|
var exports_devCert = {};
|
|
205635
205766
|
__export(exports_devCert, {
|
|
@@ -205639,9 +205770,9 @@ __export(exports_devCert, {
|
|
|
205639
205770
|
hasCert: () => hasCert,
|
|
205640
205771
|
ensureDevCert: () => ensureDevCert
|
|
205641
205772
|
});
|
|
205642
|
-
import { existsSync as existsSync17, mkdirSync as
|
|
205773
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync11, rmSync as rmSync2 } from "fs";
|
|
205643
205774
|
import { platform as platform3 } from "os";
|
|
205644
|
-
import { join as
|
|
205775
|
+
import { join as join19 } from "path";
|
|
205645
205776
|
var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[36m[dev]\x1B[0m ${msg}`), devWarn = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[33m[dev]\x1B[0m \x1B[33m${msg}\x1B[0m`), certFilesExist = () => existsSync17(CERT_PATH) && existsSync17(KEY_PATH), isCertExpired = () => {
|
|
205646
205777
|
try {
|
|
205647
205778
|
const certPem = readFileSync11(CERT_PATH, "utf-8");
|
|
@@ -205713,7 +205844,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => c
|
|
|
205713
205844
|
generateSelfSigned();
|
|
205714
205845
|
}
|
|
205715
205846
|
}, ensureDevCert = () => {
|
|
205716
|
-
|
|
205847
|
+
mkdirSync11(CERT_DIR, { recursive: true });
|
|
205717
205848
|
if (hasCert()) {
|
|
205718
205849
|
return { cert: CERT_PATH, key: KEY_PATH };
|
|
205719
205850
|
}
|
|
@@ -205840,16 +205971,16 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, devLog = (msg) => c
|
|
|
205840
205971
|
}
|
|
205841
205972
|
rmSync2(CERT_PATH, { force: true });
|
|
205842
205973
|
rmSync2(KEY_PATH, { force: true });
|
|
205843
|
-
|
|
205974
|
+
mkdirSync11(CERT_DIR, { recursive: true });
|
|
205844
205975
|
generateWithMkcert();
|
|
205845
205976
|
console.log("");
|
|
205846
205977
|
devLog("mkcert installed \u2014 HTTPS certificates are now locally trusted");
|
|
205847
205978
|
return true;
|
|
205848
205979
|
};
|
|
205849
205980
|
var init_devCert = __esm(() => {
|
|
205850
|
-
CERT_DIR =
|
|
205851
|
-
CERT_PATH =
|
|
205852
|
-
KEY_PATH =
|
|
205981
|
+
CERT_DIR = join19(process.cwd(), ".absolutejs");
|
|
205982
|
+
CERT_PATH = join19(CERT_DIR, "cert.pem");
|
|
205983
|
+
KEY_PATH = join19(CERT_DIR, "key.pem");
|
|
205853
205984
|
});
|
|
205854
205985
|
// types/client.ts
|
|
205855
205986
|
var hmrState = {
|
|
@@ -205877,7 +206008,7 @@ var handleHTMLPageRequest = (pagePath) => file(pagePath);
|
|
|
205877
206008
|
var handleHTMXPageRequest = (pagePath) => file(pagePath);
|
|
205878
206009
|
// src/core/prepare.ts
|
|
205879
206010
|
import { existsSync as existsSync16, readdirSync as readdirSync2, readFileSync as readFileSync10 } from "fs";
|
|
205880
|
-
import { basename as basename9, join as
|
|
206011
|
+
import { basename as basename9, join as join18, relative as relative10, resolve as resolve23 } from "path";
|
|
205881
206012
|
|
|
205882
206013
|
// src/utils/loadConfig.ts
|
|
205883
206014
|
import { resolve } from "path";
|
|
@@ -206015,7 +206146,7 @@ var loadPrerenderMap = (prerenderDir) => {
|
|
|
206015
206146
|
continue;
|
|
206016
206147
|
const name = basename9(entry, ".html");
|
|
206017
206148
|
const route = name === "index" ? "/" : `/${name}`;
|
|
206018
|
-
map.set(route,
|
|
206149
|
+
map.set(route, join18(prerenderDir, entry));
|
|
206019
206150
|
}
|
|
206020
206151
|
} catch {}
|
|
206021
206152
|
return map;
|
|
@@ -206030,15 +206161,33 @@ var prepare = async (configOrPath) => {
|
|
|
206030
206161
|
const manifest = JSON.parse(readFileSync10(`${buildDir}/manifest.json`, "utf-8"));
|
|
206031
206162
|
const { staticPlugin } = await import("@elysiajs/static");
|
|
206032
206163
|
const staticFiles = staticPlugin({ assets: buildDir, prefix: "" });
|
|
206033
|
-
const prerenderDir =
|
|
206164
|
+
const prerenderDir = join18(buildDir, "_prerendered");
|
|
206034
206165
|
const prerenderMap = loadPrerenderMap(prerenderDir);
|
|
206035
206166
|
if (prerenderMap.size > 0) {
|
|
206036
206167
|
const { Elysia } = await import("elysia");
|
|
206168
|
+
const {
|
|
206169
|
+
PRERENDER_BYPASS_HEADER: PRERENDER_BYPASS_HEADER2,
|
|
206170
|
+
readTimestamp: readTimestamp2,
|
|
206171
|
+
rerenderRoute: rerenderRoute2
|
|
206172
|
+
} = await Promise.resolve().then(() => (init_prerender(), exports_prerender));
|
|
206173
|
+
const revalidateMs = config.static?.revalidate ? config.static.revalidate * 1000 : 0;
|
|
206174
|
+
const port = Number(process.env.PORT) || 3000;
|
|
206175
|
+
const rerendering = new Set;
|
|
206037
206176
|
const prerenderPlugin = new Elysia({ name: "prerendered-pages" }).onRequest(({ request }) => {
|
|
206038
206177
|
const url = new URL(request.url);
|
|
206178
|
+
if (request.headers.get(PRERENDER_BYPASS_HEADER2))
|
|
206179
|
+
return;
|
|
206039
206180
|
const filePath = prerenderMap.get(url.pathname);
|
|
206040
206181
|
if (!filePath)
|
|
206041
206182
|
return;
|
|
206183
|
+
if (revalidateMs > 0 && !rerendering.has(url.pathname)) {
|
|
206184
|
+
const renderedAt = readTimestamp2(filePath);
|
|
206185
|
+
const age = Date.now() - renderedAt;
|
|
206186
|
+
if (age > revalidateMs) {
|
|
206187
|
+
rerendering.add(url.pathname);
|
|
206188
|
+
rerenderRoute2(url.pathname, port, prerenderDir).finally(() => rerendering.delete(url.pathname));
|
|
206189
|
+
}
|
|
206190
|
+
}
|
|
206042
206191
|
return new Response(Bun.file(filePath), {
|
|
206043
206192
|
headers: { "content-type": "text/html; charset=utf-8" }
|
|
206044
206193
|
});
|
|
@@ -206229,5 +206378,5 @@ export {
|
|
|
206229
206378
|
ANGULAR_INIT_TIMEOUT_MS
|
|
206230
206379
|
};
|
|
206231
206380
|
|
|
206232
|
-
//# debugId=
|
|
206381
|
+
//# debugId=D0959AF290C10FEC64756E2164756E21
|
|
206233
206382
|
//# sourceMappingURL=index.js.map
|