@timber-js/app 0.2.0-alpha.65 → 0.2.0-alpha.67
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/index.js +90 -8
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.d.ts +12 -5
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/cli.ts +0 -0
- package/src/plugins/fonts.ts +71 -9
- package/LICENSE +0 -8
package/dist/index.js
CHANGED
|
@@ -13491,6 +13491,48 @@ async function isCacheHit(metaPath, dataPath) {
|
|
|
13491
13491
|
return false;
|
|
13492
13492
|
}
|
|
13493
13493
|
}
|
|
13494
|
+
/**
|
|
13495
|
+
* Generate @font-face descriptors for cached (production) Google Fonts.
|
|
13496
|
+
*
|
|
13497
|
+
* Each CachedFont gets a FontFaceDescriptor pointing to the
|
|
13498
|
+
* content-hashed URL under `/_timber/fonts/`.
|
|
13499
|
+
*/
|
|
13500
|
+
function generateProductionFontFaces(cachedFonts, display) {
|
|
13501
|
+
return cachedFonts.map((cf) => ({
|
|
13502
|
+
family: cf.face.family,
|
|
13503
|
+
src: `url('/_timber/fonts/${cf.hashedFilename}') format('woff2')`,
|
|
13504
|
+
weight: cf.face.weight,
|
|
13505
|
+
style: cf.face.style,
|
|
13506
|
+
display,
|
|
13507
|
+
unicodeRange: cf.face.unicodeRange
|
|
13508
|
+
}));
|
|
13509
|
+
}
|
|
13510
|
+
/**
|
|
13511
|
+
* Generate @font-face descriptors for dev mode (CDN-pointing).
|
|
13512
|
+
*
|
|
13513
|
+
* In dev mode, we query the Google Fonts API but use the CDN URLs
|
|
13514
|
+
* directly instead of downloading. This avoids the download/cache
|
|
13515
|
+
* step during `vite dev`.
|
|
13516
|
+
*/
|
|
13517
|
+
function generateDevFontFaces(faces, display) {
|
|
13518
|
+
return faces.map((face) => ({
|
|
13519
|
+
family: face.family,
|
|
13520
|
+
src: `url('${face.url}') format('woff2')`,
|
|
13521
|
+
weight: face.weight,
|
|
13522
|
+
style: face.style,
|
|
13523
|
+
display,
|
|
13524
|
+
unicodeRange: face.unicodeRange
|
|
13525
|
+
}));
|
|
13526
|
+
}
|
|
13527
|
+
/**
|
|
13528
|
+
* Resolve dev-mode font faces for an extracted font.
|
|
13529
|
+
*
|
|
13530
|
+
* Fetches the CSS from Google Fonts API and returns FontFaceDescriptors
|
|
13531
|
+
* pointing to CDN URLs. No files are downloaded.
|
|
13532
|
+
*/
|
|
13533
|
+
async function resolveDevFontFaces(font) {
|
|
13534
|
+
return generateDevFontFaces(filterBySubsets(await fetchGoogleFontsCss(buildGoogleFontsUrl(font)), font.subsets), font.display);
|
|
13535
|
+
}
|
|
13494
13536
|
//#endregion
|
|
13495
13537
|
//#region src/plugins/fonts.ts
|
|
13496
13538
|
var VIRTUAL_GOOGLE = "@timber/fonts/google";
|
|
@@ -13662,15 +13704,22 @@ function generateLocalVirtualModule() {
|
|
|
13662
13704
|
/**
|
|
13663
13705
|
* Generate CSS for a single extracted font.
|
|
13664
13706
|
*
|
|
13665
|
-
* Includes @font-face rules (for local fonts), fallback @font-face,
|
|
13707
|
+
* Includes @font-face rules (for local and Google fonts), fallback @font-face,
|
|
13666
13708
|
* and the scoped class rule.
|
|
13709
|
+
*
|
|
13710
|
+
* For Google fonts, pass the resolved FontFaceDescriptor[] from either
|
|
13711
|
+
* `generateProductionFontFaces()` (production) or `resolveDevFontFaces()` (dev).
|
|
13667
13712
|
*/
|
|
13668
|
-
function generateFontCss(font) {
|
|
13713
|
+
function generateFontCss(font, googleFaces) {
|
|
13669
13714
|
const cssParts = [];
|
|
13670
13715
|
if (font.provider === "local" && font.localSources) {
|
|
13671
13716
|
const faceCss = generateFontFaces(generateLocalFontFaces(font.family, font.localSources, font.display));
|
|
13672
13717
|
if (faceCss) cssParts.push(faceCss);
|
|
13673
13718
|
}
|
|
13719
|
+
if (font.provider === "google" && googleFaces && googleFaces.length > 0) {
|
|
13720
|
+
const faceCss = generateFontFaces(googleFaces);
|
|
13721
|
+
if (faceCss) cssParts.push(faceCss);
|
|
13722
|
+
}
|
|
13674
13723
|
const fallbackCss = generateFallbackCss(font.family);
|
|
13675
13724
|
if (fallbackCss) cssParts.push(fallbackCss);
|
|
13676
13725
|
if (font.variable) cssParts.push(generateVariableClass(font.className, font.variable, font.fontFamily));
|
|
@@ -13680,12 +13729,18 @@ function generateFontCss(font) {
|
|
|
13680
13729
|
/**
|
|
13681
13730
|
* Generate the CSS output for all extracted fonts.
|
|
13682
13731
|
*
|
|
13683
|
-
* Includes @font-face rules for local fonts, fallback @font-face
|
|
13684
|
-
* and scoped classes.
|
|
13732
|
+
* Includes @font-face rules for local and Google fonts, fallback @font-face
|
|
13733
|
+
* rules, and scoped classes.
|
|
13734
|
+
*
|
|
13735
|
+
* `googleFontFacesMap` provides pre-resolved FontFaceDescriptor[] for each
|
|
13736
|
+
* Google font ID (keyed by ExtractedFont.id).
|
|
13685
13737
|
*/
|
|
13686
|
-
function generateAllFontCss(registry) {
|
|
13738
|
+
function generateAllFontCss(registry, googleFontFacesMap) {
|
|
13687
13739
|
const cssParts = [];
|
|
13688
|
-
for (const font of registry.values())
|
|
13740
|
+
for (const font of registry.values()) {
|
|
13741
|
+
const googleFaces = googleFontFacesMap?.get(font.id);
|
|
13742
|
+
cssParts.push(generateFontCss(font, googleFaces));
|
|
13743
|
+
}
|
|
13689
13744
|
return cssParts.join("\n\n");
|
|
13690
13745
|
}
|
|
13691
13746
|
/**
|
|
@@ -13736,6 +13791,11 @@ function timberFonts(ctx) {
|
|
|
13736
13791
|
const registry = /* @__PURE__ */ new Map();
|
|
13737
13792
|
/** Fonts downloaded during buildStart (production only). */
|
|
13738
13793
|
let cachedFonts = [];
|
|
13794
|
+
/**
|
|
13795
|
+
* Pre-resolved @font-face descriptors for Google fonts, keyed by font ID.
|
|
13796
|
+
* Populated in buildStart (production) or lazily in load (dev).
|
|
13797
|
+
*/
|
|
13798
|
+
const googleFontFacesMap = /* @__PURE__ */ new Map();
|
|
13739
13799
|
return {
|
|
13740
13800
|
name: "timber-fonts",
|
|
13741
13801
|
resolveId(id) {
|
|
@@ -13750,11 +13810,22 @@ function timberFonts(ctx) {
|
|
|
13750
13810
|
if (cleanId === VIRTUAL_FONT_CSS_REGISTER) return RESOLVED_FONT_CSS_REGISTER;
|
|
13751
13811
|
return null;
|
|
13752
13812
|
},
|
|
13753
|
-
load(id) {
|
|
13813
|
+
async load(id) {
|
|
13754
13814
|
if (id === RESOLVED_GOOGLE) return generateGoogleVirtualModule(registry);
|
|
13755
13815
|
if (id === RESOLVED_LOCAL) return generateLocalVirtualModule();
|
|
13756
13816
|
if (id === RESOLVED_FONT_CSS_REGISTER) {
|
|
13757
|
-
|
|
13817
|
+
if (ctx.dev) {
|
|
13818
|
+
const googleFonts = [...registry.values()].filter((f) => f.provider === "google");
|
|
13819
|
+
for (const font of googleFonts) if (!googleFontFacesMap.has(font.id)) try {
|
|
13820
|
+
const faces = await resolveDevFontFaces(font);
|
|
13821
|
+
googleFontFacesMap.set(font.id, faces);
|
|
13822
|
+
} catch (e) {
|
|
13823
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
13824
|
+
console.warn(`[timber-fonts] Failed to resolve Google font "${font.family}": ${msg}`);
|
|
13825
|
+
googleFontFacesMap.set(font.id, []);
|
|
13826
|
+
}
|
|
13827
|
+
}
|
|
13828
|
+
const css = generateAllFontCss(registry, googleFontFacesMap);
|
|
13758
13829
|
return `globalThis.__timber_font_css = ${JSON.stringify(css)};`;
|
|
13759
13830
|
}
|
|
13760
13831
|
return null;
|
|
@@ -13801,6 +13872,17 @@ function timberFonts(ctx) {
|
|
|
13801
13872
|
const googleFonts = [...registry.values()].filter((f) => f.provider === "google");
|
|
13802
13873
|
if (googleFonts.length === 0) return;
|
|
13803
13874
|
cachedFonts = await downloadAndCacheFonts(googleFonts, ctx.root);
|
|
13875
|
+
const cachedByFamily = /* @__PURE__ */ new Map();
|
|
13876
|
+
for (const cf of cachedFonts) {
|
|
13877
|
+
const key = cf.face.family.toLowerCase();
|
|
13878
|
+
const arr = cachedByFamily.get(key) ?? [];
|
|
13879
|
+
arr.push(cf);
|
|
13880
|
+
cachedByFamily.set(key, arr);
|
|
13881
|
+
}
|
|
13882
|
+
for (const font of googleFonts) {
|
|
13883
|
+
const faces = generateProductionFontFaces(cachedByFamily.get(font.family.toLowerCase()) ?? [], font.display);
|
|
13884
|
+
googleFontFacesMap.set(font.id, faces);
|
|
13885
|
+
}
|
|
13804
13886
|
},
|
|
13805
13887
|
transform(code, id) {
|
|
13806
13888
|
if (id.startsWith("\0") || id.includes("node_modules")) return null;
|