@jay-framework/dev-server 0.15.5 → 0.15.6

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 +72 -21
  2. package/package.json +14 -14
package/dist/index.js CHANGED
@@ -10,12 +10,12 @@ import { createRequire } from "module";
10
10
  import "@jay-framework/compiler-shared";
11
11
  import * as path from "node:path";
12
12
  import path__default from "node:path";
13
- import { JAY_IMPORT_RESOLVER, injectHeadfullFSTemplates, parseContract, slowRenderTransform, discoverHeadlessInstances, resolveHeadlessInstances } from "@jay-framework/compiler-jay-html";
13
+ import { JAY_IMPORT_RESOLVER, injectHeadfullFSTemplates, parseContract, slowRenderTransform, discoverHeadlessInstances, assignCoordinatesToJayHtml, resolveHeadlessInstances } from "@jay-framework/compiler-jay-html";
14
14
  import { getLogger, getDevLogger } from "@jay-framework/logger";
15
15
  import { createRequire as createRequire$1 } from "node:module";
16
16
  import * as fs from "node:fs";
17
17
  import { scanRoutes, routeToExpressRoute } from "@jay-framework/stack-route-scanner";
18
- import { discoverPluginsWithInit, sortPluginsByDependencies, executePluginServerInits, runInitCallbacks, actionRegistry, discoverAndRegisterActions, discoverAllPluginActions, runShutdownCallbacks, clearLifecycleCallbacks, clearServiceRegistry, clearClientInitData, DevSlowlyChangingPhase, SlowRenderCache, preparePluginClientInits, clearServerElementCache, getServiceRegistry, materializeContracts, loadPageParts, renderFastChangingData, generateClientScript, getClientInitData, generateSSRPageHtml, validateForEachInstances, slowRenderInstances } from "@jay-framework/stack-server-runtime";
18
+ import { discoverPluginsWithInit, sortPluginsByDependencies, executePluginServerInits, runInitCallbacks, actionRegistry, discoverAndRegisterActions, discoverAllPluginActions, runShutdownCallbacks, clearLifecycleCallbacks, clearServiceRegistry, clearClientInitData, DevSlowlyChangingPhase, SlowRenderCache, preparePluginClientInits, clearServerElementCache, getServiceRegistry, materializeContracts, loadPageParts, renderFastChangingData, mergeHeadTags, generateClientScript, getClientInitData, generateSSRPageHtml, validateForEachInstances, slowRenderInstances } from "@jay-framework/stack-server-runtime";
19
19
  import fs$1 from "node:fs/promises";
20
20
  import { pathToFileURL } from "node:url";
21
21
  const s$1 = createRequire(import.meta.url), e$1 = s$1("typescript"), c$1 = new Proxy(e$1, {
@@ -1200,7 +1200,7 @@ function createPluginClientImportResolver(options = {}) {
1200
1200
  const pluginDetector = options.pluginDetector || createDefaultPluginDetector();
1201
1201
  return {
1202
1202
  name: "jay-stack:plugin-client-import",
1203
- enforce: "pre",
1203
+ enforce: "post",
1204
1204
  configResolved(config) {
1205
1205
  projectRoot = config.root || projectRoot;
1206
1206
  isSSRBuild = !!config.build?.ssr;
@@ -1831,6 +1831,8 @@ function actionBodyParser() {
1831
1831
  });
1832
1832
  };
1833
1833
  }
1834
+ let _watchLinkedFiles = () => {
1835
+ };
1834
1836
  async function initRoutes(pagesBaseFolder) {
1835
1837
  return await scanRoutes(pagesBaseFolder, {
1836
1838
  jayHtmlFilename: "page.jay-html",
@@ -1854,7 +1856,9 @@ function defaults(options) {
1854
1856
  disableSSR: options.disableSSR,
1855
1857
  jayRollupConfig: {
1856
1858
  ...options.jayRollupConfig || {},
1857
- tsConfigFilePath
1859
+ tsConfigFilePath,
1860
+ pagesRoot: pagesRootFolder,
1861
+ buildFolder
1858
1862
  },
1859
1863
  httpServer: options.httpServer
1860
1864
  };
@@ -1994,7 +1998,14 @@ async function handleCachedRequest(vite, route, options, cachedEntry, pageParams
1994
1998
  timing?.end();
1995
1999
  return;
1996
2000
  }
1997
- const { parts: pageParts, clientTrackByMap, usedPackages } = pagePartsResult.val;
2001
+ const {
2002
+ parts: pageParts,
2003
+ clientTrackByMap,
2004
+ usedPackages,
2005
+ linkedCssFiles,
2006
+ linkedComponentFiles
2007
+ } = pagePartsResult.val;
2008
+ _watchLinkedFiles([...linkedCssFiles || [], ...linkedComponentFiles || []]);
1998
2009
  const pluginsForPage = filterPluginsForPage(
1999
2010
  allPluginClientInits,
2000
2011
  allPluginsWithInit,
@@ -2023,6 +2034,7 @@ async function handleCachedRequest(vite, route, options, cachedEntry, pageParams
2023
2034
  }
2024
2035
  const fastViewState = renderedFast.rendered;
2025
2036
  const fastCarryForward = renderedFast.carryForward;
2037
+ const headTags = renderedFast.headTags ?? mergeHeadTags(cachedEntry.carryForward?.__slowHeadTags ?? []);
2026
2038
  await sendResponse(
2027
2039
  vite,
2028
2040
  res,
@@ -2038,7 +2050,8 @@ async function handleCachedRequest(vite, route, options, cachedEntry, pageParams
2038
2050
  options,
2039
2051
  cachedEntry.slowViewState,
2040
2052
  timing,
2041
- cachedEntry.preRenderedContent
2053
+ cachedEntry.preRenderedContent,
2054
+ headTags
2042
2055
  );
2043
2056
  }
2044
2057
  async function handlePreRenderRequest(vite, route, options, slowlyPhase, slowRenderCache, pageParams, pageProps, allPluginClientInits, allPluginsWithInit, projectInit, res, url, timing, query = {}) {
@@ -2057,6 +2070,8 @@ async function handlePreRenderRequest(vite, route, options, slowlyPhase, slowRen
2057
2070
  timing?.end();
2058
2071
  return;
2059
2072
  }
2073
+ const { linkedCssFiles: initCss, linkedComponentFiles: initComps } = initialPartsResult.val;
2074
+ _watchLinkedFiles([...initCss || [], ...initComps || []]);
2060
2075
  const slowStart = Date.now();
2061
2076
  const renderedSlowly = await slowlyPhase.runSlowlyForPage(
2062
2077
  pageParams,
@@ -2149,8 +2164,11 @@ async function handleClientOnlyRequest(vite, route, options, slowlyPhase, pagePa
2149
2164
  usedPackages,
2150
2165
  headlessInstanceComponents,
2151
2166
  discoveredInstances,
2152
- forEachInstances
2167
+ forEachInstances,
2168
+ linkedCssFiles,
2169
+ linkedComponentFiles
2153
2170
  } = pagePartsResult.val;
2171
+ _watchLinkedFiles([...linkedCssFiles || [], ...linkedComponentFiles || []]);
2154
2172
  const pluginsForPage = filterPluginsForPage(
2155
2173
  allPluginClientInits,
2156
2174
  allPluginsWithInit,
@@ -2224,7 +2242,7 @@ async function handleClientOnlyRequest(vite, route, options, slowlyPhase, pagePa
2224
2242
  res.status(200).set({ "Content-Type": "text/html" }).send(compiledPageHtml);
2225
2243
  timing?.end();
2226
2244
  }
2227
- async function sendResponse(vite, res, url, jayHtmlPath, sourceJayHtmlPath, pageParts, viewState, carryForward, clientTrackByMap, projectInit, pluginsForPage, options, slowViewState, timing, preLoadedContent) {
2245
+ async function sendResponse(vite, res, url, jayHtmlPath, sourceJayHtmlPath, pageParts, viewState, carryForward, clientTrackByMap, projectInit, pluginsForPage, options, slowViewState, timing, preLoadedContent, headTags) {
2228
2246
  let pageHtml;
2229
2247
  const routeDir = path__default.dirname(path__default.relative(options.pagesRootFolder, sourceJayHtmlPath));
2230
2248
  try {
@@ -2253,7 +2271,10 @@ async function sendResponse(vite, res, url, jayHtmlPath, sourceJayHtmlPath, page
2253
2271
  {
2254
2272
  enableAutomation: !options.disableAutomation,
2255
2273
  slowViewState
2256
- }
2274
+ },
2275
+ // Pass source directory for headfull FS file resolution when using pre-rendered path
2276
+ jayHtmlDir !== sourceDir ? sourceDir : void 0,
2277
+ headTags
2257
2278
  );
2258
2279
  } catch (err) {
2259
2280
  getLogger().warn(`[SSR] Failed, falling back to client rendering: ${err.message}`);
@@ -2338,10 +2359,15 @@ async function preRenderJayHtml(route, slowViewState, headlessContracts, headles
2338
2359
  let forEachInstances;
2339
2360
  if (headlessInstanceComponents.length > 0) {
2340
2361
  const discoveryResult = discoverHeadlessInstances(preRenderedJayHtml);
2341
- preRenderedJayHtml = discoveryResult.preRenderedJayHtml;
2342
- if (discoveryResult.forEachInstances.length > 0) {
2362
+ const htmlWithRefs = discoveryResult.preRenderedJayHtml;
2363
+ const headlessContractNameSet = new Set(
2364
+ headlessInstanceComponents.map((c2) => c2.contractName)
2365
+ );
2366
+ preRenderedJayHtml = assignCoordinatesToJayHtml(htmlWithRefs, headlessContractNameSet);
2367
+ const finalDiscovery = discoverHeadlessInstances(preRenderedJayHtml);
2368
+ if (finalDiscovery.forEachInstances.length > 0) {
2343
2369
  const validationErrors = validateForEachInstances(
2344
- discoveryResult.forEachInstances,
2370
+ finalDiscovery.forEachInstances,
2345
2371
  headlessInstanceComponents
2346
2372
  );
2347
2373
  if (validationErrors.length > 0) {
@@ -2350,11 +2376,11 @@ async function preRenderJayHtml(route, slowViewState, headlessContracts, headles
2350
2376
  );
2351
2377
  return void 0;
2352
2378
  }
2353
- forEachInstances = discoveryResult.forEachInstances;
2379
+ forEachInstances = finalDiscovery.forEachInstances;
2354
2380
  }
2355
- if (discoveryResult.instances.length > 0) {
2381
+ if (finalDiscovery.instances.length > 0) {
2356
2382
  const slowResult = await slowRenderInstances(
2357
- discoveryResult.instances,
2383
+ finalDiscovery.instances,
2358
2384
  headlessInstanceComponents
2359
2385
  );
2360
2386
  if (slowResult) {
@@ -2450,7 +2476,11 @@ async function mkDevServer(rawOptions) {
2450
2476
  const slowlyPhase = new DevSlowlyChangingPhase();
2451
2477
  const slowRenderCacheDir = path__default.join(buildFolder, "pre-rendered");
2452
2478
  const slowRenderCache = new SlowRenderCache(slowRenderCacheDir, pagesRootFolder);
2453
- setupSlowRenderCacheInvalidation(vite, slowRenderCache, pagesRootFolder);
2479
+ _watchLinkedFiles = setupSlowRenderCacheInvalidation(
2480
+ vite,
2481
+ slowRenderCache,
2482
+ pagesRootFolder
2483
+ );
2454
2484
  const projectInit = lifecycleManager.getProjectInit() ?? void 0;
2455
2485
  const pluginsWithInit = lifecycleManager.getPluginsWithInit();
2456
2486
  const pluginClientInits = preparePluginClientInits(pluginsWithInit);
@@ -2509,19 +2539,39 @@ function setupActionRouter(vite) {
2509
2539
  vite.middlewares.use(ACTION_ENDPOINT_BASE, createActionRouter());
2510
2540
  getLogger().info(`[Actions] Action router mounted at ${ACTION_ENDPOINT_BASE}`);
2511
2541
  }
2512
- function setupSlowRenderCacheInvalidation(vite, cache, pagesRootFolder) {
2542
+ function setupSlowRenderCacheInvalidation(vite, cache, pagesRootFolder, projectRootFolder) {
2543
+ const watchedFiles = /* @__PURE__ */ new Set();
2544
+ const watchLinkedFiles = (files) => {
2545
+ for (const file of files) {
2546
+ if (watchedFiles.has(file))
2547
+ continue;
2548
+ watchedFiles.add(file);
2549
+ vite.watcher.add(file);
2550
+ getLogger().info(`[SlowRender] Watching: ${file}`);
2551
+ }
2552
+ };
2513
2553
  vite.watcher.on("change", (changedPath) => {
2514
- if (!changedPath.startsWith(pagesRootFolder)) {
2554
+ if (watchedFiles.has(changedPath)) {
2555
+ clearServerElementCache();
2556
+ cache.clear().then(() => {
2557
+ getLogger().info(
2558
+ `[SlowRender] Cache cleared (linked file changed: ${changedPath})`
2559
+ );
2560
+ vite.ws.send({ type: "full-reload" });
2561
+ });
2515
2562
  return;
2516
2563
  }
2517
- if (changedPath.endsWith(".jay-html")) {
2564
+ if (changedPath.endsWith(".jay-html") && changedPath.startsWith(pagesRootFolder)) {
2518
2565
  clearServerElementCache();
2519
- cache.invalidate(changedPath).then(() => {
2520
- getLogger().info(`[SlowRender] Cache invalidated for ${changedPath}`);
2566
+ cache.clear().then(() => {
2567
+ getLogger().info(`[SlowRender] Cache cleared (jay-html changed: ${changedPath})`);
2521
2568
  vite.ws.send({ type: "full-reload" });
2522
2569
  });
2523
2570
  return;
2524
2571
  }
2572
+ if (!changedPath.startsWith(pagesRootFolder)) {
2573
+ return;
2574
+ }
2525
2575
  if (changedPath.endsWith("page.ts")) {
2526
2576
  const dir = path__default.dirname(changedPath);
2527
2577
  const jayHtmlPath = path__default.join(dir, "page.jay-html");
@@ -2546,6 +2596,7 @@ function setupSlowRenderCacheInvalidation(vite, cache, pagesRootFolder) {
2546
2596
  return;
2547
2597
  }
2548
2598
  });
2599
+ return watchLinkedFiles;
2549
2600
  }
2550
2601
  export {
2551
2602
  ACTION_ENDPOINT_BASE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/dev-server",
3
- "version": "0.15.5",
3
+ "version": "0.15.6",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -23,22 +23,22 @@
23
23
  "test:watch": "vitest"
24
24
  },
25
25
  "dependencies": {
26
- "@jay-framework/compiler-jay-stack": "^0.15.5",
27
- "@jay-framework/compiler-shared": "^0.15.5",
28
- "@jay-framework/component": "^0.15.5",
29
- "@jay-framework/fullstack-component": "^0.15.5",
30
- "@jay-framework/logger": "^0.15.5",
31
- "@jay-framework/runtime": "^0.15.5",
32
- "@jay-framework/stack-client-runtime": "^0.15.5",
33
- "@jay-framework/stack-route-scanner": "^0.15.5",
34
- "@jay-framework/stack-server-runtime": "^0.15.5",
35
- "@jay-framework/view-state-merge": "^0.15.5",
26
+ "@jay-framework/compiler-jay-stack": "^0.15.6",
27
+ "@jay-framework/compiler-shared": "^0.15.6",
28
+ "@jay-framework/component": "^0.15.6",
29
+ "@jay-framework/fullstack-component": "^0.15.6",
30
+ "@jay-framework/logger": "^0.15.6",
31
+ "@jay-framework/runtime": "^0.15.6",
32
+ "@jay-framework/stack-client-runtime": "^0.15.6",
33
+ "@jay-framework/stack-route-scanner": "^0.15.6",
34
+ "@jay-framework/stack-server-runtime": "^0.15.6",
35
+ "@jay-framework/view-state-merge": "^0.15.6",
36
36
  "vite": "^5.0.11"
37
37
  },
38
38
  "devDependencies": {
39
- "@jay-framework/dev-environment": "^0.15.5",
40
- "@jay-framework/jay-cli": "^0.15.5",
41
- "@jay-framework/stack-client-runtime": "^0.15.5",
39
+ "@jay-framework/dev-environment": "^0.15.6",
40
+ "@jay-framework/jay-cli": "^0.15.6",
41
+ "@jay-framework/stack-client-runtime": "^0.15.6",
42
42
  "@playwright/test": "^1.58.2",
43
43
  "@types/express": "^5.0.2",
44
44
  "@types/node": "^22.15.21",