@jxsuite/compiler 0.28.2 → 0.28.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/cli.js +159 -150
- package/dist/compiler.js +100 -95
- package/package.json +5 -5
- package/src/cli.ts +6 -6
- package/src/compile-cli.ts +6 -4
- package/src/compiler.ts +34 -23
- package/src/shared.ts +402 -231
- package/src/site/content-loader.ts +54 -29
- package/src/site/context-injection.ts +13 -9
- package/src/site/format-host.ts +26 -15
- package/src/site/head-merger.ts +37 -18
- package/src/site/image-cache.ts +13 -12
- package/src/site/image-optimizer.ts +30 -20
- package/src/site/image-transform.ts +136 -78
- package/src/site/layout-resolver.ts +33 -18
- package/src/site/pages-discovery.ts +61 -39
- package/src/site/prototype-resolver.ts +45 -21
- package/src/site/site-build.ts +212 -136
- package/src/site/site-loader.ts +70 -43
- package/src/targets/compile-class.ts +70 -51
- package/src/targets/compile-client.ts +271 -227
- package/src/targets/compile-element.ts +230 -146
- package/src/targets/compile-server.ts +9 -5
- package/src/targets/compile-static.ts +27 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/compiler",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.4",
|
|
4
4
|
"description": "Jx static HTML compiler, island detector, and site builder",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@apidevtools/json-schema-ref-parser": "^15.3.5",
|
|
45
|
-
"@jxsuite/parser": "^0.28.
|
|
46
|
-
"@jxsuite/runtime": "^0.28.
|
|
47
|
-
"@jxsuite/schema": "^0.28.
|
|
48
|
-
"sharp": "^0.
|
|
45
|
+
"@jxsuite/parser": "^0.28.4",
|
|
46
|
+
"@jxsuite/runtime": "^0.28.4",
|
|
47
|
+
"@jxsuite/schema": "^0.28.4",
|
|
48
|
+
"sharp": "^0.35.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@happy-dom/global-registrator": "^20.10.2",
|
package/src/cli.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { resolve } from "node:path";
|
|
11
11
|
|
|
12
12
|
const args = process.argv.slice(2);
|
|
13
|
-
const command = args
|
|
13
|
+
const [command] = args;
|
|
14
14
|
|
|
15
15
|
if (!command || command === "--help" || command === "-h") {
|
|
16
16
|
console.log(`Usage: jx <command> [options]
|
|
@@ -27,9 +27,9 @@ Options:
|
|
|
27
27
|
if (command === "build") {
|
|
28
28
|
const rest = args.slice(1);
|
|
29
29
|
const flags = new Set(rest.filter((a) => a.startsWith("--")));
|
|
30
|
-
const positional = rest.
|
|
30
|
+
const positional = rest.find((a) => !a.startsWith("--"));
|
|
31
31
|
|
|
32
|
-
const projectRoot = resolve(positional
|
|
32
|
+
const projectRoot = resolve(positional ?? ".");
|
|
33
33
|
const verbose = flags.has("--verbose");
|
|
34
34
|
const clean = !flags.has("--no-clean");
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ if (command === "build") {
|
|
|
37
37
|
|
|
38
38
|
try {
|
|
39
39
|
const { buildSite } = await import("./site/site-build.ts");
|
|
40
|
-
const result = await buildSite(projectRoot, {
|
|
40
|
+
const result = await buildSite(projectRoot, { clean, verbose });
|
|
41
41
|
|
|
42
42
|
if (result.errors.length > 0) {
|
|
43
43
|
console.error(`\nBuild completed with ${result.errors.length} error(s):`);
|
|
@@ -48,8 +48,8 @@ if (command === "build") {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
console.log(`\nDone: ${result.routes} routes → ${result.files} files`);
|
|
51
|
-
} catch (
|
|
52
|
-
const err =
|
|
51
|
+
} catch (error) {
|
|
52
|
+
const err = error as Error;
|
|
53
53
|
console.error(`Build failed: ${err.message}`);
|
|
54
54
|
process.exit(1);
|
|
55
55
|
}
|
package/src/compile-cli.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { runCli } from "./compiler.ts";
|
|
3
3
|
|
|
4
|
-
const [
|
|
4
|
+
const [src, out] = process.argv.slice(2);
|
|
5
5
|
if (src) {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
try {
|
|
7
|
+
await runCli(src, out);
|
|
8
|
+
} catch (error) {
|
|
9
|
+
console.error(error);
|
|
8
10
|
process.exit(1);
|
|
9
|
-
}
|
|
11
|
+
}
|
|
10
12
|
}
|
package/src/compiler.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Jx-compiler.js — Compiler orchestrator
|
|
3
3
|
* @version 3.0.0
|
|
4
4
|
* @license MIT
|
|
5
5
|
*
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
|
|
16
16
|
import { readFileSync } from "node:fs";
|
|
17
17
|
import {
|
|
18
|
-
|
|
18
|
+
DEFAULT_LIT_HTML_SRC,
|
|
19
|
+
DEFAULT_REACTIVITY_SRC,
|
|
19
20
|
compileStyles,
|
|
20
21
|
escapeHtml,
|
|
22
|
+
isDynamic,
|
|
21
23
|
tagNameToClassName,
|
|
22
|
-
DEFAULT_REACTIVITY_SRC,
|
|
23
|
-
DEFAULT_LIT_HTML_SRC,
|
|
24
24
|
} from "./shared.ts";
|
|
25
25
|
import { compileServer, compileSiteServer } from "./targets/compile-server.ts";
|
|
26
26
|
|
|
@@ -31,7 +31,10 @@ import {
|
|
|
31
31
|
} from "./targets/compile-element.ts";
|
|
32
32
|
import { compileStaticPage } from "./targets/compile-static.ts";
|
|
33
33
|
import { compileClient } from "./targets/compile-client.ts";
|
|
34
|
-
import
|
|
34
|
+
import { isClassDef } from "@jxsuite/schema/guards";
|
|
35
|
+
import { parseJxDocument } from "@jxsuite/schema/parse";
|
|
36
|
+
import type { JxDocument, JxStyle } from "@jxsuite/schema/types";
|
|
37
|
+
import type { FormatRegistry } from "@jxsuite/schema/format-registry";
|
|
35
38
|
|
|
36
39
|
// Re-exports for consumers
|
|
37
40
|
export {
|
|
@@ -45,77 +48,85 @@ export {
|
|
|
45
48
|
|
|
46
49
|
// ─── Entry ────────────────────────────────────────────────────────────────────
|
|
47
50
|
|
|
51
|
+
export interface CompileOptions {
|
|
52
|
+
title?: string;
|
|
53
|
+
reactivitySrc?: string;
|
|
54
|
+
litHtmlSrc?: string;
|
|
55
|
+
projectStyle?: JxStyle | null;
|
|
56
|
+
formats?: FormatRegistry;
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
}
|
|
59
|
+
|
|
48
60
|
/**
|
|
49
61
|
* Compile a Jx document to HTML (+ optional JS module files).
|
|
50
62
|
*
|
|
51
63
|
* Routing: 1. Not dynamic → static HTML/CSS, zero JS 2. tagName contains hyphen → custom element
|
|
52
64
|
* (lit-html) 3. Otherwise → pre-rendered HTML with reactive bindings
|
|
53
65
|
*
|
|
54
|
-
* @param {string |
|
|
55
|
-
* @param {
|
|
66
|
+
* @param {string | JxDocument} sourcePath - Path to .json file, URL, or raw document object
|
|
67
|
+
* @param {CompileOptions} [opts]
|
|
56
68
|
* @returns {Promise<{
|
|
57
69
|
* html: string;
|
|
58
70
|
* files: { path: string; content: string; tagName?: string }[];
|
|
59
71
|
* }>}
|
|
60
72
|
*/
|
|
61
|
-
export async function compile(sourcePath: string |
|
|
73
|
+
export async function compile(sourcePath: string | JxDocument, opts: CompileOptions = {}) {
|
|
62
74
|
const {
|
|
63
75
|
title = "Jx App",
|
|
64
76
|
reactivitySrc = DEFAULT_REACTIVITY_SRC,
|
|
65
77
|
litHtmlSrc = DEFAULT_LIT_HTML_SRC,
|
|
66
78
|
projectStyle = null,
|
|
67
|
-
} = opts
|
|
79
|
+
} = opts;
|
|
68
80
|
|
|
69
|
-
let raw;
|
|
81
|
+
let raw: JxDocument;
|
|
70
82
|
if (typeof sourcePath === "string") {
|
|
71
83
|
const source = readFileSync(sourcePath, "utf8");
|
|
72
84
|
if (sourcePath.endsWith(".json")) {
|
|
73
|
-
raw =
|
|
85
|
+
raw = parseJxDocument(source, sourcePath);
|
|
74
86
|
} else {
|
|
75
87
|
const { extname } = await import("node:path");
|
|
76
88
|
const ext = extname(sourcePath).toLowerCase();
|
|
77
|
-
const
|
|
78
|
-
.formats as import("@jxsuite/schema/format-registry").FormatRegistry;
|
|
79
|
-
const entry = registry?.byExtension?.(ext, "parse");
|
|
89
|
+
const entry = opts.formats?.byExtension?.(ext, "parse");
|
|
80
90
|
if (!entry) {
|
|
81
91
|
const { unknownFormatError } = await import("./site/format-host.ts");
|
|
82
92
|
throw unknownFormatError(sourcePath, ext);
|
|
83
93
|
}
|
|
84
|
-
|
|
94
|
+
// Format plugins contractually parse source text into a Jx document.
|
|
95
|
+
raw = (await entry.call("parse", source)) as JxDocument;
|
|
85
96
|
}
|
|
86
97
|
} else {
|
|
87
98
|
raw = sourcePath;
|
|
88
99
|
}
|
|
89
100
|
|
|
90
101
|
// Route 0: .class.json schema-defined class → JS class module
|
|
91
|
-
if (raw
|
|
102
|
+
if (isClassDef(raw)) {
|
|
92
103
|
const { compileClassJson } = await import("./targets/compile-class.js");
|
|
93
104
|
const jsContent = compileClassJson(raw, opts);
|
|
94
105
|
const outputPath =
|
|
95
106
|
typeof sourcePath === "string"
|
|
96
107
|
? sourcePath.replace(/\.class\.json$/, ".js")
|
|
97
108
|
: `${raw.title}.js`;
|
|
98
|
-
return {
|
|
109
|
+
return { files: [{ content: jsContent, path: outputPath }], html: "" };
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
// Route 1: Fully static → plain HTML/CSS
|
|
102
113
|
if (!isDynamic(raw)) {
|
|
103
114
|
return compileStaticPage(raw, {
|
|
104
|
-
title,
|
|
105
|
-
reactivitySrc,
|
|
106
115
|
litHtmlSrc,
|
|
107
116
|
projectStyle,
|
|
117
|
+
reactivitySrc,
|
|
118
|
+
title,
|
|
108
119
|
});
|
|
109
120
|
}
|
|
110
121
|
|
|
111
122
|
// Route 2: Custom element tagName (contains hyphen) → lit-html web component
|
|
112
123
|
if (raw.tagName && raw.tagName.includes("-")) {
|
|
113
|
-
const tagName = raw
|
|
124
|
+
const { tagName } = raw;
|
|
114
125
|
const className = tagNameToClassName(tagName);
|
|
115
126
|
const moduleContent = emitElementModule(raw, className, []);
|
|
116
127
|
const moduleFile = {
|
|
117
|
-
path: `${tagName}.js`,
|
|
118
128
|
content: moduleContent,
|
|
129
|
+
path: `${tagName}.js`,
|
|
119
130
|
tagName,
|
|
120
131
|
};
|
|
121
132
|
const styleBlock = compileStyles(raw, raw.$media ?? {});
|
|
@@ -142,11 +153,11 @@ export async function compile(sourcePath: string | any, opts: Record<string, unk
|
|
|
142
153
|
</body>
|
|
143
154
|
</html>`;
|
|
144
155
|
|
|
145
|
-
return {
|
|
156
|
+
return { files: [moduleFile], html };
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
// Route 3: Dynamic with standard tagName → pre-rendered HTML + reactive bindings
|
|
149
|
-
return compileClient(raw, {
|
|
160
|
+
return compileClient(raw, { litHtmlSrc, projectStyle, reactivitySrc, title });
|
|
150
161
|
}
|
|
151
162
|
|
|
152
163
|
// ─── CLI ──────────────────────────────────────────────────────────────────────
|