@jxsuite/compiler 1.1.0 → 1.3.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/dist/cli.js +263 -185
- package/dist/compiler.js +111 -109
- package/package.json +8 -7
- package/src/cli.ts +9 -12
- package/src/compiler.ts +18 -2
- package/src/shared.ts +170 -110
- package/src/site/bundler.ts +187 -0
- package/src/site/prototype-resolver.ts +15 -0
- package/src/site/schema-command.ts +22 -9
- package/src/site/site-build.ts +147 -13
- package/src/site/validate-command.ts +264 -0
- package/src/targets/compile-client.ts +17 -3
- package/src/targets/compile-element.ts +28 -3
- package/src/targets/compile-static.ts +17 -2
|
@@ -41,6 +41,12 @@ import type {
|
|
|
41
41
|
export interface CompileElementOptions {
|
|
42
42
|
/** Resolve an `$elements` ref path to its emitted JS module path. */
|
|
43
43
|
resolveElementPath?: (refPath: string, currentDir: string | null) => string;
|
|
44
|
+
/**
|
|
45
|
+
* Rewrite a Function-def `$src` specifier to its served URL (bundleable specifiers → their
|
|
46
|
+
* `/assets/` bundle path). Receives the directory of the declaring document for relative
|
|
47
|
+
* specifiers. Identity when omitted.
|
|
48
|
+
*/
|
|
49
|
+
rewriteSrc?: (specifier: string, docDir: string | null) => string;
|
|
44
50
|
$media?: Record<string, string>;
|
|
45
51
|
formats?: FormatRegistry;
|
|
46
52
|
basePath?: string | null;
|
|
@@ -135,7 +141,13 @@ export async function compileElement(
|
|
|
135
141
|
if (optsMedia) {
|
|
136
142
|
doc.$media = { ...optsMedia, ...doc.$media };
|
|
137
143
|
}
|
|
138
|
-
const
|
|
144
|
+
const { rewriteSrc } = opts;
|
|
145
|
+
const jsContent = emitElementModule(
|
|
146
|
+
doc,
|
|
147
|
+
className,
|
|
148
|
+
elementImports,
|
|
149
|
+
rewriteSrc ? (spec: string) => rewriteSrc(spec, currentDir) : undefined,
|
|
150
|
+
);
|
|
139
151
|
const outputPath = filePath ? filePath.replace(/\.json$/, ".js") : `${tagName}.js`;
|
|
140
152
|
files.push({ content: jsContent, path: outputPath, tagName });
|
|
141
153
|
}
|
|
@@ -244,7 +256,12 @@ function extractInitialValue(def: JxMutableNode) {
|
|
|
244
256
|
* @param {string[]} elementImports
|
|
245
257
|
* @returns {string}
|
|
246
258
|
*/
|
|
247
|
-
export function emitElementModule(
|
|
259
|
+
export function emitElementModule(
|
|
260
|
+
doc: JxDocument,
|
|
261
|
+
className: string,
|
|
262
|
+
elementImports: string[],
|
|
263
|
+
rewriteSrc?: (specifier: string) => string,
|
|
264
|
+
) {
|
|
248
265
|
const lines: string[] = ["// Generated by @jxsuite/compiler — do not edit manually"];
|
|
249
266
|
|
|
250
267
|
if (doc.$id) {
|
|
@@ -269,7 +286,10 @@ export function emitElementModule(doc: JxDocument, className: string, elementImp
|
|
|
269
286
|
}
|
|
270
287
|
}
|
|
271
288
|
for (const [srcPath, names] of srcImportMap) {
|
|
272
|
-
|
|
289
|
+
// Bundleable specifiers (npm:…, ./relative) are rewritten to their /assets/ bundle URL;
|
|
290
|
+
// The site build bundles them after all documents compile (spec.md §12).
|
|
291
|
+
const importPath = rewriteSrc ? rewriteSrc(srcPath) : srcPath;
|
|
292
|
+
lines.push(`import { ${names.join(", ")} } from '${importPath}';`);
|
|
273
293
|
}
|
|
274
294
|
|
|
275
295
|
lines.push(
|
|
@@ -486,11 +506,16 @@ export function emitElementModule(doc: JxDocument, className: string, elementImp
|
|
|
486
506
|
);
|
|
487
507
|
}
|
|
488
508
|
lines.push(
|
|
509
|
+
// Lifecycle: onMount (spec §16.4) — same microtask contract as the runtime
|
|
510
|
+
" if (typeof this.state.onMount === 'function') {",
|
|
511
|
+
" queueMicrotask(() => this.state.onMount(this.state));",
|
|
512
|
+
" }",
|
|
489
513
|
" }",
|
|
490
514
|
"",
|
|
491
515
|
// DisconnectedCallback
|
|
492
516
|
" disconnectedCallback() {",
|
|
493
517
|
" if (this.#dispose) { this.#dispose(); this.#dispose = null; }",
|
|
518
|
+
" if (typeof this.state.onUnmount === 'function') { this.state.onUnmount(this.state); }",
|
|
494
519
|
" }",
|
|
495
520
|
"}",
|
|
496
521
|
"",
|
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
buildAttrs,
|
|
10
|
+
colorSchemePrePaintScript,
|
|
10
11
|
compileStyles,
|
|
11
12
|
createCompileContext,
|
|
12
13
|
escapeHtml,
|
|
13
14
|
isNodeDynamic,
|
|
15
|
+
pureSchemeOf,
|
|
14
16
|
resolveStaticValue,
|
|
15
17
|
SELF_CLOSING,
|
|
16
18
|
} from "../shared.ts";
|
|
@@ -31,6 +33,7 @@ export function compileStaticPage(
|
|
|
31
33
|
reactivitySrc?: string;
|
|
32
34
|
litHtmlSrc?: string;
|
|
33
35
|
projectStyle?: JxStyle | null;
|
|
36
|
+
prePaintScheme?: boolean;
|
|
34
37
|
[key: string]: unknown;
|
|
35
38
|
},
|
|
36
39
|
) {
|
|
@@ -51,7 +54,12 @@ export function compileStaticPage(
|
|
|
51
54
|
let moduleScripts = "";
|
|
52
55
|
if (islands.length > 0) {
|
|
53
56
|
for (const island of islands) {
|
|
54
|
-
const moduleContent = emitElementModule(
|
|
57
|
+
const moduleContent = emitElementModule(
|
|
58
|
+
island.def as JxDocument,
|
|
59
|
+
island.className,
|
|
60
|
+
[],
|
|
61
|
+
opts.rewriteSrc as ((specifier: string) => string) | undefined,
|
|
62
|
+
);
|
|
55
63
|
files.push({
|
|
56
64
|
content: moduleContent,
|
|
57
65
|
path: `_islands/${island.tagName}.js`,
|
|
@@ -73,13 +81,20 @@ export function compileStaticPage(
|
|
|
73
81
|
.join("\n ");
|
|
74
82
|
}
|
|
75
83
|
|
|
84
|
+
// Forced-scheme contract (spec §9.5): restore the persisted scheme before any styles apply
|
|
85
|
+
const prePaint =
|
|
86
|
+
opts.prePaintScheme !== false &&
|
|
87
|
+
Object.values(raw.$media ?? {}).some((q) => pureSchemeOf(String(q)) !== null)
|
|
88
|
+
? `<script>${colorSchemePrePaintScript()}</script>\n `
|
|
89
|
+
: "";
|
|
90
|
+
|
|
76
91
|
const html = `<!DOCTYPE html>
|
|
77
92
|
<html lang="en">
|
|
78
93
|
<head>
|
|
79
94
|
<meta charset="utf-8">
|
|
80
95
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
81
96
|
<title>${escapeHtml(title)}</title>
|
|
82
|
-
${importMap}
|
|
97
|
+
${prePaint}${importMap}
|
|
83
98
|
${styleBlock}
|
|
84
99
|
</head>
|
|
85
100
|
<body>
|