@moonsjs/vite 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +9 -2
- package/dist/index-8xq8fcgq.js +222 -0
- package/dist/index-8xq8fcgq.js.map +14 -0
- package/dist/index-fg6nqart.js +776 -0
- package/dist/index-fg6nqart.js.map +10 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +423 -0
- package/dist/index.js.map +11 -0
- package/dist/leak-check.d.ts +14 -0
- package/dist/leak-check.d.ts.map +1 -0
- package/dist/manifest.d.ts +21 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/plugin.d.ts +13 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/server/dev.d.ts +9 -0
- package/dist/server/dev.d.ts.map +1 -0
- package/dist/server/handler.d.ts +18 -0
- package/dist/server/handler.d.ts.map +1 -0
- package/dist/server/index.d.ts +13 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +311 -0
- package/dist/server/index.js.map +13 -0
- package/dist/server/node-server.d.ts +17 -0
- package/dist/server/node-server.d.ts.map +1 -0
- package/dist/server/node.d.ts +6 -0
- package/dist/server/node.d.ts.map +1 -0
- package/dist/server/shell.d.ts +18 -0
- package/dist/server/shell.d.ts.map +1 -0
- package/dist/server/shutdown.d.ts +17 -0
- package/dist/server/shutdown.d.ts.map +1 -0
- package/dist/server/test-server.d.ts +21 -0
- package/dist/server/test-server.d.ts.map +1 -0
- package/dist/transform.d.ts +101 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/transform.js +34 -0
- package/dist/transform.js.map +9 -0
- package/dist/virtual-modules.d.ts +12 -0
- package/dist/virtual-modules.d.ts.map +1 -0
- package/package.json +51 -4
- package/src/ctx-fallback.d.ts +9 -0
- package/src/index.ts +2 -0
- package/src/leak-check.ts +36 -0
- package/src/manifest.ts +79 -0
- package/src/plugin.ts +471 -0
- package/src/server/dev.ts +54 -0
- package/src/server/handler.ts +249 -0
- package/src/server/index.ts +12 -0
- package/src/server/node-server.ts +115 -0
- package/src/server/node.ts +61 -0
- package/src/server/shell.ts +77 -0
- package/src/server/shutdown.ts +64 -0
- package/src/server/test-server.ts +44 -0
- package/src/transform.ts +1073 -0
- package/src/virtual-modules.ts +23 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { MoonsError } from "@moonsjs/core";
|
|
2
|
+
/**
|
|
3
|
+
* Spec §12: analisis `.server.ts` + stub client + injeksi meta server +
|
|
4
|
+
* penolakan import (E_SERVER_IMPORT_IN_CLIENT / E_FORBIDDEN_SERVER_IMPORT).
|
|
5
|
+
*/
|
|
6
|
+
export interface ServerFnInfo {
|
|
7
|
+
name: string;
|
|
8
|
+
hash: string;
|
|
9
|
+
line: number;
|
|
10
|
+
input: {
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
};
|
|
14
|
+
output: {
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
};
|
|
18
|
+
objectStart: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ServerFileAnalysis {
|
|
21
|
+
/** Absolute path. */
|
|
22
|
+
file: string;
|
|
23
|
+
serverFns: ServerFnInfo[];
|
|
24
|
+
/** Semua nama export top-level (langsung). */
|
|
25
|
+
exportNames: string[];
|
|
26
|
+
/** Pernyataan `export { X as Y } from "./z.server"` (untuk resolusi re-export). */
|
|
27
|
+
reExports: Array<{
|
|
28
|
+
source: string;
|
|
29
|
+
names: Array<{
|
|
30
|
+
local: string;
|
|
31
|
+
exported: string;
|
|
32
|
+
}>;
|
|
33
|
+
}>;
|
|
34
|
+
/** `export * from "./z.server"`. */
|
|
35
|
+
exportAllFrom: string[];
|
|
36
|
+
}
|
|
37
|
+
export declare function isServerFilePath(path: string): boolean;
|
|
38
|
+
/** File server dengan ekstensi di luar kontrak §12 (tidak bisa di-stub). */
|
|
39
|
+
export declare function isNonContractServerFile(path: string): boolean;
|
|
40
|
+
export declare function isServerSpecifier(specifier: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Resolusi sinkron untuk specifier `*.server` (relatif/absolut).
|
|
43
|
+
* Import alias/virtual untuk file server tidak didukung — tidak dibutuhkan app.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveServerSpecifierSync(importerFile: string, specifier: string): string | null;
|
|
46
|
+
export declare function stripQuery(id: string): string;
|
|
47
|
+
export declare function analyzeServerFile(source: string, filename: string, projectRoot: string): ServerFileAnalysis;
|
|
48
|
+
/** Nama-nama yang diekspor sebagai serverFn stub dari file (langsung atau via re-export). */
|
|
49
|
+
export declare function serverFnExportNames(analysis: ServerFileAnalysis, analyzeTarget: (specifier: string) => ServerFileAnalysis | null, seen?: Set<string>): Set<string>;
|
|
50
|
+
export interface StubDependencies {
|
|
51
|
+
/** Resolve specifier relatif file sumber → analysis (null bila tidak bisa). */
|
|
52
|
+
analyzeSpecifier: (sourceFile: string, specifier: string) => ServerFileAnalysis | null;
|
|
53
|
+
}
|
|
54
|
+
export interface RenderStubResult {
|
|
55
|
+
code: string;
|
|
56
|
+
/** Specifier server file yang di-referensikan (untuk keperluan cache/diagnostik). */
|
|
57
|
+
referenced: string[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Bangun stub client §12.2/§12.3 dari sumber `.server.ts`:
|
|
61
|
+
* hanya import yang dipakai schema + `__moons_createStub` per serverFn.
|
|
62
|
+
*/
|
|
63
|
+
export declare function renderServerFnStub(source: string, filename: string, analysis: ServerFileAnalysis, dependencies: StubDependencies): RenderStubResult;
|
|
64
|
+
/** Inject meta §7.2 ke deklarasi serverFn (env ssr; handler tetap utuh). */
|
|
65
|
+
export declare function injectServerFnMeta(source: string, analysis: ServerFileAnalysis, projectRoot: string): string;
|
|
66
|
+
export interface ClientImportCheckContext {
|
|
67
|
+
/** Absolute path file yang sedang diperiksa. */
|
|
68
|
+
file: string;
|
|
69
|
+
code: string;
|
|
70
|
+
projectRoot: string;
|
|
71
|
+
/**
|
|
72
|
+
* Resolve specifier dengan importer tertentu → absolute path (null bila tidak
|
|
73
|
+
* ada). Boleh sinkron maupun async (plugin memakai `this.resolve`, sehingga
|
|
74
|
+
* alias Vite & `tsconfig paths` ikut terperiksa — audit ronde 2).
|
|
75
|
+
*/
|
|
76
|
+
resolve: (specifier: string, importer: string) => string | null | Promise<string | null>;
|
|
77
|
+
/** Analysis untuk file server (hasil cache plugin). */
|
|
78
|
+
analyze: (absoluteFile: string) => ServerFileAnalysis | null;
|
|
79
|
+
}
|
|
80
|
+
export declare function nonContractServerFileError(file: string, projectRoot: string): MoonsError;
|
|
81
|
+
/** Periksa import modul client terhadap §12.4/§12.7/§12.8 — berbasis hasil resolve. */
|
|
82
|
+
export declare function checkClientModuleImports(context: ClientImportCheckContext): Promise<void>;
|
|
83
|
+
export interface RouteExportCheckContext {
|
|
84
|
+
file: string;
|
|
85
|
+
code: string;
|
|
86
|
+
routesDir: string;
|
|
87
|
+
projectRoot: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* §11.2 + §12.4: export legal per jenis modul route.
|
|
91
|
+
* page: `default|loader|meta`; layout: `default|loader`; `_error`/`_404`: `default`.
|
|
92
|
+
*/
|
|
93
|
+
export declare function checkRouteModuleExports(context: RouteExportCheckContext): void;
|
|
94
|
+
/** Scan semua `*.server.{ts,tsx}` di bawah root (exclude direktori build/dependency). */
|
|
95
|
+
export declare function scanServerFiles(projectRoot: string): string[];
|
|
96
|
+
export interface FnRegistryJson {
|
|
97
|
+
[key: string]: string;
|
|
98
|
+
}
|
|
99
|
+
/** Bangun isi `fn-registry.json` (bentuk yang dibaca §21.3). */
|
|
100
|
+
export declare function buildFnRegistry(projectRoot: string, files: string[]): FnRegistryJson;
|
|
101
|
+
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isServerFilePath2,
|
|
3
|
+
isNonContractServerFile2,
|
|
4
|
+
isServerSpecifier2,
|
|
5
|
+
resolveServerSpecifierSync2,
|
|
6
|
+
stripQuery2,
|
|
7
|
+
analyzeServerFile2,
|
|
8
|
+
serverFnExportNames2,
|
|
9
|
+
renderServerFnStub2,
|
|
10
|
+
injectServerFnMeta2,
|
|
11
|
+
nonContractServerFileError2,
|
|
12
|
+
checkClientModuleImports2,
|
|
13
|
+
checkRouteModuleExports2,
|
|
14
|
+
scanServerFiles2,
|
|
15
|
+
buildFnRegistry2
|
|
16
|
+
} from "./index-fg6nqart.js";
|
|
17
|
+
export {
|
|
18
|
+
analyzeServerFile2 as analyzeServerFile,
|
|
19
|
+
buildFnRegistry2 as buildFnRegistry,
|
|
20
|
+
checkClientModuleImports2 as checkClientModuleImports,
|
|
21
|
+
checkRouteModuleExports2 as checkRouteModuleExports,
|
|
22
|
+
injectServerFnMeta2 as injectServerFnMeta,
|
|
23
|
+
isNonContractServerFile2 as isNonContractServerFile,
|
|
24
|
+
isServerFilePath2 as isServerFilePath,
|
|
25
|
+
isServerSpecifier2 as isServerSpecifier,
|
|
26
|
+
nonContractServerFileError2 as nonContractServerFileError,
|
|
27
|
+
renderServerFnStub2 as renderServerFnStub,
|
|
28
|
+
resolveServerSpecifierSync2 as resolveServerSpecifierSync,
|
|
29
|
+
scanServerFiles2 as scanServerFiles,
|
|
30
|
+
serverFnExportNames2 as serverFnExportNames,
|
|
31
|
+
stripQuery2 as stripQuery
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//# debugId=B5ECBEB295B684F664756E2164756E21
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Nama virtual module PRD §9.4. Semua di-resolve ke id `\0`-prefix. */
|
|
2
|
+
export declare const VIRTUAL_MODULES: {
|
|
3
|
+
readonly routes: "virtual:moons/routes";
|
|
4
|
+
readonly config: "virtual:moons/config";
|
|
5
|
+
readonly clientEntry: "virtual:moons/client-entry";
|
|
6
|
+
readonly serverEntry: "virtual:moons/server-entry";
|
|
7
|
+
};
|
|
8
|
+
export type VirtualModuleName = (typeof VIRTUAL_MODULES)[keyof typeof VIRTUAL_MODULES];
|
|
9
|
+
export declare function isVirtualModuleId(id: string): id is VirtualModuleName;
|
|
10
|
+
export declare function toNullPrefixed(id: VirtualModuleName): `\0${string}`;
|
|
11
|
+
export declare function fromNullPrefixed(id: string): VirtualModuleName | null;
|
|
12
|
+
//# sourceMappingURL=virtual-modules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-modules.d.ts","sourceRoot":"","sources":["../src/virtual-modules.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,eAAe;aAC1B,MAAM,EAAE,sBAAsB;aAC9B,MAAM,EAAE,sBAAsB;aAC9B,WAAW,EAAE,4BAA4B;aACzC,WAAW,EAAE,4BAA4B;CACjC,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEvF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,iBAAiB,CAGrE;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,KAAK,MAAM,EAAE,CAEnE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAGrE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moonsjs/vite",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/RamonymousDev/Moons.git",
|
|
10
|
+
"directory": "packages/vite"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/RamonymousDev/Moons#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/RamonymousDev/Moons/issues"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./src/index.ts",
|
|
23
|
+
"bun": "./src/index.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./server": {
|
|
27
|
+
"types": "./src/server/index.ts",
|
|
28
|
+
"bun": "./src/server/index.ts",
|
|
29
|
+
"default": "./dist/server/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./transform": {
|
|
32
|
+
"types": "./src/transform.ts",
|
|
33
|
+
"bun": "./src/transform.ts",
|
|
34
|
+
"default": "./dist/transform.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"prepack": "bun run build",
|
|
39
|
+
"build": "rm -rf dist && tsc -p tsconfig.json --emitDeclarationOnly && bun build src/index.ts src/server/index.ts src/transform.ts --outdir dist --target node --format esm --splitting --sourcemap=external --external @moonsjs/core --external '@moonsjs/core/*' --external @moonsjs/react --external '@moonsjs/react/*' --external @moonsjs/server --external '@moonsjs/server/*' --external @babel/parser --external vite"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@babel/parser": "^8.0.7",
|
|
43
|
+
"@moonsjs/core": "^0.1.0",
|
|
44
|
+
"@moonsjs/react": "^0.1.0",
|
|
45
|
+
"@moonsjs/server": "^0.1.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"vite": "^8.3.4"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"vite": "^8.3.4"
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface BundleOutputLike {
|
|
2
|
+
type: string;
|
|
3
|
+
fileName?: string;
|
|
4
|
+
code?: string;
|
|
5
|
+
source?: string | Uint8Array;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* §9.1 (`leakTest.canary`) / §10.4: cari canary pada output bundle client.
|
|
10
|
+
* Dipakai `generateBundle` plugin — build gagal bila canary ditemukan.
|
|
11
|
+
*/
|
|
12
|
+
export function findLeak(
|
|
13
|
+
outputs: Iterable<BundleOutputLike>,
|
|
14
|
+
canary: string,
|
|
15
|
+
decode: (source: Uint8Array) => string = defaultDecode,
|
|
16
|
+
): { fileName: string } | null {
|
|
17
|
+
for (const output of outputs) {
|
|
18
|
+
const fileName = output.fileName ?? "(unknown)";
|
|
19
|
+
let text = "";
|
|
20
|
+
if (typeof output.code === "string") {
|
|
21
|
+
text = output.code;
|
|
22
|
+
} else if (typeof output.source === "string") {
|
|
23
|
+
text = output.source;
|
|
24
|
+
} else if (output.source instanceof Uint8Array) {
|
|
25
|
+
text = decode(output.source);
|
|
26
|
+
}
|
|
27
|
+
if (text.includes(canary)) {
|
|
28
|
+
return { fileName };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function defaultDecode(bytes: Uint8Array): string {
|
|
35
|
+
return new TextDecoder().decode(bytes);
|
|
36
|
+
}
|
package/src/manifest.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { findLayouts, routeKeyFromFile, type RouteDefinition } from "@moonsjs/core";
|
|
2
|
+
import { relative, sep } from "node:path";
|
|
3
|
+
|
|
4
|
+
export interface ClientManifestEntry {
|
|
5
|
+
page: string;
|
|
6
|
+
layouts: string[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Key manifest untuk halaman kustom `_404` dan `_error` (§11.2). */
|
|
10
|
+
export const NOT_FOUND_ROUTE_KEY = "__moons/404";
|
|
11
|
+
export const ERROR_ROUTE_KEY = "__moons/error";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Manifest route untuk client (PRD §8.2): key = key route file
|
|
15
|
+
* (routeKeyFromFile), nilai = page + layout chain dari root ke leaf.
|
|
16
|
+
*/
|
|
17
|
+
export function buildClientManifest(
|
|
18
|
+
routes: RouteDefinition[],
|
|
19
|
+
routesDir: string,
|
|
20
|
+
): Record<string, ClientManifestEntry> {
|
|
21
|
+
const manifest: Record<string, ClientManifestEntry> = {};
|
|
22
|
+
for (const route of routes) {
|
|
23
|
+
if (route.kind !== "page") {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const key = routeKeyFromFile(routesDir, route.file);
|
|
27
|
+
manifest[key] = {
|
|
28
|
+
page: key,
|
|
29
|
+
layouts: findLayouts(route, routes).map((layout) => routeKeyFromFile(routesDir, layout.file)),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const notFound = routes.find((route) => route.kind === "404");
|
|
34
|
+
if (notFound !== undefined) {
|
|
35
|
+
manifest[NOT_FOUND_ROUTE_KEY] = { page: routeKeyFromFile(routesDir, notFound.file), layouts: [] };
|
|
36
|
+
}
|
|
37
|
+
const errorRoute = routes.find((route) => route.kind === "error");
|
|
38
|
+
if (errorRoute !== undefined) {
|
|
39
|
+
manifest[ERROR_ROUTE_KEY] = { page: routeKeyFromFile(routesDir, errorRoute.file), layouts: [] };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return manifest;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Isi `virtual:moons/routes`: daftar RouteDefinition, manifest client, dan
|
|
47
|
+
* peta import() dinamis per file route (specifier root-relative).
|
|
48
|
+
*/
|
|
49
|
+
export function renderRoutesModule(
|
|
50
|
+
routes: RouteDefinition[],
|
|
51
|
+
routesDir: string,
|
|
52
|
+
projectRoot: string,
|
|
53
|
+
): string {
|
|
54
|
+
const manifest = buildClientManifest(routes, routesDir);
|
|
55
|
+
|
|
56
|
+
const loadEntries = routes.map((route) => {
|
|
57
|
+
const key = routeKeyFromFile(routesDir, route.file);
|
|
58
|
+
return ` ${JSON.stringify(key)}: () => import(${JSON.stringify(rootSpecifier(projectRoot, route.file))}),`;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return [
|
|
62
|
+
"// Generated by @moons. Jangan diubah manual.",
|
|
63
|
+
`export const routes = ${JSON.stringify(routes, null, 2)};`,
|
|
64
|
+
"",
|
|
65
|
+
`export const clientManifest = ${JSON.stringify(manifest, null, 2)};`,
|
|
66
|
+
"",
|
|
67
|
+
"export const loadRoute = {",
|
|
68
|
+
...loadEntries,
|
|
69
|
+
"};",
|
|
70
|
+
"",
|
|
71
|
+
].join("\n");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Path file absolut project → specifier root-relative yang bisa di-resolve Vite. */
|
|
75
|
+
export function rootSpecifier(projectRoot: string, file: string): string {
|
|
76
|
+
let rel = relative(projectRoot, file);
|
|
77
|
+
rel = sep === "/" ? rel : rel.split(sep).join("/");
|
|
78
|
+
return rel.startsWith("/") ? rel : `/${rel}`;
|
|
79
|
+
}
|