@nestjs-ssr/react 0.1.5 → 0.1.7
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/README.md +60 -73
- package/dist/{index-Bptct1Q3.d.mts → index-Bpzo1KfR.d.mts} +4 -2
- package/dist/{index-Bptct1Q3.d.ts → index-Bpzo1KfR.d.ts} +4 -2
- package/dist/index.d.mts +31 -22
- package/dist/index.d.ts +31 -22
- package/dist/index.js +77 -7046
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +70 -7018
- package/dist/index.mjs.map +1 -1
- package/dist/render/index.d.mts +1 -1
- package/dist/render/index.d.ts +1 -1
- package/dist/render/index.js +61 -26
- package/dist/render/index.js.map +1 -1
- package/dist/render/index.mjs +62 -27
- package/dist/render/index.mjs.map +1 -1
- package/dist/templates/entry-client.tsx +37 -4
- package/dist/templates/entry-server.tsx +4 -8
- package/package.json +1 -1
- package/src/global.d.ts +2 -10
- package/src/templates/entry-client.tsx +37 -4
- package/src/templates/entry-server.tsx +4 -8
- package/dist/vite/index.d.mts +0 -11
- package/dist/vite/index.d.ts +0 -11
- package/dist/vite/index.js +0 -7022
- package/dist/vite/index.js.map +0 -1
- package/dist/vite/index.mjs +0 -6997
- package/dist/vite/index.mjs.map +0 -1
package/dist/render/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { E as ErrorPageDevelopment, f as ErrorPageProduction, b as RenderInterceptor, R as RenderModule, a as RenderService, S as StreamingErrorHandler, T as TemplateParserService } from '../index-
|
|
1
|
+
export { E as ErrorPageDevelopment, f as ErrorPageProduction, b as RenderInterceptor, R as RenderModule, a as RenderService, S as StreamingErrorHandler, T as TemplateParserService } from '../index-Bpzo1KfR.mjs';
|
|
2
2
|
import '@nestjs/common';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'vite';
|
package/dist/render/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { E as ErrorPageDevelopment, f as ErrorPageProduction, b as RenderInterceptor, R as RenderModule, a as RenderService, S as StreamingErrorHandler, T as TemplateParserService } from '../index-
|
|
1
|
+
export { E as ErrorPageDevelopment, f as ErrorPageProduction, b as RenderInterceptor, R as RenderModule, a as RenderService, S as StreamingErrorHandler, T as TemplateParserService } from '../index-Bpzo1KfR.js';
|
|
2
2
|
import '@nestjs/common';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'vite';
|
package/dist/render/index.js
CHANGED
|
@@ -109,7 +109,7 @@ exports.TemplateParserService = class TemplateParserService {
|
|
|
109
109
|
* This library handles all edge cases including escaping dangerous characters,
|
|
110
110
|
* functions, dates, regexes, and prevents prototype pollution.
|
|
111
111
|
*/
|
|
112
|
-
buildInlineScripts(data, context,
|
|
112
|
+
buildInlineScripts(data, context, componentName) {
|
|
113
113
|
return `<script>
|
|
114
114
|
window.__INITIAL_STATE__ = ${serialize__default.default(data, {
|
|
115
115
|
isJSON: true
|
|
@@ -117,7 +117,7 @@ window.__INITIAL_STATE__ = ${serialize__default.default(data, {
|
|
|
117
117
|
window.__CONTEXT__ = ${serialize__default.default(context, {
|
|
118
118
|
isJSON: true
|
|
119
119
|
})};
|
|
120
|
-
window.
|
|
120
|
+
window.__COMPONENT_NAME__ = ${serialize__default.default(componentName, {
|
|
121
121
|
isJSON: true
|
|
122
122
|
})};
|
|
123
123
|
</script>`;
|
|
@@ -427,12 +427,28 @@ exports.RenderService = class _RenderService {
|
|
|
427
427
|
serverManifest = null;
|
|
428
428
|
isDevelopment;
|
|
429
429
|
ssrMode;
|
|
430
|
+
entryServerPath;
|
|
431
|
+
entryClientPath;
|
|
430
432
|
constructor(templateParser, streamingErrorHandler, ssrMode, defaultHead) {
|
|
431
433
|
this.templateParser = templateParser;
|
|
432
434
|
this.streamingErrorHandler = streamingErrorHandler;
|
|
433
435
|
this.defaultHead = defaultHead;
|
|
434
436
|
this.isDevelopment = process.env.NODE_ENV !== "production";
|
|
435
437
|
this.ssrMode = ssrMode || process.env.SSR_MODE || "string";
|
|
438
|
+
const absoluteServerPath = path.join(__dirname, "/templates/entry-server.tsx");
|
|
439
|
+
const relativeServerPath = path.relative(process.cwd(), absoluteServerPath);
|
|
440
|
+
if (relativeServerPath.startsWith("..")) {
|
|
441
|
+
this.entryServerPath = absoluteServerPath;
|
|
442
|
+
} else {
|
|
443
|
+
this.entryServerPath = "/" + relativeServerPath.replace(/\\/g, "/");
|
|
444
|
+
}
|
|
445
|
+
const absoluteClientPath = path.join(__dirname, "/templates/entry-client.tsx");
|
|
446
|
+
const relativeClientPath = path.relative(process.cwd(), absoluteClientPath);
|
|
447
|
+
if (relativeClientPath.startsWith("..")) {
|
|
448
|
+
this.entryClientPath = absoluteClientPath;
|
|
449
|
+
} else {
|
|
450
|
+
this.entryClientPath = "/" + relativeClientPath.replace(/\\/g, "/");
|
|
451
|
+
}
|
|
436
452
|
let templatePath;
|
|
437
453
|
if (this.isDevelopment) {
|
|
438
454
|
const packageTemplatePaths = [
|
|
@@ -484,15 +500,15 @@ exports.RenderService = class _RenderService {
|
|
|
484
500
|
/**
|
|
485
501
|
* Main render method that routes to string or stream mode
|
|
486
502
|
*/
|
|
487
|
-
async render(
|
|
503
|
+
async render(viewComponent, data = {}, res, head) {
|
|
488
504
|
const mergedHead = this.mergeHead(this.defaultHead, head);
|
|
489
505
|
if (this.ssrMode === "stream") {
|
|
490
506
|
if (!res) {
|
|
491
507
|
throw new Error("Response object is required for streaming SSR mode. Pass res as third parameter.");
|
|
492
508
|
}
|
|
493
|
-
return this.renderToStream(
|
|
509
|
+
return this.renderToStream(viewComponent, data, res, mergedHead);
|
|
494
510
|
}
|
|
495
|
-
return this.renderToString(
|
|
511
|
+
return this.renderToString(viewComponent, data, mergedHead);
|
|
496
512
|
}
|
|
497
513
|
/**
|
|
498
514
|
* Merge default head with page-specific head
|
|
@@ -519,7 +535,7 @@ exports.RenderService = class _RenderService {
|
|
|
519
535
|
/**
|
|
520
536
|
* Traditional string-based SSR using renderToString
|
|
521
537
|
*/
|
|
522
|
-
async renderToString(
|
|
538
|
+
async renderToString(viewComponent, data = {}, head) {
|
|
523
539
|
const startTime = Date.now();
|
|
524
540
|
try {
|
|
525
541
|
let template = this.template;
|
|
@@ -528,7 +544,7 @@ exports.RenderService = class _RenderService {
|
|
|
528
544
|
}
|
|
529
545
|
let renderModule;
|
|
530
546
|
if (this.vite) {
|
|
531
|
-
renderModule = await this.vite.ssrLoadModule(
|
|
547
|
+
renderModule = await this.vite.ssrLoadModule(this.entryServerPath);
|
|
532
548
|
} else {
|
|
533
549
|
if (this.serverManifest) {
|
|
534
550
|
const manifestEntry = Object.entries(this.serverManifest).find(([key, value]) => value.isEntry && key.includes("entry-server"));
|
|
@@ -544,7 +560,8 @@ exports.RenderService = class _RenderService {
|
|
|
544
560
|
}
|
|
545
561
|
}
|
|
546
562
|
const { data: pageData, __context: context } = data;
|
|
547
|
-
const appHtml = await renderModule.renderComponent(
|
|
563
|
+
const appHtml = await renderModule.renderComponent(viewComponent, data);
|
|
564
|
+
const componentName = viewComponent.displayName || viewComponent.name || "Component";
|
|
548
565
|
const initialStateScript = `
|
|
549
566
|
<script>
|
|
550
567
|
window.__INITIAL_STATE__ = ${serialize__default.default(pageData, {
|
|
@@ -553,7 +570,7 @@ exports.RenderService = class _RenderService {
|
|
|
553
570
|
window.__CONTEXT__ = ${serialize__default.default(context, {
|
|
554
571
|
isJSON: true
|
|
555
572
|
})};
|
|
556
|
-
window.
|
|
573
|
+
window.__COMPONENT_NAME__ = ${serialize__default.default(componentName, {
|
|
557
574
|
isJSON: true
|
|
558
575
|
})};
|
|
559
576
|
</script>
|
|
@@ -561,7 +578,7 @@ exports.RenderService = class _RenderService {
|
|
|
561
578
|
let clientScript = "";
|
|
562
579
|
let styles = "";
|
|
563
580
|
if (this.vite) {
|
|
564
|
-
clientScript = `<script type="module" src="
|
|
581
|
+
clientScript = `<script type="module" src="${this.entryClientPath}"></script>`;
|
|
565
582
|
styles = "";
|
|
566
583
|
} else {
|
|
567
584
|
if (this.manifest) {
|
|
@@ -591,7 +608,8 @@ exports.RenderService = class _RenderService {
|
|
|
591
608
|
html = html.replace("<!--head-meta-->", headTags);
|
|
592
609
|
if (this.isDevelopment) {
|
|
593
610
|
const duration = Date.now() - startTime;
|
|
594
|
-
|
|
611
|
+
const componentName2 = typeof viewComponent === "function" ? viewComponent.name : String(viewComponent);
|
|
612
|
+
this.logger.log(`[SSR] ${componentName2} rendered in ${duration}ms (string mode)`);
|
|
595
613
|
}
|
|
596
614
|
return html;
|
|
597
615
|
} catch (error) {
|
|
@@ -601,7 +619,7 @@ exports.RenderService = class _RenderService {
|
|
|
601
619
|
/**
|
|
602
620
|
* Modern streaming SSR using renderToPipeableStream
|
|
603
621
|
*/
|
|
604
|
-
async renderToStream(
|
|
622
|
+
async renderToStream(viewComponent, data = {}, res, head) {
|
|
605
623
|
const startTime = Date.now();
|
|
606
624
|
let shellReadyTime = 0;
|
|
607
625
|
try {
|
|
@@ -612,7 +630,7 @@ exports.RenderService = class _RenderService {
|
|
|
612
630
|
const templateParts = this.templateParser.parseTemplate(template);
|
|
613
631
|
let renderModule;
|
|
614
632
|
if (this.vite) {
|
|
615
|
-
renderModule = await this.vite.ssrLoadModule(
|
|
633
|
+
renderModule = await this.vite.ssrLoadModule(this.entryServerPath);
|
|
616
634
|
} else {
|
|
617
635
|
if (this.serverManifest) {
|
|
618
636
|
const manifestEntry = Object.entries(this.serverManifest).find(([key, value]) => value.isEntry && key.includes("entry-server"));
|
|
@@ -628,12 +646,13 @@ exports.RenderService = class _RenderService {
|
|
|
628
646
|
}
|
|
629
647
|
}
|
|
630
648
|
const { data: pageData, __context: context } = data;
|
|
631
|
-
const
|
|
649
|
+
const componentName = viewComponent.displayName || viewComponent.name || "Component";
|
|
650
|
+
const inlineScripts = this.templateParser.buildInlineScripts(pageData, context, componentName);
|
|
632
651
|
const clientScript = this.templateParser.getClientScriptTag(this.isDevelopment, this.manifest);
|
|
633
652
|
const stylesheetTags = this.templateParser.getStylesheetTags(this.isDevelopment, this.manifest);
|
|
634
653
|
const headTags = this.templateParser.buildHeadTags(head);
|
|
635
654
|
let didError = false;
|
|
636
|
-
const { pipe, abort } = renderModule.renderComponentStream(
|
|
655
|
+
const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
|
|
637
656
|
onShellReady: /* @__PURE__ */ __name(() => {
|
|
638
657
|
shellReadyTime = Date.now();
|
|
639
658
|
res.statusCode = didError ? 500 : 200;
|
|
@@ -646,15 +665,15 @@ exports.RenderService = class _RenderService {
|
|
|
646
665
|
pipe(res);
|
|
647
666
|
if (this.isDevelopment) {
|
|
648
667
|
const ttfb = shellReadyTime - startTime;
|
|
649
|
-
this.logger.log(`[SSR] ${
|
|
668
|
+
this.logger.log(`[SSR] ${componentName} shell ready in ${ttfb}ms (stream mode - TTFB)`);
|
|
650
669
|
}
|
|
651
670
|
}, "onShellReady"),
|
|
652
671
|
onShellError: /* @__PURE__ */ __name((error) => {
|
|
653
|
-
this.streamingErrorHandler.handleShellError(error, res,
|
|
672
|
+
this.streamingErrorHandler.handleShellError(error, res, componentName, this.isDevelopment);
|
|
654
673
|
}, "onShellError"),
|
|
655
674
|
onError: /* @__PURE__ */ __name((error) => {
|
|
656
675
|
didError = true;
|
|
657
|
-
this.streamingErrorHandler.handleStreamError(error,
|
|
676
|
+
this.streamingErrorHandler.handleStreamError(error, componentName);
|
|
658
677
|
}, "onError"),
|
|
659
678
|
onAllReady: /* @__PURE__ */ __name(() => {
|
|
660
679
|
res.write(inlineScripts);
|
|
@@ -665,7 +684,7 @@ exports.RenderService = class _RenderService {
|
|
|
665
684
|
if (this.isDevelopment) {
|
|
666
685
|
const totalTime = Date.now() - startTime;
|
|
667
686
|
const streamTime = Date.now() - shellReadyTime;
|
|
668
|
-
this.logger.log(`[SSR] ${
|
|
687
|
+
this.logger.log(`[SSR] ${componentName} streaming complete in ${totalTime}ms total (${streamTime}ms streaming)`);
|
|
669
688
|
}
|
|
670
689
|
}, "onAllReady")
|
|
671
690
|
});
|
|
@@ -673,7 +692,8 @@ exports.RenderService = class _RenderService {
|
|
|
673
692
|
abort();
|
|
674
693
|
});
|
|
675
694
|
} catch (error) {
|
|
676
|
-
|
|
695
|
+
const componentName = typeof viewComponent === "function" ? viewComponent.name : String(viewComponent);
|
|
696
|
+
this.streamingErrorHandler.handleShellError(error, res, componentName, this.isDevelopment);
|
|
677
697
|
}
|
|
678
698
|
}
|
|
679
699
|
};
|
|
@@ -720,8 +740,8 @@ exports.RenderInterceptor = class RenderInterceptor {
|
|
|
720
740
|
this.renderService = renderService;
|
|
721
741
|
}
|
|
722
742
|
intercept(context, next) {
|
|
723
|
-
const
|
|
724
|
-
if (!
|
|
743
|
+
const viewPathOrComponent = this.reflector.get(RENDER_KEY, context.getHandler());
|
|
744
|
+
if (!viewPathOrComponent) {
|
|
725
745
|
return next.handle();
|
|
726
746
|
}
|
|
727
747
|
return next.handle().pipe(operators.switchMap(async (data) => {
|
|
@@ -745,7 +765,7 @@ exports.RenderInterceptor = class RenderInterceptor {
|
|
|
745
765
|
__context: renderContext
|
|
746
766
|
};
|
|
747
767
|
try {
|
|
748
|
-
const html = await this.renderService.render(
|
|
768
|
+
const html = await this.renderService.render(viewPathOrComponent, fullData, response, renderResponse.head);
|
|
749
769
|
if (html !== void 0) {
|
|
750
770
|
response.type("text/html");
|
|
751
771
|
return html;
|
|
@@ -791,6 +811,7 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
791
811
|
logger = new common.Logger(_ViteInitializerService.name);
|
|
792
812
|
viteMode;
|
|
793
813
|
vitePort;
|
|
814
|
+
viteServer = null;
|
|
794
815
|
constructor(renderService, httpAdapterHost, viteConfig) {
|
|
795
816
|
this.renderService = renderService;
|
|
796
817
|
this.httpAdapterHost = httpAdapterHost;
|
|
@@ -808,15 +829,15 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
808
829
|
async setupDevelopmentMode() {
|
|
809
830
|
try {
|
|
810
831
|
const { createServer: createViteServer } = await import('vite');
|
|
811
|
-
|
|
832
|
+
this.viteServer = await createViteServer({
|
|
812
833
|
server: {
|
|
813
834
|
middlewareMode: true
|
|
814
835
|
},
|
|
815
836
|
appType: "custom"
|
|
816
837
|
});
|
|
817
|
-
this.renderService.setViteServer(
|
|
838
|
+
this.renderService.setViteServer(this.viteServer);
|
|
818
839
|
if (this.viteMode === "embedded") {
|
|
819
|
-
await this.mountViteMiddleware(
|
|
840
|
+
await this.mountViteMiddleware(this.viteServer);
|
|
820
841
|
} else if (this.viteMode === "proxy") {
|
|
821
842
|
await this.setupViteProxy();
|
|
822
843
|
}
|
|
@@ -879,6 +900,20 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
879
900
|
this.logger.warn(`Failed to setup static assets: ${error.message}`);
|
|
880
901
|
}
|
|
881
902
|
}
|
|
903
|
+
/**
|
|
904
|
+
* Cleanup: Close Vite server on module destroy
|
|
905
|
+
* This prevents port conflicts on hot reload
|
|
906
|
+
*/
|
|
907
|
+
async onModuleDestroy() {
|
|
908
|
+
if (this.viteServer) {
|
|
909
|
+
try {
|
|
910
|
+
await this.viteServer.close();
|
|
911
|
+
this.logger.log("\u2713 Vite server closed");
|
|
912
|
+
} catch (error) {
|
|
913
|
+
this.logger.warn(`Failed to close Vite server: ${error.message}`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
882
917
|
};
|
|
883
918
|
ViteInitializerService = _ts_decorate5([
|
|
884
919
|
common.Injectable(),
|