@vesk/vesk-cli 0.2.50-canary.2 → 0.2.50-canary.3

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.
Files changed (2) hide show
  1. package/dist/cli.js +113 -50
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -32504,7 +32504,7 @@ async function renderFullPage(source, componentName, props = {}, registry = /* @
32504
32504
  const cssUrls = options.cssUrls || (options.cssUrl ? [options.cssUrl] : []);
32505
32505
  const cssLink = cssUrls.map((u) => ` <link rel="stylesheet" href="${u}" />
32506
32506
  `).join("");
32507
- const clientScript = options.clientScriptUrl ? ` <script type="module" src="${options.clientScriptUrl}"></script>
32507
+ const clientScript = options.clientScriptUrl ? ` <script type="module" src="${options.clientScriptUrl}"${options.clientScriptIntegrity ? ` integrity="${options.clientScriptIntegrity}" crossorigin="anonymous"` : ""}></script>
32508
32508
  ` : "";
32509
32509
  const dataScripts = buildDataScripts(ssrProps, ssrData, options.externalDataScript);
32510
32510
  const dataScriptBlock = dataScripts.length > 0 ? "\n" + dataScripts.join("\n") + "\n" : "";
@@ -32640,7 +32640,7 @@ function renderPageStream(source, componentName, props = {}, registry = /* @__PU
32640
32640
  pruneSsrDataSlots();
32641
32641
  const dataScripts = buildDataScripts(ssrProps, ssrData, options.externalDataScript);
32642
32642
  const dataScriptBlock = dataScripts.length > 0 ? "\n" + dataScripts.join("\n") : "";
32643
- const clientScript = options.clientScriptUrl ? ` <script type="module" src="${options.clientScriptUrl}"></script>
32643
+ const clientScript = options.clientScriptUrl ? ` <script type="module" src="${options.clientScriptUrl}"${options.clientScriptIntegrity ? ` integrity="${options.clientScriptIntegrity}" crossorigin="anonymous"` : ""}></script>
32644
32644
  ` : "";
32645
32645
  yield `
32646
32646
  </div>${dataScriptBlock}${clientScript}</body>
@@ -32745,7 +32745,7 @@ import {
32745
32745
  mkdirSync as mkdirSync6,
32746
32746
  statSync as statSync7
32747
32747
  } from "node:fs";
32748
- import { resolve as resolve14, dirname as dirname11, join as join10, extname as extname4, basename } from "node:path";
32748
+ import { resolve as resolve14, dirname as dirname11, join as join10, extname as extname4, basename as basename2 } from "node:path";
32749
32749
  import { createRequire as createRequire4 } from "node:module";
32750
32750
  import { spawn } from "node:child_process";
32751
32751
  function defaultState() {
@@ -32803,7 +32803,7 @@ function resolvePackage(appDir, pkg) {
32803
32803
  break;
32804
32804
  }
32805
32805
  const parent = dirname11(cur);
32806
- if (parent !== cur && basename(cur) === "node_modules") break;
32806
+ if (parent !== cur && basename2(cur) === "node_modules") break;
32807
32807
  cur = parent;
32808
32808
  }
32809
32809
  } catch {
@@ -46255,7 +46255,7 @@ function setRuntimeModule2(mod) {
46255
46255
 
46256
46256
  // ../adapter/dist/index.js
46257
46257
  import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync12, existsSync as existsSync22, readFileSync as readFileSync21 } from "node:fs";
46258
- import { resolve as resolve21, dirname as dirname16, relative as relative4, basename as basename2 } from "node:path";
46258
+ import { resolve as resolve21, dirname as dirname16, relative as relative4, basename as basename3 } from "node:path";
46259
46259
  import { fileURLToPath as fileURLToPath5 } from "node:url";
46260
46260
 
46261
46261
  // ../adapter/src/runtime-bundle.ts
@@ -46738,7 +46738,7 @@ ${layoutDecls.map((d) => " " + d.compiled + ",").join("\n")}
46738
46738
  return { ${paramExprs.join(", ")} };
46739
46739
  }
46740
46740
  `;
46741
- const clientScriptOption = ', clientScriptUrl: "/_vesk/static/client.js"';
46741
+ const clientScriptOption = `, clientScriptUrl: ${JSON.stringify(options?.clientScriptUrl || "/_vesk/static/client.js")}` + (options?.clientScriptIntegrity ? `, clientScriptIntegrity: ${JSON.stringify(options.clientScriptIntegrity)}` : "");
46742
46742
  const dataScriptOption = ", externalDataScript: storeDataScriptGlobal";
46743
46743
  let registryCode = "";
46744
46744
  const compRegEntries = [];
@@ -47288,6 +47288,43 @@ function generateApiFunction(apiNode, _apiDir, outDir, options) {
47288
47288
  return { funcPath, funcCode, name };
47289
47289
  }
47290
47290
 
47291
+ // ../adapter/src/asset-hash.ts
47292
+ import { createHash } from "node:crypto";
47293
+ var EXT_RE = /\.([a-z0-9]+)$/i;
47294
+ function hashedName(fileName, content) {
47295
+ const m = EXT_RE.exec(fileName);
47296
+ if (!m) return fileName;
47297
+ const base = fileName.slice(0, m.index);
47298
+ return `${base}.${hashOf(content)}${m[0]}`;
47299
+ }
47300
+ function hashOf(content) {
47301
+ return createHash("sha256").update(content).digest("hex").slice(0, 10);
47302
+ }
47303
+ function integrityOf(content) {
47304
+ return `sha384-${createHash("sha384").update(content).digest("base64")}`;
47305
+ }
47306
+ function describeAsset(fileName, content) {
47307
+ return {
47308
+ fileName: hashedName(fileName, content),
47309
+ hash: hashOf(content),
47310
+ bytes: typeof content === "string" ? Buffer.byteLength(content) : content.length,
47311
+ integrity: integrityOf(content)
47312
+ };
47313
+ }
47314
+ function isHashedName(fileName) {
47315
+ const m = EXT_RE.exec(fileName);
47316
+ if (!m) return false;
47317
+ const base = fileName.slice(0, m.index);
47318
+ const dot = base.lastIndexOf(".");
47319
+ if (dot === -1) return false;
47320
+ const suffix = base.slice(dot + 1);
47321
+ return suffix.length === 10 && /^[0-9a-f]{10}$/.test(suffix);
47322
+ }
47323
+ function cacheControlFor(fileName, isDev) {
47324
+ if (isDev) return "no-cache";
47325
+ return isHashedName(fileName) ? "public, max-age=31536000, immutable" : "public, max-age=0, must-revalidate";
47326
+ }
47327
+
47291
47328
  // ../adapter/src/middleware.ts
47292
47329
  import { readFileSync as readFileSync10 } from "node:fs";
47293
47330
 
@@ -47591,14 +47628,14 @@ async function compileEvents(appDir, outDir) {
47591
47628
 
47592
47629
  // ../adapter/src/client-bundle.ts
47593
47630
  init_esbuild_fallback();
47594
- init_strip_ts();
47595
- init_parser();
47596
- init_client_codegen();
47597
- init_vsk_collision();
47598
47631
  import { readFileSync as readFileSync11, existsSync as existsSync11, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, statSync as statSync3, rmSync, mkdtempSync, mkdirSync as mkdirSync3 } from "node:fs";
47599
47632
  import { resolve as resolve10, join as join7, dirname as dirname8, relative as relative2, sep } from "node:path";
47600
47633
  import { fileURLToPath as fileURLToPath2 } from "node:url";
47601
47634
  import { tmpdir } from "node:os";
47635
+ init_strip_ts();
47636
+ init_parser();
47637
+ init_client_codegen();
47638
+ init_vsk_collision();
47602
47639
  init_vsk_imports();
47603
47640
  init_md_inline();
47604
47641
  init_module_imports();
@@ -48184,8 +48221,11 @@ async function generateClientBundle(routeTree, appDir, componentMap, options) {
48184
48221
  }, annotate2 = function(nodes) {
48185
48222
  for (const node of nodes) {
48186
48223
  const chunkName = `page-${buildChunkName(node)}.js`;
48187
- const hasEntry = chunkEntries.some((e) => e.name === chunkName && e.code.trim());
48188
- if (hasEntry) node.chunk = `/_vesk/static/${chunkName}`;
48224
+ const emitted = chunks.find((c) => c.name === chunkName && c.code.trim());
48225
+ if (emitted) {
48226
+ const fileName = options?.hmr ? chunkName : hashedName(chunkName, emitted.code);
48227
+ node.chunk = `/_vesk/static/${fileName}`;
48228
+ }
48189
48229
  annotate2(node.children || []);
48190
48230
  }
48191
48231
  };
@@ -48624,7 +48664,7 @@ function copyStaticAssets(publicDir, outDir) {
48624
48664
 
48625
48665
  // ../adapter/src/prod-server.ts
48626
48666
  import { readFileSync as readFileSync15, existsSync as existsSync15, statSync as statSync6 } from "node:fs";
48627
- import { resolve as resolve13, extname as extname3, dirname as dirname10 } from "node:path";
48667
+ import { resolve as resolve13, extname as extname3, dirname as dirname10, basename } from "node:path";
48628
48668
  import { createServer } from "node:http";
48629
48669
  import { fileURLToPath as fileURLToPath3 } from "node:url";
48630
48670
  init_server_utils();
@@ -48935,9 +48975,13 @@ async function startProdServer(outDir, options) {
48935
48975
  return;
48936
48976
  }
48937
48977
  if (url.pathname === "/_vesk/runtime.js") {
48938
- const clientPath = resolve13(staticDir, "client.js");
48978
+ const clientFile = buildConfig?.assets?.client?.file || "client.js";
48979
+ const clientPath = resolve13(staticDir, clientFile);
48939
48980
  if (existsSync15(clientPath)) {
48940
- res.writeHead(200, { "Content-Type": "application/javascript" });
48981
+ res.writeHead(200, {
48982
+ "Content-Type": "application/javascript",
48983
+ "Cache-Control": cacheControlFor(clientFile, false)
48984
+ });
48941
48985
  res.end(readFileSync15(clientPath));
48942
48986
  return;
48943
48987
  }
@@ -48952,7 +48996,13 @@ async function startProdServer(outDir, options) {
48952
48996
  }
48953
48997
  if (existsSync15(staticPath) && statSync6(staticPath).isFile()) {
48954
48998
  const ext = extname3(staticPath);
48955
- res.writeHead(200, { "Content-Type": MIME[ext] || "application/octet-stream" });
48999
+ res.writeHead(200, {
49000
+ "Content-Type": MIME[ext] || "application/octet-stream",
49001
+ // A content-hashed name can never change meaning, so it is immutable
49002
+ // for a year; anything unhashed must be revalidated or a deploy would
49003
+ // serve stale JS forever.
49004
+ "Cache-Control": cacheControlFor(basename(staticPath), false)
49005
+ });
48956
49006
  res.end(readFileSync15(staticPath));
48957
49007
  return;
48958
49008
  }
@@ -49150,7 +49200,7 @@ async function startProdServer(outDir, options) {
49150
49200
  const src2 = readFileSync15(errPath, "utf-8");
49151
49201
  const compName = resolveComponentName(src2) || "Error";
49152
49202
  const expose = process.env.NODE_ENV !== "production";
49153
- errorHtml = await renderFullPage2(src2, compName, { error: expose ? err.message : "Internal Server Error", stack: expose ? err.stack : "", statusCode: 500, url: url.pathname }, /* @__PURE__ */ new Map(), { hydrate: true, cssUrls: pageCssUrls, clientScriptUrl: "/_vesk/static/client.js", security: securityConfig?.security || {}, externalDataScript: storeDataScriptGlobal, sourcePath: errPath, headExtra: bakedHeadExtra });
49203
+ errorHtml = await renderFullPage2(src2, compName, { error: expose ? err.message : "Internal Server Error", stack: expose ? err.stack : "", statusCode: 500, url: url.pathname }, /* @__PURE__ */ new Map(), { hydrate: true, cssUrls: pageCssUrls, clientScriptUrl: buildConfig?.assets?.client?.url || "/_vesk/static/client.js", clientScriptIntegrity: buildConfig?.assets?.client?.integrity, security: securityConfig?.security || {}, externalDataScript: storeDataScriptGlobal, sourcePath: errPath, headExtra: bakedHeadExtra });
49154
49204
  } catch {
49155
49205
  }
49156
49206
  }
@@ -49231,7 +49281,7 @@ function filterPluginsForBuild(plugins, state) {
49231
49281
  return filterActivePlugins2(plugins, state.plugins);
49232
49282
  }
49233
49283
  function veskDirFromOutDir(outDir) {
49234
- const base = basename2(outDir);
49284
+ const base = basename3(outDir);
49235
49285
  if (base === "dev" || base === "build")
49236
49286
  return dirname16(outDir);
49237
49287
  return outDir;
@@ -49360,6 +49410,34 @@ async function build2(appDir, options) {
49360
49410
  const apiTree = existsSync22(apiDir) ? scanApiRoutes2(apiDir) : [];
49361
49411
  console.error(`vesk build: ${routeTree.length} root routes, ${apiTree.length} API routes`);
49362
49412
  markPhase("scan routes");
49413
+ console.error("vesk build: bundling client runtime...");
49414
+ const bundleOpts = {};
49415
+ if (options?.codeSplit)
49416
+ bundleOpts.codeSplit = true;
49417
+ if (options?.hmr)
49418
+ bundleOpts.hmr = true;
49419
+ if (options?.routeDataCache !== void 0)
49420
+ bundleOpts.routeDataCache = options.routeDataCache;
49421
+ if (pluginsPipelines.length > 0)
49422
+ bundleOpts.plugins = pluginsPipelines;
49423
+ const { main, chunks } = await generateClientBundle(routeTree, appDir, componentMap, bundleOpts);
49424
+ markPhase("client runtime + chunks");
49425
+ const staticDir = resolve21(outDir, "static");
49426
+ const hashed = !options?.hmr;
49427
+ const clientAsset = describeAsset("client.js", main);
49428
+ const clientFileName = hashed ? clientAsset.fileName : "client.js";
49429
+ writeFileSync12(resolve21(staticDir, clientFileName), main, "utf-8");
49430
+ const clientUrl = `/_vesk/static/${clientFileName}`;
49431
+ const mode = chunks.length > 0 ? "code-split" : "monolithic";
49432
+ console.error(`vesk build: client \u2192 static/${clientFileName} (${main.length} bytes, ${mode}${hashed ? `, ${clientAsset.hash}` : ""})`);
49433
+ const emittedAssets = [clientAsset];
49434
+ for (const chunk of chunks) {
49435
+ const asset = describeAsset(chunk.name, chunk.code);
49436
+ emittedAssets.push(asset);
49437
+ writeFileSync12(resolve21(staticDir, hashed ? asset.fileName : chunk.name), chunk.code, "utf-8");
49438
+ console.error(`vesk build: chunk \u2192 static/${hashed ? asset.fileName : chunk.name} (${chunk.code.length} bytes${hashed ? `, ${asset.hash}` : ""})`);
49439
+ }
49440
+ const clientIntegrity = hashed ? clientAsset.integrity : void 0;
49363
49441
  console.error("vesk build: bundling server runtime...");
49364
49442
  await bundleRuntime(appDir, outDir);
49365
49443
  const ssrRoutes = [];
@@ -49379,7 +49457,7 @@ async function build2(appDir, options) {
49379
49457
  mwCode = compileMiddlewareCode(mwSources);
49380
49458
  }
49381
49459
  const ssrAncestorLayouts = isStandalone ? [] : ancestorLayouts;
49382
- const { funcPath, funcCode, name } = generateSsrFunction(node, appDir, outDir, componentMap, { ancestorLayouts: ssrAncestorLayouts, middlewareCode: mwCode, headExtra: pluginHeadExtra });
49460
+ const { funcPath, funcCode, name } = generateSsrFunction(node, appDir, outDir, componentMap, { ancestorLayouts: ssrAncestorLayouts, middlewareCode: mwCode, headExtra: pluginHeadExtra, clientScriptUrl: clientUrl, clientScriptIntegrity: clientIntegrity });
49383
49461
  writeFileSync12(funcPath, funcCode, "utf-8");
49384
49462
  const pagePath = resolve21(appDir, node.sourceDir, "page.vsk");
49385
49463
  if (existsSync22(pagePath)) {
@@ -49439,28 +49517,6 @@ async function build2(appDir, options) {
49439
49517
  const hasEvents = await compileEvents(appDir, outDir);
49440
49518
  if (hasEvents)
49441
49519
  console.error("vesk build: evt \u2192 server/events.js (onStart/onRequest/onStop)");
49442
- markPhase("api functions");
49443
- console.error("vesk build: bundling client runtime...");
49444
- const bundleOpts = {};
49445
- if (options?.codeSplit)
49446
- bundleOpts.codeSplit = true;
49447
- if (options?.hmr)
49448
- bundleOpts.hmr = true;
49449
- if (options?.routeDataCache !== void 0)
49450
- bundleOpts.routeDataCache = options.routeDataCache;
49451
- if (pluginsPipelines.length > 0)
49452
- bundleOpts.plugins = pluginsPipelines;
49453
- const { main, chunks } = await generateClientBundle(routeTree, appDir, componentMap, bundleOpts);
49454
- writeFileSync12(resolve21(outDir, "static", "client.js"), main, "utf-8");
49455
- const mode = chunks.length > 0 ? "code-split" : "monolithic";
49456
- console.error(`vesk build: client \u2192 static/client.js (${main.length} bytes, ${mode})`);
49457
- if (chunks.length > 0) {
49458
- const staticDir = resolve21(outDir, "static");
49459
- for (const chunk of chunks) {
49460
- writeFileSync12(resolve21(staticDir, chunk.name), chunk.code, "utf-8");
49461
- console.error(`vesk build: chunk \u2192 static/${chunk.name} (${chunk.code.length} bytes)`);
49462
- }
49463
- }
49464
49520
  copyStaticAssets(publicDir, outDir);
49465
49521
  markPhase("client runtime + chunks");
49466
49522
  console.error("vesk build: static \u2192 static/public/");
@@ -49503,6 +49559,11 @@ async function build2(appDir, options) {
49503
49559
  }
49504
49560
  markPhase("ssg+images+seo");
49505
49561
  const manifest = generateManifest(routeTree, ssrRoutes, apiRoutes, prerenderedRoutes, middlewareEnabled, actionMap, pluginHeadExtra, hasEvents);
49562
+ manifest.assets = {
49563
+ hashed,
49564
+ client: { file: clientFileName, url: clientUrl, hash: clientAsset.hash, bytes: clientAsset.bytes, integrity: clientAsset.integrity },
49565
+ chunks: emittedAssets.slice(1).map((a) => ({ file: a.fileName, hash: a.hash, bytes: a.bytes, integrity: a.integrity }))
49566
+ };
49506
49567
  writeFileSync12(resolve21(outDir, "config.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
49507
49568
  console.error("vesk build: config \u2192 config.json");
49508
49569
  {
@@ -52202,7 +52263,7 @@ init_tokens();
52202
52263
  init_scan();
52203
52264
  init_strip_ts();
52204
52265
  import { readdirSync as readdirSync7, statSync as statSync12, existsSync as existsSync23, readFileSync as readFileSync22 } from "fs";
52205
- import { join as join15, relative as relative5, basename as basename3 } from "path";
52266
+ import { join as join15, relative as relative5, basename as basename4 } from "path";
52206
52267
  function collapseSlashes2(p) {
52207
52268
  let out = "";
52208
52269
  let prevSlash = false;
@@ -52386,7 +52447,7 @@ function scanDirectory(rootDir, dir, parentPath, options) {
52386
52447
  continue;
52387
52448
  }
52388
52449
  }
52389
- let segName = basename3(dir);
52450
+ let segName = basename4(dir);
52390
52451
  let isGroup = segName.startsWith("(") && segName.endsWith(")");
52391
52452
  let isDynamic = segName.startsWith("[") && segName.endsWith("]") && !segName.startsWith("[...");
52392
52453
  let isCatchAll = segName.startsWith("[...") && segName.endsWith("]");
@@ -52595,7 +52656,7 @@ function matchUrl(tree, pathname) {
52595
52656
  import { readdirSync as readdirSync8, statSync as statSync13, existsSync as existsSync24 } from "fs";
52596
52657
  import { join as join16 } from "path";
52597
52658
  init_server_utils();
52598
- function basename4(p) {
52659
+ function basename5(p) {
52599
52660
  const idx = p.lastIndexOf("/");
52600
52661
  return idx === -1 ? p : p.slice(idx + 1);
52601
52662
  }
@@ -52621,7 +52682,7 @@ function scanApiDir(rootDir, dir, parentPath) {
52621
52682
  break;
52622
52683
  }
52623
52684
  }
52624
- const segName = basename4(dir);
52685
+ const segName = basename5(dir);
52625
52686
  const isDynamic = segName.startsWith("[") && segName.endsWith("]") && !segName.startsWith("[...");
52626
52687
  const isCatchAll = segName.startsWith("[...") && segName.endsWith("]");
52627
52688
  const isPrivate = segName.startsWith("_");
@@ -54036,9 +54097,11 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options) {
54036
54097
  }, annotate2 = function(nodes) {
54037
54098
  for (const node of nodes) {
54038
54099
  const chunkName = `page-${buildChunkName(node)}.js`;
54039
- const hasEntry = chunkEntries.some((e) => e.name === chunkName && e.code.trim());
54040
- if (hasEntry)
54041
- node.chunk = `/_vesk/static/${chunkName}`;
54100
+ const emitted = chunks.find((c) => c.name === chunkName && c.code.trim());
54101
+ if (emitted) {
54102
+ const fileName = options?.hmr ? chunkName : hashedName(chunkName, emitted.code);
54103
+ node.chunk = `/_vesk/static/${fileName}`;
54104
+ }
54042
54105
  annotate2(node.children || []);
54043
54106
  }
54044
54107
  };
@@ -54520,7 +54583,7 @@ import { resolve as resolve28 } from "node:path";
54520
54583
  // ../adapter/dist/plugins.js
54521
54584
  init_paths();
54522
54585
  import { readFileSync as readFileSync26, writeFileSync as writeFileSync14, existsSync as existsSync30, mkdirSync as mkdirSync13, statSync as statSync16 } from "node:fs";
54523
- import { resolve as resolve26, dirname as dirname19, join as join20, extname as extname7, basename as basename5 } from "node:path";
54586
+ import { resolve as resolve26, dirname as dirname19, join as join20, extname as extname7, basename as basename6 } from "node:path";
54524
54587
  import { createRequire as createRequire6 } from "node:module";
54525
54588
  import { spawn as spawn2 } from "node:child_process";
54526
54589
  var PLUGIN_STATE_FILENAME2 = "plugins.json";
@@ -54586,7 +54649,7 @@ function resolvePackage2(appDir, pkg) {
54586
54649
  break;
54587
54650
  }
54588
54651
  const parent = dirname19(cur);
54589
- if (parent !== cur && basename5(cur) === "node_modules")
54652
+ if (parent !== cur && basename6(cur) === "node_modules")
54590
54653
  break;
54591
54654
  cur = parent;
54592
54655
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/vesk-cli",
3
- "version": "0.2.50-canary.2",
3
+ "version": "0.2.50-canary.3",
4
4
  "type": "module",
5
5
  "description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
6
6
  "bin": {
@@ -8,10 +8,10 @@
8
8
  },
9
9
  "main": "./dist/cli.js",
10
10
  "dependencies": {
11
- "@vesk/adapter": "^0.2.50-canary.2",
12
- "@vesk/compiler": "^0.2.50-canary.2",
13
- "@vesk/plugin-tailwind": "^0.2.50-canary.2",
14
- "@vesk/runtime": "^0.2.50-canary.2",
11
+ "@vesk/adapter": "^0.2.50-canary.3",
12
+ "@vesk/compiler": "^0.2.50-canary.3",
13
+ "@vesk/plugin-tailwind": "^0.2.50-canary.3",
14
+ "@vesk/runtime": "^0.2.50-canary.3",
15
15
  "esrap": "^2.3.0",
16
16
  "typescript": "^5.8.0",
17
17
  "ws": "^8.18.0",