@jxsuite/compiler 0.25.3 → 0.25.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 +157 -157
- package/package.json +4 -4
- package/src/site/image-cache.ts +3 -3
- package/src/site/image-optimizer.ts +15 -1
- package/src/site/site-build.ts +19 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/compiler",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.4",
|
|
4
4
|
"description": "Jx static HTML compiler, island detector, and site builder",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@apidevtools/json-schema-ref-parser": "^15.3.5",
|
|
44
|
-
"@jxsuite/parser": "^0.25.
|
|
45
|
-
"@jxsuite/runtime": "^0.25.
|
|
46
|
-
"@jxsuite/schema": "^0.25.
|
|
44
|
+
"@jxsuite/parser": "^0.25.4",
|
|
45
|
+
"@jxsuite/runtime": "^0.25.4",
|
|
46
|
+
"@jxsuite/schema": "^0.25.4",
|
|
47
47
|
"remark-gfm": "^4.0.1",
|
|
48
48
|
"remark-stringify": "^11.0.0",
|
|
49
49
|
"sharp": "^0.34.5",
|
package/src/site/image-cache.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Image-cache.js — Content-hash based cache for processed image variants.
|
|
3
3
|
*
|
|
4
4
|
* Stores a manifest of previously processed images so that unchanged sources can skip re-encoding
|
|
5
|
-
* on subsequent builds. Cache lives in .
|
|
5
|
+
* on subsequent builds. Cache lives in .cache/images/.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
@@ -41,7 +41,7 @@ export function cacheKey(srcPath: string, config: ImageConfig) {
|
|
|
41
41
|
* @returns {CacheManifest}
|
|
42
42
|
*/
|
|
43
43
|
export function loadCache(projectRoot: string) {
|
|
44
|
-
const manifestPath = resolve(projectRoot, ".
|
|
44
|
+
const manifestPath = resolve(projectRoot, ".cache/images/manifest.json");
|
|
45
45
|
if (!existsSync(manifestPath)) {
|
|
46
46
|
return { version: 1, entries: {} };
|
|
47
47
|
}
|
|
@@ -59,7 +59,7 @@ export function loadCache(projectRoot: string) {
|
|
|
59
59
|
* @param {CacheManifest} cache
|
|
60
60
|
*/
|
|
61
61
|
export function saveCache(projectRoot: string, cache: CacheManifest) {
|
|
62
|
-
const cacheDir = resolve(projectRoot, ".
|
|
62
|
+
const cacheDir = resolve(projectRoot, ".cache/images");
|
|
63
63
|
mkdirSync(cacheDir, { recursive: true });
|
|
64
64
|
writeFileSync(resolve(cacheDir, "manifest.json"), JSON.stringify(cache, null, 2), "utf8");
|
|
65
65
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { readFileSync, mkdirSync, existsSync } from "node:fs";
|
|
10
10
|
import { resolve, basename, extname } from "node:path";
|
|
11
|
+
import { createRequire } from "node:module";
|
|
11
12
|
|
|
12
13
|
export interface ImageVariant {
|
|
13
14
|
width: number; // Pixel width of the variant
|
|
@@ -35,9 +36,22 @@ let _sharp: typeof import("sharp") | null = null;
|
|
|
35
36
|
|
|
36
37
|
async function getSharp() {
|
|
37
38
|
if (_sharp) return _sharp;
|
|
39
|
+
// Primary: dynamic import — works in tests (mock.module intercepts it) and in
|
|
40
|
+
// production installs where @img/sharp-* native packages are adjacent to cli.js.
|
|
38
41
|
try {
|
|
39
42
|
const sharpMod = await import("sharp");
|
|
40
|
-
_sharp = sharpMod.default;
|
|
43
|
+
_sharp = sharpMod.default as typeof import("sharp");
|
|
44
|
+
return _sharp;
|
|
45
|
+
} catch {
|
|
46
|
+
// Fall through to CJS fallback below.
|
|
47
|
+
}
|
|
48
|
+
// Fallback: resolve from the project being compiled. This covers symlinked
|
|
49
|
+
// monorepo dev environments (e.g. NixOS) where Node.js resolves import.meta.url
|
|
50
|
+
// to the compiler package's real path, making the @img/sharp-* packages
|
|
51
|
+
// unreachable via the primary import path.
|
|
52
|
+
try {
|
|
53
|
+
const req = createRequire(resolve(process.cwd(), "package.json"));
|
|
54
|
+
_sharp = req("sharp") as typeof import("sharp");
|
|
41
55
|
return _sharp;
|
|
42
56
|
} catch (e) {
|
|
43
57
|
throw new Error(
|
package/src/site/site-build.ts
CHANGED
|
@@ -93,7 +93,8 @@ export async function buildSite(
|
|
|
93
93
|
const hasOptimized = existsSync(optimizedDir);
|
|
94
94
|
let tmpOptimized = "";
|
|
95
95
|
if (hasOptimized) {
|
|
96
|
-
tmpOptimized = resolve(projectRoot, ".
|
|
96
|
+
tmpOptimized = resolve(projectRoot, ".cache/_optimized_tmp");
|
|
97
|
+
mkdirSync(resolve(projectRoot, ".cache"), { recursive: true });
|
|
97
98
|
renameSync(optimizedDir, tmpOptimized);
|
|
98
99
|
}
|
|
99
100
|
rmSync(outDir, { recursive: true, force: true });
|
|
@@ -624,6 +625,16 @@ function expandMapTemplate(template: JxMutableNode, scope: Record<string, unknow
|
|
|
624
625
|
}
|
|
625
626
|
}
|
|
626
627
|
node.attributes = attrs;
|
|
628
|
+
} else if (k === "$props" && v && typeof v === "object") {
|
|
629
|
+
const props = { ...v } as Record<string, unknown>;
|
|
630
|
+
for (const [pk, pv] of Object.entries(props)) {
|
|
631
|
+
if (typeof pv === "string" && isTemplateString(pv)) {
|
|
632
|
+
const resolved = evaluateMapTemplate(pv, scope);
|
|
633
|
+
// null = evaluation error → keep template string; undefined = missing data → use null
|
|
634
|
+
props[pk] = resolved !== null ? (resolved ?? null) : pv;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
node.$props = props;
|
|
627
638
|
} else if (typeof v === "string" && isTemplateString(v)) {
|
|
628
639
|
node[k] = evaluateMapTemplate(v, scope) ?? v;
|
|
629
640
|
} else {
|
|
@@ -694,6 +705,13 @@ function resolveDocTemplates(node: JxElement | string, scope: Record<string, unk
|
|
|
694
705
|
}
|
|
695
706
|
}
|
|
696
707
|
}
|
|
708
|
+
if (node.$props && typeof node.$props === "object") {
|
|
709
|
+
for (const [k, v] of Object.entries(node.$props)) {
|
|
710
|
+
if (typeof v === "string" && isTemplateString(v)) {
|
|
711
|
+
node.$props[k] = evaluateStaticTemplate(v, scope) ?? v;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
697
715
|
const rawChildren = node.children as unknown;
|
|
698
716
|
if (
|
|
699
717
|
rawChildren &&
|