@taujs/server 0.5.0 → 0.5.2

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/index.js +83 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -143,6 +143,7 @@ var REGEX = {
143
143
  BENIGN_NET_ERR: /\b(?:ECONNRESET|EPIPE|ECONNABORTED)\b|socket hang up|aborted|premature(?: close)?/i,
144
144
  SAFE_TRACE: /^[a-zA-Z0-9-_:.]{1,128}$/
145
145
  };
146
+ var ENTRY_EXTENSIONS = [".ts", ".tsx"];
146
147
 
147
148
  // src/Setup.ts
148
149
  var extractBuildConfigs = (config) => {
@@ -256,6 +257,11 @@ function printContractReport(logger, report) {
256
257
  var computeScore = (path7) => {
257
258
  return path7.split("/").filter(Boolean).reduce((score, segment) => score + (segment.startsWith(":") ? 1 : 10), 0);
258
259
  };
260
+ function printVitePluginSummary(logger, appPlugins, merged) {
261
+ const mergedNames = merged.map((p) => p?.name).filter((n) => typeof n === "string" && n.length > 0);
262
+ const appsLine = appPlugins.length === 0 ? "no app plugins" : appPlugins.map((a) => `${a.appId}=[${a.plugins.join(", ") || "none"}]`).join(" ");
263
+ logger.info(void 0, `${CONTENT.TAG} [vite] Plugins ${appsLine} merged=[${mergedNames.join(", ") || "none"}]`);
264
+ }
259
265
 
260
266
  // src/logging/AppError.ts
261
267
  var HTTP_STATUS = {
@@ -1226,6 +1232,7 @@ var cspReportPlugin = fp2(
1226
1232
  );
1227
1233
 
1228
1234
  // src/utils/AssetManager.ts
1235
+ import { existsSync } from "fs";
1229
1236
  import { readFile } from "fs/promises";
1230
1237
  import path2 from "path";
1231
1238
  import { pathToFileURL } from "url";
@@ -1337,6 +1344,14 @@ var rebuildTemplate = (parts, headContent, bodyContent) => {
1337
1344
  };
1338
1345
 
1339
1346
  // src/utils/AssetManager.ts
1347
+ function resolveEntryFile(clientRoot, stem) {
1348
+ for (const ext of ENTRY_EXTENSIONS) {
1349
+ const filename = `${stem}${ext}`;
1350
+ const absPath = path2.join(clientRoot, filename);
1351
+ if (existsSync(absPath)) return filename;
1352
+ }
1353
+ throw new Error(`Entry file "${stem}" not found in ${clientRoot}. Tried: ${ENTRY_EXTENSIONS.map((e) => stem + e).join(", ")}`);
1354
+ }
1340
1355
  var createMaps = () => ({
1341
1356
  bootstrapModules: /* @__PURE__ */ new Map(),
1342
1357
  cssLinks: /* @__PURE__ */ new Map(),
@@ -1349,13 +1364,20 @@ var createMaps = () => ({
1349
1364
  var processConfigs = (configs, baseClientRoot, templateDefaults) => {
1350
1365
  return configs.map((config) => {
1351
1366
  const clientRoot = path2.resolve(baseClientRoot, config.entryPoint);
1367
+ const entryClient = config.entryClient || templateDefaults.defaultEntryClient;
1368
+ const entryServer = config.entryServer || templateDefaults.defaultEntryServer;
1369
+ const entryClientFile = resolveEntryFile(clientRoot, entryClient);
1370
+ const entryServerFile = resolveEntryFile(clientRoot, entryServer);
1352
1371
  return {
1353
1372
  clientRoot,
1354
1373
  entryPoint: config.entryPoint,
1355
- entryClient: config.entryClient || templateDefaults.defaultEntryClient,
1356
- entryServer: config.entryServer || templateDefaults.defaultEntryServer,
1374
+ entryClient,
1375
+ entryServer,
1357
1376
  htmlTemplate: config.htmlTemplate || templateDefaults.defaultHtmlTemplate,
1358
- appId: config.appId
1377
+ appId: config.appId,
1378
+ plugins: config.plugins ?? [],
1379
+ entryClientFile,
1380
+ entryServerFile
1359
1381
  };
1360
1382
  });
1361
1383
  };
@@ -1365,7 +1387,7 @@ var loadAssets = async (processedConfigs, baseClientRoot, bootstrapModules, cssL
1365
1387
  includeContext: true
1366
1388
  });
1367
1389
  for (const config of processedConfigs) {
1368
- const { clientRoot, entryClient, entryServer, htmlTemplate, entryPoint } = config;
1390
+ const { clientRoot, entryClient, entryServer, htmlTemplate, entryPoint, entryClientFile, entryServerFile } = config;
1369
1391
  try {
1370
1392
  const templateHtmlPath = path2.join(clientRoot, htmlTemplate);
1371
1393
  const templateHtml = await readFile(templateHtmlPath, "utf-8");
@@ -1386,17 +1408,17 @@ var loadAssets = async (processedConfigs, baseClientRoot, bootstrapModules, cssL
1386
1408
  const ssrManifestContent = await readFile(ssrManifestPath, "utf-8");
1387
1409
  const ssrManifest = JSON.parse(ssrManifestContent);
1388
1410
  ssrManifests.set(clientRoot, ssrManifest);
1389
- const entryClientFile = manifest[`${entryClient}.tsx`]?.file;
1390
- if (!entryClientFile) {
1391
- throw AppError.internal(`Entry client file not found in manifest for ${entryClient}.tsx`, {
1411
+ const manifestEntry = manifest[entryClientFile];
1412
+ if (!manifestEntry?.file) {
1413
+ throw AppError.internal(`Entry client file not found in manifest for ${entryClientFile}`, {
1392
1414
  details: {
1393
1415
  clientRoot,
1394
- entryClient,
1416
+ entryClientFile,
1395
1417
  availableKeys: Object.keys(manifest)
1396
1418
  }
1397
1419
  });
1398
1420
  }
1399
- const bootstrapModule = `/${adjustedRelativePath}/${entryClientFile}`.replace(/\/{2,}/g, "/");
1421
+ const bootstrapModule = `/${adjustedRelativePath}/${manifestEntry.file}`.replace(/\/{2,}/g, "/");
1400
1422
  bootstrapModules.set(clientRoot, bootstrapModule);
1401
1423
  const preloadLink = renderPreloadLinks(ssrManifest, adjustedRelativePath);
1402
1424
  preloadLinks.set(clientRoot, preloadLink);
@@ -1433,7 +1455,7 @@ var loadAssets = async (processedConfigs, baseClientRoot, bootstrapModules, cssL
1433
1455
  }
1434
1456
  }
1435
1457
  } else {
1436
- const bootstrapModule = `/${adjustedRelativePath}/${entryClient}`.replace(/\/{2,}/g, "/");
1458
+ const bootstrapModule = `/${adjustedRelativePath}/${entryClientFile}`.replace(/\/{2,}/g, "/");
1437
1459
  bootstrapModules.set(clientRoot, bootstrapModule);
1438
1460
  }
1439
1461
  } catch (err) {
@@ -1450,7 +1472,7 @@ var loadAssets = async (processedConfigs, baseClientRoot, bootstrapModules, cssL
1450
1472
 
1451
1473
  // src/utils/DevServer.ts
1452
1474
  import path3 from "path";
1453
- var setupDevServer = async (app, baseClientRoot, alias, debug, devNet) => {
1475
+ var setupDevServer = async (app, baseClientRoot, alias, debug, devNet, plugins = []) => {
1454
1476
  const logger = createLogger({
1455
1477
  context: { service: "setupDevServer" },
1456
1478
  debug,
@@ -1470,6 +1492,7 @@ var setupDevServer = async (app, baseClientRoot, alias, debug, devNet) => {
1470
1492
  },
1471
1493
  mode: "development",
1472
1494
  plugins: [
1495
+ ...plugins,
1473
1496
  ...debug ? [
1474
1497
  {
1475
1498
  name: "\u03C4js-development-server-debug-logging",
@@ -1592,7 +1615,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1592
1615
  }
1593
1616
  });
1594
1617
  }
1595
- const { clientRoot, entryServer } = config;
1618
+ const { clientRoot, entryServerFile } = config;
1596
1619
  let template = ensureNonNull(maps.templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
1597
1620
  const bootstrapModule = maps.bootstrapModules.get(clientRoot);
1598
1621
  const cssLink = maps.cssLinks.get(clientRoot);
@@ -1604,7 +1627,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1604
1627
  try {
1605
1628
  template = template.replace(/<script type="module" src="\/@vite\/client"><\/script>/g, "");
1606
1629
  template = template.replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
1607
- const entryServerPath = path4.join(clientRoot, `${entryServer}.tsx`);
1630
+ const entryServerPath = path4.join(clientRoot, entryServerFile);
1608
1631
  const executedModule = await viteDevServer.ssrLoadModule(entryServerPath);
1609
1632
  renderModule = executedModule;
1610
1633
  const styles = await collectStyle(viteDevServer, [entryServerPath]);
@@ -1612,7 +1635,7 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1612
1635
  template = template?.replace("</head>", `<style type="text/css"${styleNonce}>${styles}</style></head>`);
1613
1636
  template = await viteDevServer.transformIndexHtml(url, template);
1614
1637
  } catch (error) {
1615
- throw AppError.internal("Failed to load dev assets", { cause: error, details: { clientRoot, entryServer, url } });
1638
+ throw AppError.internal("Failed to load dev assets", { cause: error, details: { clientRoot, entryServerFile, url } });
1616
1639
  }
1617
1640
  } else {
1618
1641
  renderModule = maps.renderModules.get(clientRoot);
@@ -1746,8 +1769,8 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1746
1769
  reply.raw.on("error", (err) => {
1747
1770
  if (!isBenignSocketAbort(err)) logger.error({ error: err }, "HTTP socket error:");
1748
1771
  });
1749
- writable.pipe(reply.raw, { end: false });
1750
1772
  let finalData = void 0;
1773
+ let pipedToReply = false;
1751
1774
  renderStream(
1752
1775
  writable,
1753
1776
  {
@@ -1755,7 +1778,11 @@ var handleRender = async (req, reply, routeMatchers, processedConfigs, serviceRe
1755
1778
  let aggregateHeadContent = headContent;
1756
1779
  if (ssrManifest && preloadLink) aggregateHeadContent += preloadLink;
1757
1780
  if (manifest && cssLink) aggregateHeadContent += cssLink;
1758
- return reply.raw.write(`${templateParts.beforeHead}${aggregateHeadContent}${templateParts.afterHead}${templateParts.beforeBody}`);
1781
+ reply.raw.write(`${templateParts.beforeHead}${aggregateHeadContent}${templateParts.afterHead}${templateParts.beforeBody}`);
1782
+ if (!pipedToReply) {
1783
+ pipedToReply = true;
1784
+ writable.pipe(reply.raw, { end: false });
1785
+ }
1759
1786
  },
1760
1787
  onShellReady: () => {
1761
1788
  },
@@ -1928,6 +1955,26 @@ async function registerStaticAssets(app, clientRoot, reg, defaults) {
1928
1955
  }
1929
1956
  }
1930
1957
 
1958
+ // src/utils/VitePlugins.ts
1959
+ function flattenPlugins(input) {
1960
+ if (!input) return [];
1961
+ if (Array.isArray(input)) return input.flatMap(flattenPlugins);
1962
+ return [input];
1963
+ }
1964
+ function mergePlugins(opts) {
1965
+ const internal = flattenPlugins(opts.internal);
1966
+ const apps = (opts.apps ?? []).flatMap((a) => flattenPlugins(a.plugins));
1967
+ const merged = [...internal, ...apps];
1968
+ const seen = /* @__PURE__ */ new Set();
1969
+ return merged.filter((p) => {
1970
+ const name = typeof p?.name === "string" ? p.name : "";
1971
+ if (!name) return true;
1972
+ if (seen.has(name)) return false;
1973
+ seen.add(name);
1974
+ return true;
1975
+ });
1976
+ }
1977
+
1931
1978
  // src/SSRServer.ts
1932
1979
  var SSRServer = fp3(
1933
1980
  async (app, opts) => {
@@ -1977,7 +2024,21 @@ var SSRServer = fp3(
1977
2024
  routeMatchers,
1978
2025
  debug: opts.debug
1979
2026
  });
1980
- if (isDevelopment) viteDevServer = await setupDevServer(app, clientRoot, alias, opts.debug, opts.devNet);
2027
+ if (isDevelopment) {
2028
+ const plugins = mergePlugins({
2029
+ internal: [],
2030
+ apps: processedConfigs
2031
+ });
2032
+ printVitePluginSummary(
2033
+ logger,
2034
+ processedConfigs.map((c) => ({
2035
+ appId: c.appId,
2036
+ plugins: (c.plugins ?? []).map((p) => Array.isArray(p) ? `array(${p.length})` : p?.name ?? typeof p)
2037
+ })),
2038
+ plugins
2039
+ );
2040
+ viteDevServer = await setupDevServer(app, clientRoot, alias, opts.debug, opts.devNet, plugins);
2041
+ }
1981
2042
  app.addHook("onRequest", createAuthHook(routeMatchers, logger));
1982
2043
  app.get("/__taujs/data", async (req, reply) => {
1983
2044
  const query = req.query;
@@ -2126,7 +2187,7 @@ ${import_picocolors4.default.bgGreen(import_picocolors4.default.black(` ${CONTEN
2126
2187
  };
2127
2188
 
2128
2189
  // src/Build.ts
2129
- import { existsSync } from "fs";
2190
+ import { existsSync as existsSync2 } from "fs";
2130
2191
  import path6 from "path";
2131
2192
  import { build } from "vite";
2132
2193
  function resolveInputs(isSSRBuild, mainExists, paths) {
@@ -2319,7 +2380,7 @@ async function taujsBuild({
2319
2380
  }
2320
2381
  if (!isSSRBuild) await deleteDist();
2321
2382
  for (const appConfig of configsToBuild) {
2322
- const { appId, entryPoint, clientRoot, entryClient, entryServer, htmlTemplate, plugins = [] } = appConfig;
2383
+ const { appId, entryPoint, clientRoot, entryClientFile, entryServerFile, htmlTemplate, plugins = [] } = appConfig;
2323
2384
  const outDir = path6.resolve(projectRoot, isSSRBuild ? `dist/ssr/${entryPoint}` : `dist/client/${entryPoint}`);
2324
2385
  const root = entryPoint ? path6.resolve(clientBaseDir, entryPoint) : clientBaseDir;
2325
2386
  const defaultAlias = {
@@ -2328,10 +2389,10 @@ async function taujsBuild({
2328
2389
  "@shared": path6.resolve(projectRoot, "src/shared")
2329
2390
  };
2330
2391
  const resolvedAlias = { ...defaultAlias, ...userAlias ?? {} };
2331
- const server = path6.resolve(clientRoot, `${entryServer}.tsx`);
2332
- const client = path6.resolve(clientRoot, `${entryClient}.tsx`);
2392
+ const server = path6.resolve(clientRoot, entryServerFile);
2393
+ const client = path6.resolve(clientRoot, entryClientFile);
2333
2394
  const main = path6.resolve(clientRoot, htmlTemplate);
2334
- const inputs = resolveInputs(isSSRBuild, !isSSRBuild && existsSync(main), { server, client, main });
2395
+ const inputs = resolveInputs(isSSRBuild, !isSSRBuild && existsSync2(main), { server, client, main });
2335
2396
  const nodeVersion = process.versions.node.split(".")[0];
2336
2397
  const frameworkConfig = {
2337
2398
  base: entryPoint ? `/${entryPoint}/` : "/",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taujs/server",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "τjs [ taujs ]",
5
5
  "author": "John Smith | Aoede <taujs@aoede.uk.net> (https://www.aoede.uk.net)",
6
6
  "license": "MIT",