@nestjs-ssr/react 0.3.4 → 0.3.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.
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
- export { E as ErrorPageDevelopment, e as ErrorPageProduction, c as RenderConfig, b as RenderInterceptor, R as RenderModule, a as RenderService, d as SSRMode, S as StreamingErrorHandler, T as TemplateParserService } from './index-DdE--mA2.mjs';
1
+ export { C as ContextFactory, E as ErrorPageDevelopment, e as ErrorPageProduction, c as RenderConfig, b as RenderInterceptor, R as RenderModule, a as RenderService, d as SSRMode, S as StreamingErrorHandler, T as TemplateParserService } from './index-ZpkYrPcK.mjs';
2
2
  import React, { ComponentType, ReactNode } from 'react';
3
- import { P as PageProps } from './use-page-context-CGT9woWe.mjs';
4
- export { a as PageContextProvider, c as createSSRHooks, i as useCookie, h as useCookies, g as useHeader, f as useHeaders, u as usePageContext, b as useParams, d as useQuery, e as useRequest } from './use-page-context-CGT9woWe.mjs';
5
- import { R as RenderContext, H as HeadData, a as RenderResponse } from './render-response.interface-CxbuKGnV.mjs';
3
+ import { P as PageProps } from './use-page-context-CVC9DHcL.mjs';
4
+ export { a as PageContextProvider, c as createSSRHooks, i as useCookie, h as useCookies, g as useHeader, f as useHeaders, u as usePageContext, b as useParams, d as useQuery, e as useRequest } from './use-page-context-CVC9DHcL.mjs';
5
+ import { R as RenderContext, H as HeadData, a as RenderResponse } from './render-response.interface-ClWJXKL4.mjs';
6
6
  import '@nestjs/common';
7
+ import 'http';
7
8
  import 'vite';
8
- import 'express';
9
9
  import '@nestjs/core';
10
10
  import 'rxjs';
11
11
  import 'react/jsx-runtime';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export { E as ErrorPageDevelopment, e as ErrorPageProduction, c as RenderConfig, b as RenderInterceptor, R as RenderModule, a as RenderService, d as SSRMode, S as StreamingErrorHandler, T as TemplateParserService } from './index-BzOLOiIZ.js';
1
+ export { C as ContextFactory, E as ErrorPageDevelopment, e as ErrorPageProduction, c as RenderConfig, b as RenderInterceptor, R as RenderModule, a as RenderService, d as SSRMode, S as StreamingErrorHandler, T as TemplateParserService } from './index-CSvZfKpi.js';
2
2
  import React, { ComponentType, ReactNode } from 'react';
3
- import { P as PageProps } from './use-page-context-05ODF4zW.js';
4
- export { a as PageContextProvider, c as createSSRHooks, i as useCookie, h as useCookies, g as useHeader, f as useHeaders, u as usePageContext, b as useParams, d as useQuery, e as useRequest } from './use-page-context-05ODF4zW.js';
5
- import { R as RenderContext, H as HeadData, a as RenderResponse } from './render-response.interface-CxbuKGnV.js';
3
+ import { P as PageProps } from './use-page-context-DChgHhL9.js';
4
+ export { a as PageContextProvider, c as createSSRHooks, i as useCookie, h as useCookies, g as useHeader, f as useHeaders, u as usePageContext, b as useParams, d as useQuery, e as useRequest } from './use-page-context-DChgHhL9.js';
5
+ import { R as RenderContext, H as HeadData, a as RenderResponse } from './render-response.interface-ClWJXKL4.js';
6
6
  import '@nestjs/common';
7
+ import 'http';
7
8
  import 'vite';
8
- import 'express';
9
9
  import '@nestjs/core';
10
10
  import 'rxjs';
11
11
  import 'react/jsx-runtime';
package/dist/index.js CHANGED
@@ -315,9 +315,13 @@ var StringRenderer = class _StringRenderer {
315
315
  throw new Error("Server bundle not found in manifest. Run `pnpm build:server` to generate the server bundle.");
316
316
  }
317
317
  }
318
- const { data: pageData, __context: pageContext } = data;
318
+ const { data: pageData, __context: pageContext, __layouts: layouts } = data;
319
319
  const html = await renderModule.renderSegment(viewComponent, data);
320
320
  const componentName = viewComponent.displayName || viewComponent.name || "Component";
321
+ const layoutMetadata = layouts ? layouts.map((l) => ({
322
+ name: l.layout.displayName || l.layout.name || "default",
323
+ props: l.props
324
+ })) : [];
321
325
  if (context.isDevelopment) {
322
326
  const duration = Date.now() - startTime;
323
327
  this.logger.log(`[SSR] ${componentName} segment rendered in ${duration}ms`);
@@ -328,7 +332,8 @@ var StringRenderer = class _StringRenderer {
328
332
  props: pageData,
329
333
  swapTarget,
330
334
  componentName,
331
- context: pageContext
335
+ context: pageContext,
336
+ layouts: layoutMetadata
332
337
  };
333
338
  }
334
339
  };
@@ -457,6 +462,39 @@ function ErrorPageProduction() {
457
462
  }
458
463
  __name(ErrorPageProduction, "ErrorPageProduction");
459
464
 
465
+ // src/render/adapters/http-adapter-utils.ts
466
+ function detectAdapterType(httpAdapterHost) {
467
+ const adapter = httpAdapterHost?.httpAdapter;
468
+ if (!adapter) return "unknown";
469
+ const instance = adapter.getInstance();
470
+ if (instance && typeof instance.register === "function") {
471
+ return "fastify";
472
+ }
473
+ if (instance && typeof instance.use === "function" && typeof instance.get === "function") {
474
+ return "express";
475
+ }
476
+ return "unknown";
477
+ }
478
+ __name(detectAdapterType, "detectAdapterType");
479
+ function isFastifyLikeResponse(res) {
480
+ return res != null && typeof res === "object" && "raw" in res && res.raw != null && typeof res.raw.write === "function";
481
+ }
482
+ __name(isFastifyLikeResponse, "isFastifyLikeResponse");
483
+ function getRawResponse(res) {
484
+ if (isFastifyLikeResponse(res)) {
485
+ return res.raw;
486
+ }
487
+ return res;
488
+ }
489
+ __name(getRawResponse, "getRawResponse");
490
+ function isHeadersSent(res) {
491
+ if (typeof res.sent === "boolean") {
492
+ return res.sent;
493
+ }
494
+ return res.headersSent === true;
495
+ }
496
+ __name(isHeadersSent, "isHeadersSent");
497
+
460
498
  // src/render/streaming-error-handler.ts
461
499
  function _ts_decorate3(decorators, target, key, desc) {
462
500
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -492,21 +530,19 @@ exports.StreamingErrorHandler = class _StreamingErrorHandler {
492
530
  */
493
531
  handleShellError(error, res, viewPath, isDevelopment) {
494
532
  this.logger.error(`Shell error rendering ${viewPath}: ${error.message}`, error.stack);
495
- if (res.headersSent) {
533
+ const rawRes = getRawResponse(res);
534
+ if (isHeadersSent(res)) {
496
535
  this.logger.error(`Cannot send error page for ${viewPath} - headers already sent (streaming started)`);
497
- if (!res.writableEnded) {
498
- res.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
499
- res.end();
536
+ if (!rawRes.writableEnded) {
537
+ rawRes.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
538
+ rawRes.end();
500
539
  }
501
540
  return;
502
541
  }
503
- res.statusCode = 500;
504
- res.setHeader("Content-Type", "text/html; charset=utf-8");
505
- if (isDevelopment) {
506
- res.send(this.renderDevelopmentErrorPage(error, viewPath, "shell"));
507
- } else {
508
- res.send(this.renderProductionErrorPage());
509
- }
542
+ rawRes.statusCode = 500;
543
+ rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
544
+ const html = isDevelopment ? this.renderDevelopmentErrorPage(error, viewPath, "shell") : this.renderProductionErrorPage();
545
+ rawRes.end(html);
510
546
  }
511
547
  /**
512
548
  * Handle error that occurred during streaming
@@ -662,7 +698,7 @@ var StreamRenderer = class _StreamRenderer {
662
698
  *
663
699
  * @param viewComponent - The React component to render
664
700
  * @param data - Data to pass to the component
665
- * @param res - Express response object (required for streaming)
701
+ * @param res - HTTP response object (Express or Fastify)
666
702
  * @param context - Render context with Vite and manifest info
667
703
  * @param head - Head data for SEO tags
668
704
  */
@@ -704,20 +740,21 @@ var StreamRenderer = class _StreamRenderer {
704
740
  const { PassThrough } = await import('stream');
705
741
  const reactStream = new PassThrough();
706
742
  let allReadyFired = false;
743
+ const rawRes = getRawResponse(res);
707
744
  const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
708
745
  onShellReady: /* @__PURE__ */ __name(() => {
709
746
  shellReadyTime = Date.now();
710
- if (!res.headersSent) {
711
- res.statusCode = didError ? 500 : 200;
712
- res.setHeader("Content-Type", "text/html; charset=utf-8");
747
+ if (!rawRes.headersSent) {
748
+ rawRes.statusCode = didError ? 500 : 200;
749
+ rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
713
750
  }
714
751
  let htmlStart = templateParts.htmlStart;
715
752
  htmlStart = htmlStart.replace("<!--styles-->", stylesheetTags);
716
753
  htmlStart = htmlStart.replace("<!--head-meta-->", headTags);
717
- res.write(htmlStart);
718
- res.write(templateParts.rootStart);
754
+ rawRes.write(htmlStart);
755
+ rawRes.write(templateParts.rootStart);
719
756
  pipe(reactStream);
720
- reactStream.pipe(res, {
757
+ reactStream.pipe(rawRes, {
721
758
  end: false
722
759
  });
723
760
  if (context.isDevelopment) {
@@ -742,11 +779,11 @@ var StreamRenderer = class _StreamRenderer {
742
779
  if (shellErrorOccurred) {
743
780
  return;
744
781
  }
745
- res.write(inlineScripts);
746
- res.write(clientScript);
747
- res.write(templateParts.rootEnd);
748
- res.write(templateParts.htmlEnd);
749
- res.end();
782
+ rawRes.write(inlineScripts);
783
+ rawRes.write(clientScript);
784
+ rawRes.write(templateParts.rootEnd);
785
+ rawRes.write(templateParts.htmlEnd);
786
+ rawRes.end();
750
787
  if (context.isDevelopment) {
751
788
  const totalTime = Date.now() - startTime;
752
789
  const streamTime = Date.now() - shellReadyTime;
@@ -758,7 +795,7 @@ var StreamRenderer = class _StreamRenderer {
758
795
  reactStream.on("error", (error) => {
759
796
  reject(error);
760
797
  });
761
- res.on("close", () => {
798
+ rawRes.on("close", () => {
762
799
  abort();
763
800
  resolve();
764
801
  });
@@ -1097,11 +1134,13 @@ exports.RenderInterceptor = class RenderInterceptor {
1097
1134
  renderService;
1098
1135
  allowedHeaders;
1099
1136
  allowedCookies;
1100
- constructor(reflector, renderService, allowedHeaders, allowedCookies) {
1137
+ contextFactory;
1138
+ constructor(reflector, renderService, allowedHeaders, allowedCookies, contextFactory) {
1101
1139
  this.reflector = reflector;
1102
1140
  this.renderService = renderService;
1103
1141
  this.allowedHeaders = allowedHeaders;
1104
1142
  this.allowedCookies = allowedCookies;
1143
+ this.contextFactory = contextFactory;
1105
1144
  }
1106
1145
  /**
1107
1146
  * Resolve the layout hierarchy for a given route
@@ -1241,6 +1280,14 @@ exports.RenderInterceptor = class RenderInterceptor {
1241
1280
  renderContext.cookies = cookies;
1242
1281
  }
1243
1282
  }
1283
+ if (this.contextFactory) {
1284
+ const customContext = await this.contextFactory({
1285
+ req: request
1286
+ });
1287
+ if (customContext) {
1288
+ Object.assign(renderContext, customContext);
1289
+ }
1290
+ }
1244
1291
  const renderResponse = isRenderResponse(data) ? data : {
1245
1292
  props: data
1246
1293
  };
@@ -1287,12 +1334,15 @@ exports.RenderInterceptor = _ts_decorate6([
1287
1334
  _ts_param3(2, common.Inject("ALLOWED_HEADERS")),
1288
1335
  _ts_param3(3, common.Optional()),
1289
1336
  _ts_param3(3, common.Inject("ALLOWED_COOKIES")),
1337
+ _ts_param3(4, common.Optional()),
1338
+ _ts_param3(4, common.Inject("CONTEXT_FACTORY")),
1290
1339
  _ts_metadata5("design:type", Function),
1291
1340
  _ts_metadata5("design:paramtypes", [
1292
1341
  typeof core.Reflector === "undefined" ? Object : core.Reflector,
1293
1342
  typeof exports.RenderService === "undefined" ? Object : exports.RenderService,
1294
1343
  Array,
1295
- Array
1344
+ Array,
1345
+ typeof ContextFactory === "undefined" ? Object : ContextFactory
1296
1346
  ])
1297
1347
  ], exports.RenderInterceptor);
1298
1348
  function _ts_decorate7(decorators, target, key, desc) {
@@ -1343,7 +1393,7 @@ var ViteInitializerService = class _ViteInitializerService {
1343
1393
  if (isDevelopment) {
1344
1394
  await this.setupDevelopmentMode();
1345
1395
  } else {
1346
- this.setupProductionMode();
1396
+ await this.setupProductionMode();
1347
1397
  }
1348
1398
  }
1349
1399
  async setupDevelopmentMode() {
@@ -1385,18 +1435,38 @@ var ViteInitializerService = class _ViteInitializerService {
1385
1435
  this.logger.warn(`Failed to setup Vite proxy: ${error.message}. Make sure http-proxy-middleware is installed.`);
1386
1436
  }
1387
1437
  }
1388
- setupProductionMode() {
1438
+ async setupProductionMode() {
1389
1439
  try {
1390
1440
  const httpAdapter = this.httpAdapterHost.httpAdapter;
1391
- if (httpAdapter) {
1392
- const app = httpAdapter.getInstance();
1393
- const { join: join2 } = __require("path");
1441
+ if (!httpAdapter) return;
1442
+ const app = httpAdapter.getInstance();
1443
+ const { join: join2 } = __require("path");
1444
+ const staticPath = join2(process.cwd(), "dist/client");
1445
+ const adapterType = detectAdapterType(this.httpAdapterHost);
1446
+ if (adapterType === "fastify") {
1447
+ try {
1448
+ const fastifyStatic = await import('@fastify/static').catch(() => null);
1449
+ if (fastifyStatic) {
1450
+ await app.register(fastifyStatic.default, {
1451
+ root: staticPath,
1452
+ prefix: "/",
1453
+ index: false,
1454
+ maxAge: 31536e6
1455
+ });
1456
+ this.logger.log("\u2713 Static assets configured (dist/client) [Fastify]");
1457
+ } else {
1458
+ this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
1459
+ }
1460
+ } catch {
1461
+ this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
1462
+ }
1463
+ } else {
1394
1464
  const express = __require("express");
1395
- app.use(express.static(join2(process.cwd(), "dist/client"), {
1465
+ app.use(express.static(staticPath, {
1396
1466
  index: false,
1397
1467
  maxAge: "1y"
1398
1468
  }));
1399
- this.logger.log("\u2713 Static assets configured (dist/client)");
1469
+ this.logger.log("\u2713 Static assets configured (dist/client) [Express]");
1400
1470
  }
1401
1471
  } catch (error) {
1402
1472
  this.logger.warn(`Failed to setup static assets: ${error.message}`);
@@ -1536,6 +1606,12 @@ exports.RenderModule = class _RenderModule {
1536
1606
  provide: "ALLOWED_COOKIES",
1537
1607
  useValue: config?.allowedCookies || []
1538
1608
  });
1609
+ if (config?.context) {
1610
+ providers.push({
1611
+ provide: "CONTEXT_FACTORY",
1612
+ useValue: config.context
1613
+ });
1614
+ }
1539
1615
  return {
1540
1616
  global: true,
1541
1617
  module: _RenderModule,
@@ -1654,6 +1730,13 @@ exports.RenderModule = class _RenderModule {
1654
1730
  inject: [
1655
1731
  "RENDER_CONFIG"
1656
1732
  ]
1733
+ },
1734
+ {
1735
+ provide: "CONTEXT_FACTORY",
1736
+ useFactory: /* @__PURE__ */ __name((config) => config?.context, "useFactory"),
1737
+ inject: [
1738
+ "RENDER_CONFIG"
1739
+ ]
1657
1740
  }
1658
1741
  ];
1659
1742
  return {
@@ -1716,9 +1799,28 @@ var PageContext = getOrCreateContext();
1716
1799
  function registerPageContextState(setter) {
1717
1800
  }
1718
1801
  __name(registerPageContextState, "registerPageContextState");
1802
+ var segmentSetters = /* @__PURE__ */ new Set();
1803
+ function registerSegmentSetter(setter) {
1804
+ segmentSetters.add(setter);
1805
+ }
1806
+ __name(registerSegmentSetter, "registerSegmentSetter");
1807
+ function unregisterSegmentSetter(setter) {
1808
+ segmentSetters.delete(setter);
1809
+ }
1810
+ __name(unregisterSegmentSetter, "unregisterSegmentSetter");
1811
+ function broadcastToSegments(context) {
1812
+ segmentSetters.forEach((setter) => setter(context));
1813
+ }
1814
+ __name(broadcastToSegments, "broadcastToSegments");
1719
1815
  function PageContextProvider({ context: initialContext, children, isSegment = false }) {
1720
1816
  const [context, setContext] = React2.useState(initialContext);
1721
1817
  React2.useEffect(() => {
1818
+ if (!isSegment) {
1819
+ return void 0;
1820
+ } else {
1821
+ registerSegmentSetter(setContext);
1822
+ return () => unregisterSegmentSetter(setContext);
1823
+ }
1722
1824
  }, [
1723
1825
  isSegment
1724
1826
  ]);
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Injectable, Logger, Optional, Inject, Global, Module, SetMetadata } from '@nestjs/common';
2
- import { HttpAdapterHost, APP_INTERCEPTOR, Reflector } from '@nestjs/core';
2
+ import { Reflector, HttpAdapterHost, APP_INTERCEPTOR } from '@nestjs/core';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
  import { join, relative } from 'path';
5
5
  import { uneval } from 'devalue';
@@ -308,9 +308,13 @@ var StringRenderer = class _StringRenderer {
308
308
  throw new Error("Server bundle not found in manifest. Run `pnpm build:server` to generate the server bundle.");
309
309
  }
310
310
  }
311
- const { data: pageData, __context: pageContext } = data;
311
+ const { data: pageData, __context: pageContext, __layouts: layouts } = data;
312
312
  const html = await renderModule.renderSegment(viewComponent, data);
313
313
  const componentName = viewComponent.displayName || viewComponent.name || "Component";
314
+ const layoutMetadata = layouts ? layouts.map((l) => ({
315
+ name: l.layout.displayName || l.layout.name || "default",
316
+ props: l.props
317
+ })) : [];
314
318
  if (context.isDevelopment) {
315
319
  const duration = Date.now() - startTime;
316
320
  this.logger.log(`[SSR] ${componentName} segment rendered in ${duration}ms`);
@@ -321,7 +325,8 @@ var StringRenderer = class _StringRenderer {
321
325
  props: pageData,
322
326
  swapTarget,
323
327
  componentName,
324
- context: pageContext
328
+ context: pageContext,
329
+ layouts: layoutMetadata
325
330
  };
326
331
  }
327
332
  };
@@ -450,6 +455,39 @@ function ErrorPageProduction() {
450
455
  }
451
456
  __name(ErrorPageProduction, "ErrorPageProduction");
452
457
 
458
+ // src/render/adapters/http-adapter-utils.ts
459
+ function detectAdapterType(httpAdapterHost) {
460
+ const adapter = httpAdapterHost?.httpAdapter;
461
+ if (!adapter) return "unknown";
462
+ const instance = adapter.getInstance();
463
+ if (instance && typeof instance.register === "function") {
464
+ return "fastify";
465
+ }
466
+ if (instance && typeof instance.use === "function" && typeof instance.get === "function") {
467
+ return "express";
468
+ }
469
+ return "unknown";
470
+ }
471
+ __name(detectAdapterType, "detectAdapterType");
472
+ function isFastifyLikeResponse(res) {
473
+ return res != null && typeof res === "object" && "raw" in res && res.raw != null && typeof res.raw.write === "function";
474
+ }
475
+ __name(isFastifyLikeResponse, "isFastifyLikeResponse");
476
+ function getRawResponse(res) {
477
+ if (isFastifyLikeResponse(res)) {
478
+ return res.raw;
479
+ }
480
+ return res;
481
+ }
482
+ __name(getRawResponse, "getRawResponse");
483
+ function isHeadersSent(res) {
484
+ if (typeof res.sent === "boolean") {
485
+ return res.sent;
486
+ }
487
+ return res.headersSent === true;
488
+ }
489
+ __name(isHeadersSent, "isHeadersSent");
490
+
453
491
  // src/render/streaming-error-handler.ts
454
492
  function _ts_decorate3(decorators, target, key, desc) {
455
493
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -485,21 +523,19 @@ var StreamingErrorHandler = class _StreamingErrorHandler {
485
523
  */
486
524
  handleShellError(error, res, viewPath, isDevelopment) {
487
525
  this.logger.error(`Shell error rendering ${viewPath}: ${error.message}`, error.stack);
488
- if (res.headersSent) {
526
+ const rawRes = getRawResponse(res);
527
+ if (isHeadersSent(res)) {
489
528
  this.logger.error(`Cannot send error page for ${viewPath} - headers already sent (streaming started)`);
490
- if (!res.writableEnded) {
491
- res.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
492
- res.end();
529
+ if (!rawRes.writableEnded) {
530
+ rawRes.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
531
+ rawRes.end();
493
532
  }
494
533
  return;
495
534
  }
496
- res.statusCode = 500;
497
- res.setHeader("Content-Type", "text/html; charset=utf-8");
498
- if (isDevelopment) {
499
- res.send(this.renderDevelopmentErrorPage(error, viewPath, "shell"));
500
- } else {
501
- res.send(this.renderProductionErrorPage());
502
- }
535
+ rawRes.statusCode = 500;
536
+ rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
537
+ const html = isDevelopment ? this.renderDevelopmentErrorPage(error, viewPath, "shell") : this.renderProductionErrorPage();
538
+ rawRes.end(html);
503
539
  }
504
540
  /**
505
541
  * Handle error that occurred during streaming
@@ -655,7 +691,7 @@ var StreamRenderer = class _StreamRenderer {
655
691
  *
656
692
  * @param viewComponent - The React component to render
657
693
  * @param data - Data to pass to the component
658
- * @param res - Express response object (required for streaming)
694
+ * @param res - HTTP response object (Express or Fastify)
659
695
  * @param context - Render context with Vite and manifest info
660
696
  * @param head - Head data for SEO tags
661
697
  */
@@ -697,20 +733,21 @@ var StreamRenderer = class _StreamRenderer {
697
733
  const { PassThrough } = await import('stream');
698
734
  const reactStream = new PassThrough();
699
735
  let allReadyFired = false;
736
+ const rawRes = getRawResponse(res);
700
737
  const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
701
738
  onShellReady: /* @__PURE__ */ __name(() => {
702
739
  shellReadyTime = Date.now();
703
- if (!res.headersSent) {
704
- res.statusCode = didError ? 500 : 200;
705
- res.setHeader("Content-Type", "text/html; charset=utf-8");
740
+ if (!rawRes.headersSent) {
741
+ rawRes.statusCode = didError ? 500 : 200;
742
+ rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
706
743
  }
707
744
  let htmlStart = templateParts.htmlStart;
708
745
  htmlStart = htmlStart.replace("<!--styles-->", stylesheetTags);
709
746
  htmlStart = htmlStart.replace("<!--head-meta-->", headTags);
710
- res.write(htmlStart);
711
- res.write(templateParts.rootStart);
747
+ rawRes.write(htmlStart);
748
+ rawRes.write(templateParts.rootStart);
712
749
  pipe(reactStream);
713
- reactStream.pipe(res, {
750
+ reactStream.pipe(rawRes, {
714
751
  end: false
715
752
  });
716
753
  if (context.isDevelopment) {
@@ -735,11 +772,11 @@ var StreamRenderer = class _StreamRenderer {
735
772
  if (shellErrorOccurred) {
736
773
  return;
737
774
  }
738
- res.write(inlineScripts);
739
- res.write(clientScript);
740
- res.write(templateParts.rootEnd);
741
- res.write(templateParts.htmlEnd);
742
- res.end();
775
+ rawRes.write(inlineScripts);
776
+ rawRes.write(clientScript);
777
+ rawRes.write(templateParts.rootEnd);
778
+ rawRes.write(templateParts.htmlEnd);
779
+ rawRes.end();
743
780
  if (context.isDevelopment) {
744
781
  const totalTime = Date.now() - startTime;
745
782
  const streamTime = Date.now() - shellReadyTime;
@@ -751,7 +788,7 @@ var StreamRenderer = class _StreamRenderer {
751
788
  reactStream.on("error", (error) => {
752
789
  reject(error);
753
790
  });
754
- res.on("close", () => {
791
+ rawRes.on("close", () => {
755
792
  abort();
756
793
  resolve();
757
794
  });
@@ -1090,11 +1127,13 @@ var RenderInterceptor = class {
1090
1127
  renderService;
1091
1128
  allowedHeaders;
1092
1129
  allowedCookies;
1093
- constructor(reflector, renderService, allowedHeaders, allowedCookies) {
1130
+ contextFactory;
1131
+ constructor(reflector, renderService, allowedHeaders, allowedCookies, contextFactory) {
1094
1132
  this.reflector = reflector;
1095
1133
  this.renderService = renderService;
1096
1134
  this.allowedHeaders = allowedHeaders;
1097
1135
  this.allowedCookies = allowedCookies;
1136
+ this.contextFactory = contextFactory;
1098
1137
  }
1099
1138
  /**
1100
1139
  * Resolve the layout hierarchy for a given route
@@ -1234,6 +1273,14 @@ var RenderInterceptor = class {
1234
1273
  renderContext.cookies = cookies;
1235
1274
  }
1236
1275
  }
1276
+ if (this.contextFactory) {
1277
+ const customContext = await this.contextFactory({
1278
+ req: request
1279
+ });
1280
+ if (customContext) {
1281
+ Object.assign(renderContext, customContext);
1282
+ }
1283
+ }
1237
1284
  const renderResponse = isRenderResponse(data) ? data : {
1238
1285
  props: data
1239
1286
  };
@@ -1280,12 +1327,15 @@ RenderInterceptor = _ts_decorate6([
1280
1327
  _ts_param3(2, Inject("ALLOWED_HEADERS")),
1281
1328
  _ts_param3(3, Optional()),
1282
1329
  _ts_param3(3, Inject("ALLOWED_COOKIES")),
1330
+ _ts_param3(4, Optional()),
1331
+ _ts_param3(4, Inject("CONTEXT_FACTORY")),
1283
1332
  _ts_metadata5("design:type", Function),
1284
1333
  _ts_metadata5("design:paramtypes", [
1285
1334
  typeof Reflector === "undefined" ? Object : Reflector,
1286
1335
  typeof RenderService === "undefined" ? Object : RenderService,
1287
1336
  Array,
1288
- Array
1337
+ Array,
1338
+ typeof ContextFactory === "undefined" ? Object : ContextFactory
1289
1339
  ])
1290
1340
  ], RenderInterceptor);
1291
1341
  function _ts_decorate7(decorators, target, key, desc) {
@@ -1336,7 +1386,7 @@ var ViteInitializerService = class _ViteInitializerService {
1336
1386
  if (isDevelopment) {
1337
1387
  await this.setupDevelopmentMode();
1338
1388
  } else {
1339
- this.setupProductionMode();
1389
+ await this.setupProductionMode();
1340
1390
  }
1341
1391
  }
1342
1392
  async setupDevelopmentMode() {
@@ -1378,18 +1428,38 @@ var ViteInitializerService = class _ViteInitializerService {
1378
1428
  this.logger.warn(`Failed to setup Vite proxy: ${error.message}. Make sure http-proxy-middleware is installed.`);
1379
1429
  }
1380
1430
  }
1381
- setupProductionMode() {
1431
+ async setupProductionMode() {
1382
1432
  try {
1383
1433
  const httpAdapter = this.httpAdapterHost.httpAdapter;
1384
- if (httpAdapter) {
1385
- const app = httpAdapter.getInstance();
1386
- const { join: join2 } = __require("path");
1434
+ if (!httpAdapter) return;
1435
+ const app = httpAdapter.getInstance();
1436
+ const { join: join2 } = __require("path");
1437
+ const staticPath = join2(process.cwd(), "dist/client");
1438
+ const adapterType = detectAdapterType(this.httpAdapterHost);
1439
+ if (adapterType === "fastify") {
1440
+ try {
1441
+ const fastifyStatic = await import('@fastify/static').catch(() => null);
1442
+ if (fastifyStatic) {
1443
+ await app.register(fastifyStatic.default, {
1444
+ root: staticPath,
1445
+ prefix: "/",
1446
+ index: false,
1447
+ maxAge: 31536e6
1448
+ });
1449
+ this.logger.log("\u2713 Static assets configured (dist/client) [Fastify]");
1450
+ } else {
1451
+ this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
1452
+ }
1453
+ } catch {
1454
+ this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
1455
+ }
1456
+ } else {
1387
1457
  const express = __require("express");
1388
- app.use(express.static(join2(process.cwd(), "dist/client"), {
1458
+ app.use(express.static(staticPath, {
1389
1459
  index: false,
1390
1460
  maxAge: "1y"
1391
1461
  }));
1392
- this.logger.log("\u2713 Static assets configured (dist/client)");
1462
+ this.logger.log("\u2713 Static assets configured (dist/client) [Express]");
1393
1463
  }
1394
1464
  } catch (error) {
1395
1465
  this.logger.warn(`Failed to setup static assets: ${error.message}`);
@@ -1529,6 +1599,12 @@ var RenderModule = class _RenderModule {
1529
1599
  provide: "ALLOWED_COOKIES",
1530
1600
  useValue: config?.allowedCookies || []
1531
1601
  });
1602
+ if (config?.context) {
1603
+ providers.push({
1604
+ provide: "CONTEXT_FACTORY",
1605
+ useValue: config.context
1606
+ });
1607
+ }
1532
1608
  return {
1533
1609
  global: true,
1534
1610
  module: _RenderModule,
@@ -1647,6 +1723,13 @@ var RenderModule = class _RenderModule {
1647
1723
  inject: [
1648
1724
  "RENDER_CONFIG"
1649
1725
  ]
1726
+ },
1727
+ {
1728
+ provide: "CONTEXT_FACTORY",
1729
+ useFactory: /* @__PURE__ */ __name((config) => config?.context, "useFactory"),
1730
+ inject: [
1731
+ "RENDER_CONFIG"
1732
+ ]
1650
1733
  }
1651
1734
  ];
1652
1735
  return {
@@ -1709,9 +1792,28 @@ var PageContext = getOrCreateContext();
1709
1792
  function registerPageContextState(setter) {
1710
1793
  }
1711
1794
  __name(registerPageContextState, "registerPageContextState");
1795
+ var segmentSetters = /* @__PURE__ */ new Set();
1796
+ function registerSegmentSetter(setter) {
1797
+ segmentSetters.add(setter);
1798
+ }
1799
+ __name(registerSegmentSetter, "registerSegmentSetter");
1800
+ function unregisterSegmentSetter(setter) {
1801
+ segmentSetters.delete(setter);
1802
+ }
1803
+ __name(unregisterSegmentSetter, "unregisterSegmentSetter");
1804
+ function broadcastToSegments(context) {
1805
+ segmentSetters.forEach((setter) => setter(context));
1806
+ }
1807
+ __name(broadcastToSegments, "broadcastToSegments");
1712
1808
  function PageContextProvider({ context: initialContext, children, isSegment = false }) {
1713
1809
  const [context, setContext] = useState(initialContext);
1714
1810
  useEffect(() => {
1811
+ if (!isSegment) {
1812
+ return void 0;
1813
+ } else {
1814
+ registerSegmentSetter(setContext);
1815
+ return () => unregisterSegmentSetter(setContext);
1816
+ }
1715
1817
  }, [
1716
1818
  isSegment
1717
1819
  ]);
@@ -1,9 +1,9 @@
1
- export { E as ErrorPageDevelopment, e as ErrorPageProduction, b as RenderInterceptor, R as RenderModule, a as RenderService, S as StreamingErrorHandler, T as TemplateParserService } from '../index-DdE--mA2.mjs';
1
+ export { E as ErrorPageDevelopment, e as ErrorPageProduction, b as RenderInterceptor, R as RenderModule, a as RenderService, S as StreamingErrorHandler, T as TemplateParserService } from '../index-ZpkYrPcK.mjs';
2
2
  import '@nestjs/common';
3
3
  import 'react';
4
- import '../render-response.interface-CxbuKGnV.mjs';
4
+ import '../render-response.interface-ClWJXKL4.mjs';
5
+ import 'http';
5
6
  import 'vite';
6
- import 'express';
7
7
  import '@nestjs/core';
8
8
  import 'rxjs';
9
9
  import 'react/jsx-runtime';