@moonsjs/vite 0.1.10 → 0.1.12
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/devtools.d.ts +30 -0
- package/dist/devtools.d.ts.map +1 -0
- package/dist/{index-qz9sc74p.js → index-h66m8653.js} +91 -1
- package/dist/{index-qz9sc74p.js.map → index-h66m8653.js.map} +5 -4
- package/dist/index.js +20 -4
- package/dist/index.js.map +3 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/server/dev.d.ts +3 -0
- package/dist/server/dev.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +126 -45
- package/dist/server/index.js.map +6 -5
- package/dist/server/isr.d.ts +8 -2
- package/dist/server/isr.d.ts.map +1 -1
- package/dist/server/node-server.d.ts +12 -0
- package/dist/server/node-server.d.ts.map +1 -1
- package/dist/server/storage.d.ts +10 -0
- package/dist/server/storage.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/devtools.ts +127 -0
- package/src/plugin.ts +28 -2
- package/src/server/dev.ts +26 -1
- package/src/server/index.ts +1 -0
- package/src/server/isr.ts +16 -2
- package/src/server/node-server.ts +77 -34
- package/src/server/storage.ts +53 -0
package/dist/server/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
toWebRequest2,
|
|
9
9
|
sendNodeResponse2,
|
|
10
10
|
installDevMiddleware2
|
|
11
|
-
} from "../index-
|
|
11
|
+
} from "../index-h66m8653.js";
|
|
12
12
|
|
|
13
13
|
// src/server/handler.ts
|
|
14
14
|
import {
|
|
@@ -467,9 +467,9 @@ function warnPayloadFindings(payload, scan, warned) {
|
|
|
467
467
|
}
|
|
468
468
|
}
|
|
469
469
|
// src/server/node-server.ts
|
|
470
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
470
|
+
import { existsSync, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
471
471
|
import { createServer } from "node:http";
|
|
472
|
-
import { extname, join, resolve, sep } from "node:path";
|
|
472
|
+
import { extname as extname2, join, resolve, sep } from "node:path";
|
|
473
473
|
|
|
474
474
|
// src/server/isr.ts
|
|
475
475
|
import { renameSync, writeFileSync } from "node:fs";
|
|
@@ -510,6 +510,14 @@ async function runRevalidate(options) {
|
|
|
510
510
|
log(`[moons] isr: TIDAK menulis ${options.pathname} — memuat ${labels}`);
|
|
511
511
|
return;
|
|
512
512
|
}
|
|
513
|
+
if (options.storage !== undefined) {
|
|
514
|
+
await options.storage.write(options.pathname, new TextEncoder().encode(html));
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (options.file === undefined) {
|
|
518
|
+
log(`[moons] isr: lewati ${options.pathname} — tanpa file/storage tujuan`);
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
513
521
|
const tmp = `${options.file}.tmp-${process.pid}`;
|
|
514
522
|
writeFileSync(tmp, html);
|
|
515
523
|
renameSync(tmp, options.file);
|
|
@@ -518,6 +526,50 @@ async function runRevalidate(options) {
|
|
|
518
526
|
}
|
|
519
527
|
}
|
|
520
528
|
|
|
529
|
+
// src/server/storage.ts
|
|
530
|
+
import { mkdirSync, readFileSync, renameSync as renameSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
531
|
+
import { dirname, extname } from "node:path";
|
|
532
|
+
function createFileStorage(clientDir) {
|
|
533
|
+
return {
|
|
534
|
+
async read(pathname) {
|
|
535
|
+
const file = resolveStaticFile(clientDir, pathname);
|
|
536
|
+
if (file === null) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
const stat = statSync(file);
|
|
540
|
+
return { body: readFileSync(file), mtimeMs: stat.mtimeMs };
|
|
541
|
+
},
|
|
542
|
+
async write(pathname, body) {
|
|
543
|
+
const target = staticFileTarget(clientDir, pathname);
|
|
544
|
+
if (target === null) {
|
|
545
|
+
throw new Error(`[moons] isr: path tidak valid untuk ditulis: ${pathname}`);
|
|
546
|
+
}
|
|
547
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
548
|
+
const tmp = `${target}.tmp-${process.pid}`;
|
|
549
|
+
writeFileSync2(tmp, body);
|
|
550
|
+
renameSync2(tmp, target);
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
function contentTypeForPathname(pathname) {
|
|
555
|
+
const ext = extname(pathname.split("?")[0] ?? "").toLowerCase();
|
|
556
|
+
return MIME[ext] ?? MIME[".html"] ?? "text/html; charset=utf-8";
|
|
557
|
+
}
|
|
558
|
+
var MIME = {
|
|
559
|
+
".html": "text/html; charset=utf-8",
|
|
560
|
+
".js": "text/javascript; charset=utf-8",
|
|
561
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
562
|
+
".css": "text/css; charset=utf-8",
|
|
563
|
+
".json": "application/json; charset=utf-8",
|
|
564
|
+
".txt": "text/plain; charset=utf-8",
|
|
565
|
+
".svg": "image/svg+xml",
|
|
566
|
+
".ico": "image/x-icon",
|
|
567
|
+
".png": "image/png",
|
|
568
|
+
".webp": "image/webp",
|
|
569
|
+
".woff": "font/woff",
|
|
570
|
+
".woff2": "font/woff2"
|
|
571
|
+
};
|
|
572
|
+
|
|
521
573
|
// src/server/shutdown.ts
|
|
522
574
|
function installGracefulShutdown(server, options = {}) {
|
|
523
575
|
const timeoutMs = options.timeoutMs ?? 1e4;
|
|
@@ -594,19 +646,49 @@ function startNodeServer(handler, options = {}) {
|
|
|
594
646
|
try {
|
|
595
647
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
596
648
|
if (req.method === "GET" || req.method === "HEAD") {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
649
|
+
if (options.storage !== undefined) {
|
|
650
|
+
const entry = await options.storage.read(url.pathname);
|
|
651
|
+
if (entry !== null) {
|
|
652
|
+
scheduleRevalidation({
|
|
653
|
+
pathname: url.pathname,
|
|
654
|
+
mtimeMs: entry.mtimeMs,
|
|
655
|
+
storage: options.storage,
|
|
656
|
+
handler,
|
|
657
|
+
options,
|
|
658
|
+
clientDir
|
|
659
|
+
});
|
|
660
|
+
res.statusCode = 200;
|
|
661
|
+
res.setHeader("content-type", contentTypeForPathname(url.pathname));
|
|
662
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
663
|
+
if (!res.hasHeader(name)) {
|
|
664
|
+
res.setHeader(name, value);
|
|
665
|
+
}
|
|
606
666
|
}
|
|
667
|
+
res.end(req.method === "HEAD" ? undefined : Buffer.from(entry.body));
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
const staticFile = resolveStaticFile(clientDir, url.pathname);
|
|
672
|
+
if (staticFile !== null) {
|
|
673
|
+
scheduleRevalidation({
|
|
674
|
+
pathname: url.pathname,
|
|
675
|
+
mtimeMs: statSync2(staticFile).mtimeMs,
|
|
676
|
+
file: staticFile,
|
|
677
|
+
handler,
|
|
678
|
+
options,
|
|
679
|
+
clientDir
|
|
680
|
+
});
|
|
681
|
+
const body = readFileSync2(staticFile);
|
|
682
|
+
res.statusCode = 200;
|
|
683
|
+
res.setHeader("content-type", MIME_TYPES[extname2(staticFile).toLowerCase()] ?? "application/octet-stream");
|
|
684
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
685
|
+
if (!res.hasHeader(name)) {
|
|
686
|
+
res.setHeader(name, value);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
res.end(req.method === "HEAD" ? undefined : body);
|
|
690
|
+
return;
|
|
607
691
|
}
|
|
608
|
-
res.end(req.method === "HEAD" ? undefined : body);
|
|
609
|
-
return;
|
|
610
692
|
}
|
|
611
693
|
}
|
|
612
694
|
const response = await handler(await toWebRequest2(req));
|
|
@@ -643,6 +725,10 @@ function startNodeServer(handler, options = {}) {
|
|
|
643
725
|
return server;
|
|
644
726
|
}
|
|
645
727
|
function resolveStaticFile(clientDir, pathname) {
|
|
728
|
+
const target = staticFileTarget(clientDir, pathname);
|
|
729
|
+
return target !== null && isFile(target) ? target : null;
|
|
730
|
+
}
|
|
731
|
+
function staticFileTarget(clientDir, pathname) {
|
|
646
732
|
let decoded;
|
|
647
733
|
try {
|
|
648
734
|
decoded = decodeURIComponent(pathname);
|
|
@@ -657,10 +743,7 @@ function resolveStaticFile(clientDir, pathname) {
|
|
|
657
743
|
const manifest = readPrerenderManifest(clientDir);
|
|
658
744
|
if (manifest.paths.has(normalized)) {
|
|
659
745
|
const target = normalized === "/" ? "index.html" : `${normalized.slice(1)}/index.html`;
|
|
660
|
-
|
|
661
|
-
if (candidate !== null && isFile(candidate)) {
|
|
662
|
-
return candidate;
|
|
663
|
-
}
|
|
746
|
+
return safeWithin(clientDir, `./${target}`);
|
|
664
747
|
}
|
|
665
748
|
return null;
|
|
666
749
|
}
|
|
@@ -672,18 +755,18 @@ function safeWithin(clientDir, relative) {
|
|
|
672
755
|
return candidate;
|
|
673
756
|
}
|
|
674
757
|
function isFile(path) {
|
|
675
|
-
return existsSync(path) &&
|
|
758
|
+
return existsSync(path) && statSync2(path).isFile();
|
|
676
759
|
}
|
|
677
760
|
var prerenderManifestCache = null;
|
|
678
761
|
function readPrerenderManifest(clientDir) {
|
|
679
762
|
const file = join(clientDir, "_moons_prerender.json");
|
|
680
763
|
const empty = { paths: new Set, revalidate: new Map };
|
|
681
764
|
try {
|
|
682
|
-
const mtimeMs =
|
|
765
|
+
const mtimeMs = statSync2(file).mtimeMs;
|
|
683
766
|
if (prerenderManifestCache !== null && prerenderManifestCache.file === file && prerenderManifestCache.mtimeMs === mtimeMs) {
|
|
684
767
|
return prerenderManifestCache.info;
|
|
685
768
|
}
|
|
686
|
-
const json = JSON.parse(
|
|
769
|
+
const json = JSON.parse(readFileSync2(file, "utf8"));
|
|
687
770
|
const paths = new Set;
|
|
688
771
|
const revalidate = new Map;
|
|
689
772
|
if (Array.isArray(json.paths)) {
|
|
@@ -713,26 +796,22 @@ function readPrerenderManifest(clientDir) {
|
|
|
713
796
|
return empty;
|
|
714
797
|
}
|
|
715
798
|
}
|
|
716
|
-
function scheduleRevalidation(
|
|
717
|
-
const normalized = pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname;
|
|
718
|
-
const seconds = readPrerenderManifest(clientDir).revalidate.get(normalized);
|
|
799
|
+
function scheduleRevalidation(input) {
|
|
800
|
+
const normalized = input.pathname.length > 1 ? input.pathname.replace(/\/+$/, "") : input.pathname;
|
|
801
|
+
const seconds = readPrerenderManifest(input.clientDir).revalidate.get(normalized);
|
|
719
802
|
if (seconds === undefined || seconds < 0) {
|
|
720
803
|
return;
|
|
721
804
|
}
|
|
722
|
-
|
|
723
|
-
try {
|
|
724
|
-
mtimeMs = statSync(staticFile).mtimeMs;
|
|
725
|
-
} catch {
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
if (!shouldRevalidate({ mtimeMs, revalidateSeconds: seconds })) {
|
|
805
|
+
if (!shouldRevalidate({ mtimeMs: input.mtimeMs, revalidateSeconds: seconds })) {
|
|
729
806
|
return;
|
|
730
807
|
}
|
|
731
808
|
revalidatePrerendered({
|
|
732
809
|
pathname: normalized,
|
|
733
|
-
file:
|
|
734
|
-
|
|
735
|
-
|
|
810
|
+
...input.file === undefined ? {} : { file: input.file },
|
|
811
|
+
...input.storage === undefined ? {} : { storage: input.storage },
|
|
812
|
+
handler: input.handler,
|
|
813
|
+
...input.options.canary === undefined ? {} : { canary: input.options.canary },
|
|
814
|
+
env: process.env
|
|
736
815
|
});
|
|
737
816
|
}
|
|
738
817
|
// src/server/test-server.ts
|
|
@@ -808,8 +887,8 @@ function createPluginRuntime(options) {
|
|
|
808
887
|
}
|
|
809
888
|
// src/server/prerender.ts
|
|
810
889
|
import { MoonsError as MoonsError2 } from "@moonsjs/core";
|
|
811
|
-
import { mkdirSync, writeFileSync as
|
|
812
|
-
import { dirname, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
|
|
890
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
891
|
+
import { dirname as dirname2, join as join2, resolve as resolve2, sep as sep2 } from "node:path";
|
|
813
892
|
var PRERENDER_MANIFEST_FILE = "_moons_prerender.json";
|
|
814
893
|
var NOT_FOUND_SENTINEL = "/_moons/404";
|
|
815
894
|
var NOT_FOUND_FILE = "404.html";
|
|
@@ -869,8 +948,8 @@ async function runPrerender(options) {
|
|
|
869
948
|
const html = await response.text();
|
|
870
949
|
assertNoLeak(html, pathname, route.file, options, env);
|
|
871
950
|
const file = outputFile(options.clientDir, pathname);
|
|
872
|
-
|
|
873
|
-
|
|
951
|
+
mkdirSync2(dirname2(file), { recursive: true });
|
|
952
|
+
writeFileSync3(file, html);
|
|
874
953
|
entries.push(typeof revalidate === "number" && revalidate >= 0 ? { path: pathname, revalidate } : { path: pathname });
|
|
875
954
|
written += 1;
|
|
876
955
|
}
|
|
@@ -878,10 +957,10 @@ async function runPrerender(options) {
|
|
|
878
957
|
const notFound = await renderStaticNotFound(options, env, log);
|
|
879
958
|
let wrote404 = false;
|
|
880
959
|
if (notFound !== null) {
|
|
881
|
-
|
|
960
|
+
writeFileSync3(join2(options.clientDir, NOT_FOUND_FILE), notFound);
|
|
882
961
|
wrote404 = true;
|
|
883
962
|
}
|
|
884
|
-
|
|
963
|
+
writeFileSync3(join2(options.clientDir, PRERENDER_MANIFEST_FILE), `${JSON.stringify({ version: 2, entries }, null, 2)}
|
|
885
964
|
`);
|
|
886
965
|
const emitted = emitStaticFiles(options.clientDir, options.staticConfig, entries);
|
|
887
966
|
const extras = [...wrote404 ? [NOT_FOUND_FILE] : [], ...emitted];
|
|
@@ -896,7 +975,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
|
|
|
896
975
|
const headers = Object.entries(staticConfig.headers ?? {});
|
|
897
976
|
if (headers.length > 0) {
|
|
898
977
|
const lines = ["/*", ...headers.map(([name, value]) => ` ${name}: ${value}`)];
|
|
899
|
-
|
|
978
|
+
writeFileSync3(join2(clientDir, "_headers"), `${lines.join(`
|
|
900
979
|
`)}
|
|
901
980
|
`);
|
|
902
981
|
emitted.push("_headers");
|
|
@@ -904,7 +983,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
|
|
|
904
983
|
const redirects = staticConfig.redirects ?? [];
|
|
905
984
|
if (redirects.length > 0) {
|
|
906
985
|
const lines = redirects.map((entry) => `${entry.from} ${entry.to} ${entry.status ?? 301}`);
|
|
907
|
-
|
|
986
|
+
writeFileSync3(join2(clientDir, "_redirects"), `${lines.join(`
|
|
908
987
|
`)}
|
|
909
988
|
`);
|
|
910
989
|
emitted.push("_redirects");
|
|
@@ -922,7 +1001,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
|
|
|
922
1001
|
""
|
|
923
1002
|
].join(`
|
|
924
1003
|
`);
|
|
925
|
-
|
|
1004
|
+
writeFileSync3(join2(clientDir, "sitemap.xml"), xml);
|
|
926
1005
|
emitted.push("sitemap.xml");
|
|
927
1006
|
}
|
|
928
1007
|
const robots = staticConfig.robots;
|
|
@@ -934,7 +1013,7 @@ function emitStaticFiles(clientDir, staticConfig, entries) {
|
|
|
934
1013
|
if ((robots.sitemap ?? true) && sitemap !== undefined) {
|
|
935
1014
|
lines.push("", `Sitemap: ${sitemap.site.replace(/\/$/, "")}/sitemap.xml`);
|
|
936
1015
|
}
|
|
937
|
-
|
|
1016
|
+
writeFileSync3(join2(clientDir, "robots.txt"), `${lines.join(`
|
|
938
1017
|
`)}
|
|
939
1018
|
`);
|
|
940
1019
|
emitted.push("robots.txt");
|
|
@@ -1085,8 +1164,10 @@ function prerenderError(route, message) {
|
|
|
1085
1164
|
export {
|
|
1086
1165
|
DEFAULT_TEMPLATE2 as DEFAULT_TEMPLATE,
|
|
1087
1166
|
ROOT_PLACEHOLDER2 as ROOT_PLACEHOLDER,
|
|
1167
|
+
contentTypeForPathname,
|
|
1088
1168
|
createDevShell2 as createDevShell,
|
|
1089
1169
|
createFileShell2 as createFileShell,
|
|
1170
|
+
createFileStorage,
|
|
1090
1171
|
createPluginRuntime,
|
|
1091
1172
|
createRequestHandler,
|
|
1092
1173
|
createTestServer,
|
|
@@ -1100,4 +1181,4 @@ export {
|
|
|
1100
1181
|
toWebRequest2 as toWebRequest
|
|
1101
1182
|
};
|
|
1102
1183
|
|
|
1103
|
-
//# debugId=
|
|
1184
|
+
//# debugId=9A8636F992D1AC9F64756E2164756E21
|