@stacksjs/stx 0.2.98 → 0.2.100

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,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
3
  import { getPublicEnvDefine } from "./public-env.js";
4
+ import { stateDir } from "./state-dir.js";
4
5
  const EXTERNAL_PATTERNS = [
5
6
  /^stx$/,
6
7
  /^@stacksjs\/stx$/,
@@ -97,7 +98,7 @@ function createBundlePlugin(projectRoot, templateDir, tmpEntry, inputFiles) {
97
98
  };
98
99
  }
99
100
  export async function bundleClientScript(code, filePath, options = {}) {
100
- const projectRoot = options.projectRoot || process.cwd(), minify = options.minify ?? !1, cacheDir = options.cacheDir || path.join(projectRoot, ".stx", "bundle-cache"), hasher = new Bun.CryptoHasher("md5");
101
+ const projectRoot = options.projectRoot || process.cwd(), minify = options.minify ?? !1, cacheDir = options.cacheDir || stateDir(projectRoot, "bundle-cache"), hasher = new Bun.CryptoHasher("md5");
101
102
  hasher.update(code + filePath);
102
103
  const hash = hasher.digest("hex").slice(0, 12), cachePath = path.join(cacheDir, `${hash}.js`), depsPath = path.join(cacheDir, `${hash}.deps.json`), cacheFile = Bun.file(cachePath);
103
104
  if (await cacheFile.exists()) {
@@ -125,7 +126,7 @@ export async function bundleClientScript(code, filePath, options = {}) {
125
126
  }
126
127
  console.log("[stx:bundler] cache invalidated by dep change:", hash);
127
128
  }
128
- const tmpDir = path.join(projectRoot, ".stx", "bundle-tmp"), tmpEntry = path.join(tmpDir, `${hash}.ts`), tmpOutDir = path.join(tmpDir, "out", hash);
129
+ const tmpDir = stateDir(projectRoot, "bundle-tmp"), tmpEntry = path.join(tmpDir, `${hash}.ts`), tmpOutDir = path.join(tmpDir, "out", hash);
129
130
  fs.mkdirSync(tmpDir, { recursive: !0 });
130
131
  fs.mkdirSync(tmpOutDir, { recursive: !0 });
131
132
  const templateDir = path.dirname(filePath), declNames = [], declRegex = /^(export\s+)?(?:const|let|var)\s+(?:\{([^}]+)\}|(\w+))/gm, funcRegex = /^(export\s+)?(?:async\s+)?function\s+(\w+)/gm;
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { createSafeFunction, isExpressionSafe, safeEvaluateObject } from "./safe-evaluator.js";
3
- import { renderComponentWithSlot } from "./utils.js";
3
+ import { renderComponentWithSlot, userComponentFileExists } from "./utils.js";
4
4
  export function pascalToKebab(str) {
5
5
  return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
6
6
  }
@@ -537,7 +537,10 @@ export async function processCustomElements(template, context, filePath, compone
537
537
  let result = html;
538
538
  const tags = findComponentTags(result, tagPattern, skipTags);
539
539
  for (let i = tags.length - 1;i >= 0; i--) {
540
- const tag = tags[i], componentPath = isPascalCase ? pascalToKebab(tag.tagName) : tag.tagName, rawProps = parseMultilineAttributes(tag.attributes), props = {};
540
+ const tag = tags[i], componentPath = isPascalCase ? pascalToKebab(tag.tagName) : tag.tagName;
541
+ if (!isPascalCase && tag.tagName.includes("-") && !await userComponentFileExists(componentPath, componentsDir, context, filePath, options))
542
+ continue;
543
+ const rawProps = parseMultilineAttributes(tag.attributes), props = {};
541
544
  for (const [attrName, attrValue] of Object.entries(rawProps)) {
542
545
  if (attrName.startsWith("@"))
543
546
  continue;
@@ -610,6 +610,8 @@ async function processCustomElementTags(template, context, filePath, options, de
610
610
  result = result.substring(0, tag.startIndex) + rendered + result.substring(tag.endIndex);
611
611
  continue;
612
612
  }
613
+ if (!isPascalCase && tag.tagName.includes("-") && !await userComponentFileExists(componentPath, componentsDir, context, filePath, options))
614
+ continue;
613
615
  const mergedProps = {};
614
616
  for (const [key, value] of Object.entries(resolvedProps.static))
615
617
  mergedProps[key] = value;
package/dist/config.js CHANGED
@@ -11,6 +11,7 @@ import { imgDirective } from "./media/image/directive.js";
11
11
  import { videoDirective } from "./media/video/directive.js";
12
12
  import { pwaDirectives } from "./pwa/directives.js";
13
13
  import { metaDirective, structuredDataDirective } from "./seo.js";
14
+ import { DEFAULT_STATE_DIR, rebaseOntoStateDir, setStateDir, stateDirName } from "./state-dir.js";
14
15
  import { webComponentDirectiveHandler } from "./web-components.js";
15
16
  export const defaultConfig = {
16
17
  enabled: !0,
@@ -21,6 +22,7 @@ export const defaultConfig = {
21
22
  defaultLayout: "default",
22
23
  debug: !1,
23
24
  cache: !0,
25
+ stateDir: DEFAULT_STATE_DIR,
24
26
  cachePath: ".stx/cache",
25
27
  cacheVersion: "1.0.0",
26
28
  build: {
@@ -370,6 +372,17 @@ function resolveStxRoot(configRoot, configPagesDir) {
370
372
  return { root: "resources/views", pagesDir: defaultPagesDir };
371
373
  return { root: ".", pagesDir: defaultPagesDir };
372
374
  }
375
+ function applyStateDir(loaded) {
376
+ setStateDir(loaded.stateDir);
377
+ loaded.stateDir = stateDirName();
378
+ loaded.cachePath = rebaseOntoStateDir(loaded.cachePath);
379
+ if (loaded.build)
380
+ loaded.build.cacheDir = rebaseOntoStateDir(loaded.build.cacheDir);
381
+ if (loaded.media?.cache)
382
+ loaded.media.cache.directory = rebaseOntoStateDir(loaded.media.cache.directory);
383
+ if (loaded.story)
384
+ loaded.story.outDir = rebaseOntoStateDir(loaded.story.outDir);
385
+ }
373
386
  let _config = null;
374
387
  const _cwdConfigCache = new Map;
375
388
  let _configPromise = null;
@@ -390,7 +403,9 @@ export async function loadStxConfig(cwd) {
390
403
  cwd: effectiveCwd,
391
404
  defaultConfig,
392
405
  verbose: !1
393
- })).config, resolved = resolveStxRoot(loaded.root, loaded.pagesDir);
406
+ })).config;
407
+ applyStateDir(loaded);
408
+ const resolved = resolveStxRoot(loaded.root, loaded.pagesDir);
394
409
  loaded.root = resolved.root;
395
410
  loaded.pagesDir = resolved.pagesDir;
396
411
  if (loaded.root && loaded.root !== ".") {
@@ -1,5 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { hasLocalConfig } from "bunfig/discovery";
3
+ import { stateDir } from "../state-dir.js";
3
4
  import { colors } from "./terminal-colors.js";
4
5
  let crosswindModule = null, crosswindLoadAttempted = !1, cachedConfig = null, cachedCSS = "", isBuilding = !1;
5
6
  const MAX_CACHE = 256, cssByClassSet = new Map;
@@ -232,7 +233,7 @@ export async function generateCrosswindCSS(htmlContent, appDir) {
232
233
  return "";
233
234
  const resolveRoot = appDir ? path.resolve(appDir) : process.cwd();
234
235
  if (!diskCacheRoot)
235
- diskCacheRoot = path.join(resolveRoot, ".stx/cache");
236
+ diskCacheRoot = stateDir(resolveRoot, "cache");
236
237
  const classSetKey = [...classes].sort().join(" "), cacheKey = `${configFingerprint || "default"}::${classSetKey}`, cached = cssByClassSet.get(cacheKey);
237
238
  if (cached !== void 0) {
238
239
  setLruCache(cacheKey, cached);
@@ -11,6 +11,7 @@ import {
11
11
  stopHmrServer
12
12
  } from "../hot-reload.js";
13
13
  import { partialsCache } from "../includes.js";
14
+ import { stateDir } from "../state-dir.js";
14
15
  import { plugin as stxPlugin } from "../plugin.js";
15
16
  import { createRouter, matchRoute, formatRoutes, findErrorPage } from "../router.js";
16
17
  import {
@@ -138,7 +139,7 @@ export async function serveApp(appDir = ".", options = {}) {
138
139
  console.warn(`${colors.yellow}Broadcasting failed to start: ${err.message}${colors.reset}`);
139
140
  }
140
141
  } catch {}
141
- const outputDir = path.join(absoluteAppDir, ".stx/output");
142
+ const outputDir = stateDir(absoluteAppDir, "output");
142
143
  fs.mkdirSync(outputDir, { recursive: !0 });
143
144
  const builtPages = new Map, streamingRoutes = new Set, renderErrorPage = async (statusCode) => {
144
145
  const errorPagePath = findErrorPage(pagesDir, statusCode);
@@ -184,7 +185,7 @@ export async function serveApp(appDir = ".", options = {}) {
184
185
  merged.componentsDir = resolveRel(merged.componentsDir);
185
186
  merged.layoutsDir = resolveRel(merged.layoutsDir);
186
187
  merged.storesDir = resolveRel(merged.storesDir || "stores");
187
- merged.cachePath = resolveRel(merged.cachePath || ".stx/cache");
188
+ merged.cachePath = resolveRel(merged.cachePath) ?? stateDir(absoluteAppDir, "cache");
188
189
  const isStaticBuild = !requestParams && !options.profile, cacheEnabled = merged.cache !== !1;
189
190
  if (cacheEnabled && isStaticBuild) {
190
191
  const memEntry = templateCache.get(route.filePath);
@@ -353,7 +354,7 @@ export async function serveApp(appDir = ".", options = {}) {
353
354
  if (url.pathname === "/_stx/img") {
354
355
  const { handleImageRequest } = await import("../image-optimization/serve.js"), imgResponse = await handleImageRequest(request, {
355
356
  publicDir: path.join(absoluteAppDir, publicDirName),
356
- cacheDir: path.join(absoluteAppDir, ".stx/cache/img")
357
+ cacheDir: stateDir(absoluteAppDir, "cache", "img")
357
358
  });
358
359
  if (imgResponse)
359
360
  return imgResponse;
@@ -10,6 +10,7 @@ import {
10
10
  stopHmrServer
11
11
  } from "../hot-reload.js";
12
12
  import { partialsCache } from "../includes.js";
13
+ import { stateDir } from "../state-dir.js";
13
14
  import { plugin as stxPlugin } from "../plugin.js";
14
15
  import { clearComponentCache } from "../utils.js";
15
16
  import {
@@ -37,7 +38,7 @@ export async function serveStxFile(filePath, options = {}) {
37
38
  console.error(`${colors.red}Error: Unsupported file type: ${colors.bright}${absolutePath}${colors.reset}. Only .stx and .md files are supported.`);
38
39
  return !1;
39
40
  }
40
- const outputDir = path.join(process.cwd(), ".stx/output");
41
+ const outputDir = stateDir(process.cwd(), "output");
41
42
  fs.mkdirSync(outputDir, { recursive: !0 });
42
43
  console.log(`${colors.blue}Building ${colors.bright}${filePath}${colors.reset}...`);
43
44
  let htmlContent = null;
@@ -5,6 +5,7 @@ import { readMarkdownFile } from "../assets.js";
5
5
  import { stxClientHelpers } from "../client-helpers.js";
6
6
  import { config } from "../config.js";
7
7
  import { partialsCache } from "../includes.js";
8
+ import { stateDir } from "../state-dir.js";
8
9
  import { plugin as stxPlugin } from "../plugin.js";
9
10
  import { clearComponentCache } from "../utils.js";
10
11
  import {
@@ -45,7 +46,7 @@ export async function serveMultipleStxFiles(filePaths, options = {}) {
45
46
  return !1;
46
47
  }
47
48
  }
48
- const outputDir = path.join(process.cwd(), ".stx/output");
49
+ const outputDir = stateDir(process.cwd(), "output");
49
50
  fs.mkdirSync(outputDir, { recursive: !0 });
50
51
  const commonDir = findCommonDir(filePaths.map((f) => path.dirname(path.resolve(f))));
51
52
  console.log(`${colors.blue}Processing ${colors.bright}${filePaths.length}${colors.reset} files...`);
package/dist/index.d.ts CHANGED
@@ -107,6 +107,8 @@ export * from './scaffolding';
107
107
  export * from './script-classifier';
108
108
  export * from './seo';
109
109
  export * from './serve';
110
+ // Where stx keeps its generated state (`.stx/` by default, configurable)
111
+ export * from './state-dir';
110
112
  export * from './style-scoping';
111
113
  export * from './template-compiler';
112
114
  export * from './template-hydrator';
package/dist/index.js CHANGED
@@ -63,6 +63,7 @@ export * from "./scaffolding.js";
63
63
  export * from "./script-classifier.js";
64
64
  export * from "./seo.js";
65
65
  export * from "./serve.js";
66
+ export * from "./state-dir.js";
66
67
  export * from "./style-scoping.js";
67
68
  export * from "./template-compiler.js";
68
69
  export * from "./template-hydrator.js";