@jxsuite/compiler 0.28.0 → 0.28.3
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 +166 -249
- package/dist/compiler.js +100 -188
- package/package.json +5 -5
- package/src/cli.ts +6 -6
- package/src/compile-cli.ts +6 -4
- package/src/compiler.ts +35 -29
- 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 +32 -23
- package/src/site/image-transform.ts +172 -81
- 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 +232 -183
- package/src/site/site-loader.ts +71 -52
- 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 +16 -62
- package/src/targets/compile-static.ts +27 -19
- package/src/targets/compile-image-endpoint.ts +0 -138
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/compiler",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.3",
|
|
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.3",
|
|
46
|
+
"@jxsuite/runtime": "^0.28.3",
|
|
47
|
+
"@jxsuite/schema": "^0.28.3",
|
|
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,18 +15,14 @@
|
|
|
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
|
-
import {
|
|
26
|
-
compileServer,
|
|
27
|
-
compileSiteServer,
|
|
28
|
-
compilePagesFunctions,
|
|
29
|
-
} from "./targets/compile-server.ts";
|
|
25
|
+
import { compileServer, compileSiteServer } from "./targets/compile-server.ts";
|
|
30
26
|
|
|
31
27
|
import {
|
|
32
28
|
compileElement,
|
|
@@ -35,14 +31,16 @@ import {
|
|
|
35
31
|
} from "./targets/compile-element.ts";
|
|
36
32
|
import { compileStaticPage } from "./targets/compile-static.ts";
|
|
37
33
|
import { compileClient } from "./targets/compile-client.ts";
|
|
38
|
-
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";
|
|
39
38
|
|
|
40
39
|
// Re-exports for consumers
|
|
41
40
|
export {
|
|
42
41
|
isDynamic,
|
|
43
42
|
compileServer,
|
|
44
43
|
compileSiteServer,
|
|
45
|
-
compilePagesFunctions,
|
|
46
44
|
compileElement,
|
|
47
45
|
compileElementPage,
|
|
48
46
|
compileClient,
|
|
@@ -50,77 +48,85 @@ export {
|
|
|
50
48
|
|
|
51
49
|
// ─── Entry ────────────────────────────────────────────────────────────────────
|
|
52
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
|
+
|
|
53
60
|
/**
|
|
54
61
|
* Compile a Jx document to HTML (+ optional JS module files).
|
|
55
62
|
*
|
|
56
63
|
* Routing: 1. Not dynamic → static HTML/CSS, zero JS 2. tagName contains hyphen → custom element
|
|
57
64
|
* (lit-html) 3. Otherwise → pre-rendered HTML with reactive bindings
|
|
58
65
|
*
|
|
59
|
-
* @param {string |
|
|
60
|
-
* @param {
|
|
66
|
+
* @param {string | JxDocument} sourcePath - Path to .json file, URL, or raw document object
|
|
67
|
+
* @param {CompileOptions} [opts]
|
|
61
68
|
* @returns {Promise<{
|
|
62
69
|
* html: string;
|
|
63
70
|
* files: { path: string; content: string; tagName?: string }[];
|
|
64
71
|
* }>}
|
|
65
72
|
*/
|
|
66
|
-
export async function compile(sourcePath: string |
|
|
73
|
+
export async function compile(sourcePath: string | JxDocument, opts: CompileOptions = {}) {
|
|
67
74
|
const {
|
|
68
75
|
title = "Jx App",
|
|
69
76
|
reactivitySrc = DEFAULT_REACTIVITY_SRC,
|
|
70
77
|
litHtmlSrc = DEFAULT_LIT_HTML_SRC,
|
|
71
78
|
projectStyle = null,
|
|
72
|
-
} = opts
|
|
79
|
+
} = opts;
|
|
73
80
|
|
|
74
|
-
let raw;
|
|
81
|
+
let raw: JxDocument;
|
|
75
82
|
if (typeof sourcePath === "string") {
|
|
76
83
|
const source = readFileSync(sourcePath, "utf8");
|
|
77
84
|
if (sourcePath.endsWith(".json")) {
|
|
78
|
-
raw =
|
|
85
|
+
raw = parseJxDocument(source, sourcePath);
|
|
79
86
|
} else {
|
|
80
87
|
const { extname } = await import("node:path");
|
|
81
88
|
const ext = extname(sourcePath).toLowerCase();
|
|
82
|
-
const
|
|
83
|
-
.formats as import("@jxsuite/schema/format-registry").FormatRegistry;
|
|
84
|
-
const entry = registry?.byExtension?.(ext, "parse");
|
|
89
|
+
const entry = opts.formats?.byExtension?.(ext, "parse");
|
|
85
90
|
if (!entry) {
|
|
86
91
|
const { unknownFormatError } = await import("./site/format-host.ts");
|
|
87
92
|
throw unknownFormatError(sourcePath, ext);
|
|
88
93
|
}
|
|
89
|
-
|
|
94
|
+
// Format plugins contractually parse source text into a Jx document.
|
|
95
|
+
raw = (await entry.call("parse", source)) as JxDocument;
|
|
90
96
|
}
|
|
91
97
|
} else {
|
|
92
98
|
raw = sourcePath;
|
|
93
99
|
}
|
|
94
100
|
|
|
95
101
|
// Route 0: .class.json schema-defined class → JS class module
|
|
96
|
-
if (raw
|
|
102
|
+
if (isClassDef(raw)) {
|
|
97
103
|
const { compileClassJson } = await import("./targets/compile-class.js");
|
|
98
104
|
const jsContent = compileClassJson(raw, opts);
|
|
99
105
|
const outputPath =
|
|
100
106
|
typeof sourcePath === "string"
|
|
101
107
|
? sourcePath.replace(/\.class\.json$/, ".js")
|
|
102
108
|
: `${raw.title}.js`;
|
|
103
|
-
return {
|
|
109
|
+
return { files: [{ content: jsContent, path: outputPath }], html: "" };
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
// Route 1: Fully static → plain HTML/CSS
|
|
107
113
|
if (!isDynamic(raw)) {
|
|
108
114
|
return compileStaticPage(raw, {
|
|
109
|
-
title,
|
|
110
|
-
reactivitySrc,
|
|
111
115
|
litHtmlSrc,
|
|
112
116
|
projectStyle,
|
|
117
|
+
reactivitySrc,
|
|
118
|
+
title,
|
|
113
119
|
});
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
// Route 2: Custom element tagName (contains hyphen) → lit-html web component
|
|
117
123
|
if (raw.tagName && raw.tagName.includes("-")) {
|
|
118
|
-
const tagName = raw
|
|
124
|
+
const { tagName } = raw;
|
|
119
125
|
const className = tagNameToClassName(tagName);
|
|
120
126
|
const moduleContent = emitElementModule(raw, className, []);
|
|
121
127
|
const moduleFile = {
|
|
122
|
-
path: `${tagName}.js`,
|
|
123
128
|
content: moduleContent,
|
|
129
|
+
path: `${tagName}.js`,
|
|
124
130
|
tagName,
|
|
125
131
|
};
|
|
126
132
|
const styleBlock = compileStyles(raw, raw.$media ?? {});
|
|
@@ -147,11 +153,11 @@ export async function compile(sourcePath: string | any, opts: Record<string, unk
|
|
|
147
153
|
</body>
|
|
148
154
|
</html>`;
|
|
149
155
|
|
|
150
|
-
return {
|
|
156
|
+
return { files: [moduleFile], html };
|
|
151
157
|
}
|
|
152
158
|
|
|
153
159
|
// Route 3: Dynamic with standard tagName → pre-rendered HTML + reactive bindings
|
|
154
|
-
return compileClient(raw, {
|
|
160
|
+
return compileClient(raw, { litHtmlSrc, projectStyle, reactivitySrc, title });
|
|
155
161
|
}
|
|
156
162
|
|
|
157
163
|
// ─── CLI ──────────────────────────────────────────────────────────────────────
|