@stacksjs/stx 0.2.133 → 0.2.135

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.
@@ -1,3 +1,4 @@
1
+ export declare function getCrosswindServeAsset(hash: string): string | undefined;
1
2
  /**
2
3
  * Lazily load the Crosswind module
3
4
  * Returns null if Crosswind is not installed
@@ -70,7 +71,7 @@ export declare function generateCrosswindCSS(htmlContent: string, appDir?: strin
70
71
  * Inject generated CSS into HTML content
71
72
  * Tries to inject before </head>, falls back to <body> or prepends
72
73
  */
73
- export declare function injectCrosswindCSS(htmlContent: string, appDir?: string): Promise<string>;
74
+ export declare function injectCrosswindCSS(htmlContent: string, appDir?: string, serveMode?: boolean): Promise<string>;
74
75
  // Type for Crosswind module
75
76
  declare interface CrosswindModule {
76
77
  CSSGenerator: new (config: CrosswindConfig) => CSSGenerator
@@ -3,7 +3,7 @@ import { hasLocalConfig } from "bunfig/discovery";
3
3
  import { stateDir } from "../state-dir.js";
4
4
  import { colors } from "./terminal-colors.js";
5
5
  let crosswindModule = null, crosswindLoadAttempted = !1, cachedConfig = null, cachedCSS = "", isBuilding = !1;
6
- const MAX_CACHE = 256, cssByClassSet = new Map;
6
+ const MAX_CACHE = 256, cssByClassSet = new Map, serveCssByHash = new Map;
7
7
  let diskCacheRoot = null, configFingerprint = null;
8
8
  function shortHash(input) {
9
9
  return Bun.hash(input).toString(16).padStart(16, "0").slice(0, 16);
@@ -15,6 +15,23 @@ function setLruCache(key, value) {
15
15
  cssByClassSet.delete(cssByClassSet.keys().next().value);
16
16
  cssByClassSet.set(key, value);
17
17
  }
18
+ function registerServeCss(css) {
19
+ const hash = shortHash(css);
20
+ if (serveCssByHash.has(hash))
21
+ serveCssByHash.delete(hash);
22
+ else if (serveCssByHash.size >= MAX_CACHE)
23
+ serveCssByHash.delete(serveCssByHash.keys().next().value);
24
+ serveCssByHash.set(hash, css);
25
+ return hash;
26
+ }
27
+ export function getCrosswindServeAsset(hash) {
28
+ const css = serveCssByHash.get(hash);
29
+ if (css === void 0)
30
+ return;
31
+ serveCssByHash.delete(hash);
32
+ serveCssByHash.set(hash, css);
33
+ return css;
34
+ }
18
35
  async function readDiskCache(key) {
19
36
  if (!diskCacheRoot)
20
37
  return null;
@@ -140,6 +157,7 @@ export async function loadCrosswind() {
140
157
  }
141
158
  export function resetCssCache() {
142
159
  cssByClassSet.clear();
160
+ serveCssByHash.clear();
143
161
  }
144
162
  export function resetCrosswindCache() {
145
163
  crosswindModule = null;
@@ -147,6 +165,7 @@ export function resetCrosswindCache() {
147
165
  cachedConfig = null;
148
166
  cachedCSS = "";
149
167
  cssByClassSet.clear();
168
+ serveCssByHash.clear();
150
169
  configFingerprint = null;
151
170
  }
152
171
  export async function loadCrosswindConfig(cwd) {
@@ -377,27 +396,27 @@ export async function generateCrosswindCSS(htmlContent, appDir) {
377
396
  return "";
378
397
  }
379
398
  }
380
- export async function injectCrosswindCSS(htmlContent, appDir) {
399
+ export async function injectCrosswindCSS(htmlContent, appDir, serveMode = !1) {
381
400
  const css = await generateCrosswindCSS(htmlContent, appDir);
382
401
  if (!css)
383
402
  return htmlContent;
384
- const styleTag = `<style data-crosswind="generated">
403
+ const assetTag = serveMode ? `<link data-crosswind="generated" rel="stylesheet" href="/_stx/crosswind.${registerServeCss(css)}.css">` : `<style data-crosswind="generated">
385
404
  ${css}
386
- </style>`, existing = /<style data-crosswind="generated">[\s\S]*?<\/style>/g;
405
+ </style>`, existing = /(?:<style\b[^>]*\bdata-crosswind=(?:"generated"|'generated')[^>]*>[\s\S]*?<\/style>|<link\b[^>]*\bdata-crosswind=(?:"generated"|'generated')[^>]*>)/g;
387
406
  if (existing.test(htmlContent)) {
388
407
  let placed = !1;
389
408
  return htmlContent.replace(existing, () => {
390
409
  if (placed)
391
410
  return "";
392
411
  placed = !0;
393
- return styleTag;
412
+ return assetTag;
394
413
  });
395
414
  }
396
415
  if (htmlContent.includes("</head>"))
397
- return htmlContent.replace("</head>", `${styleTag}
416
+ return htmlContent.replace("</head>", `${assetTag}
398
417
  </head>`);
399
418
  if (htmlContent.includes("<body"))
400
419
  return htmlContent.replace(/<body([^>]*)>/, `<body$1>
401
- ${styleTag}`);
402
- return styleTag + htmlContent;
420
+ ${assetTag}`);
421
+ return assetTag + htmlContent;
403
422
  }
package/dist/index.d.ts CHANGED
@@ -158,7 +158,7 @@ export * from './dynamic-components';
158
158
  export { definePlugin, pluginManager } from './plugin-system';
159
159
  // These modules are exported first to establish their types
160
160
  export * from './render';
161
- export { generateCrosswindCSS, injectCrosswindCSS, extractClassNames } from './dev-server/crosswind';
161
+ export { extractClassNames, generateCrosswindCSS, getCrosswindServeAsset, injectCrosswindCSS } from './dev-server/crosswind';
162
162
  export { runDoctor, formatDoctorReport, findPantryPackage } from './doctor';
163
163
  export {
164
164
  applyTranslations,
package/dist/index.js CHANGED
@@ -107,7 +107,7 @@ export { createApp, createApp as createStxApp, defineCustomElement } from "./app
107
107
  export * from "./dynamic-components.js";
108
108
  export { definePlugin, pluginManager } from "./plugin-system.js";
109
109
  export * from "./render.js";
110
- export { generateCrosswindCSS, injectCrosswindCSS, extractClassNames } from "./dev-server/crosswind.js";
110
+ export { extractClassNames, generateCrosswindCSS, getCrosswindServeAsset, injectCrosswindCSS } from "./dev-server/crosswind.js";
111
111
  export { runDoctor, formatDoctorReport, findPantryPackage } from "./doctor.js";
112
112
  export {
113
113
  applyTranslations,
package/dist/process.js CHANGED
@@ -316,7 +316,7 @@ export async function processDirectives(template, context, filePath, options, de
316
316
  }
317
317
  } catch {}
318
318
  if (isTopLevel && context.__stx_inject_css !== !1)
319
- result = await injectCrosswindCSS(result);
319
+ result = await injectCrosswindCSS(result, void 0, options.buildMode === "serve");
320
320
  if (isTopLevel)
321
321
  result = dedupeScopedStyles(result);
322
322
  result = result.replace(/\x00STX_ESCAPED_AT\x00/g, "@");