@canonical/react-ssr 0.22.0 → 0.24.0

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 (95) hide show
  1. package/dist/esm/bin/serve-express.js +86 -0
  2. package/dist/esm/bin/serve-express.js.map +1 -0
  3. package/dist/esm/index.js +3 -2
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/lib/adapter/index.js +2 -0
  6. package/dist/esm/lib/adapter/index.js.map +1 -0
  7. package/dist/esm/lib/adapter/mime.js +85 -0
  8. package/dist/esm/lib/adapter/mime.js.map +1 -0
  9. package/dist/esm/lib/adapter/types.js +10 -0
  10. package/dist/esm/lib/adapter/types.js.map +1 -0
  11. package/dist/esm/lib/index.js +4 -0
  12. package/dist/esm/lib/index.js.map +1 -0
  13. package/dist/esm/lib/renderer/Extractor.js +172 -0
  14. package/dist/esm/lib/renderer/Extractor.js.map +1 -0
  15. package/dist/esm/lib/renderer/JSXRenderer.js +283 -0
  16. package/dist/esm/lib/renderer/JSXRenderer.js.map +1 -0
  17. package/dist/esm/lib/renderer/SitemapRenderer.js +241 -0
  18. package/dist/esm/lib/renderer/SitemapRenderer.js.map +1 -0
  19. package/dist/esm/lib/renderer/TextRenderer.js +124 -0
  20. package/dist/esm/lib/renderer/TextRenderer.js.map +1 -0
  21. package/dist/esm/lib/renderer/constants.js.map +1 -0
  22. package/dist/esm/lib/renderer/index.js +6 -0
  23. package/dist/esm/lib/renderer/index.js.map +1 -0
  24. package/dist/esm/lib/renderer/types.js +10 -0
  25. package/dist/esm/lib/renderer/types.js.map +1 -0
  26. package/dist/esm/lib/server/index.js +3 -0
  27. package/dist/esm/lib/server/index.js.map +1 -0
  28. package/dist/esm/lib/server/serveStream.js +53 -0
  29. package/dist/esm/lib/server/serveStream.js.map +1 -0
  30. package/dist/esm/lib/server/serveString.js +49 -0
  31. package/dist/esm/lib/server/serveString.js.map +1 -0
  32. package/dist/types/bin/serve-express.d.ts +24 -0
  33. package/dist/types/bin/serve-express.d.ts.map +1 -0
  34. package/dist/types/index.d.ts +3 -2
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/lib/adapter/index.d.ts +3 -0
  37. package/dist/types/lib/adapter/index.d.ts.map +1 -0
  38. package/dist/types/lib/adapter/mime.d.ts +43 -0
  39. package/dist/types/lib/adapter/mime.d.ts.map +1 -0
  40. package/dist/types/lib/adapter/types.d.ts +85 -0
  41. package/dist/types/lib/adapter/types.d.ts.map +1 -0
  42. package/dist/types/lib/index.d.ts +4 -0
  43. package/dist/types/lib/index.d.ts.map +1 -0
  44. package/dist/types/lib/renderer/Extractor.d.ts +93 -0
  45. package/dist/types/lib/renderer/Extractor.d.ts.map +1 -0
  46. package/dist/types/lib/renderer/JSXRenderer.d.ts +163 -0
  47. package/dist/types/lib/renderer/JSXRenderer.d.ts.map +1 -0
  48. package/dist/types/lib/renderer/SitemapRenderer.d.ts +153 -0
  49. package/dist/types/lib/renderer/SitemapRenderer.d.ts.map +1 -0
  50. package/dist/types/lib/renderer/TextRenderer.d.ts +83 -0
  51. package/dist/types/lib/renderer/TextRenderer.d.ts.map +1 -0
  52. package/dist/types/lib/renderer/constants.d.ts.map +1 -0
  53. package/dist/types/lib/renderer/index.d.ts +7 -0
  54. package/dist/types/lib/renderer/index.d.ts.map +1 -0
  55. package/dist/types/lib/renderer/types.d.ts +161 -0
  56. package/dist/types/lib/renderer/types.d.ts.map +1 -0
  57. package/dist/types/lib/server/index.d.ts +3 -0
  58. package/dist/types/lib/server/index.d.ts.map +1 -0
  59. package/dist/types/lib/server/serveStream.d.ts +41 -0
  60. package/dist/types/lib/server/serveStream.d.ts.map +1 -0
  61. package/dist/types/lib/server/serveString.d.ts +37 -0
  62. package/dist/types/lib/server/serveString.d.ts.map +1 -0
  63. package/package.json +37 -17
  64. package/dist/esm/renderer/Extractor.js +0 -127
  65. package/dist/esm/renderer/Extractor.js.map +0 -1
  66. package/dist/esm/renderer/JSXRenderer.js +0 -168
  67. package/dist/esm/renderer/JSXRenderer.js.map +0 -1
  68. package/dist/esm/renderer/constants.js.map +0 -1
  69. package/dist/esm/renderer/index.js +0 -4
  70. package/dist/esm/renderer/index.js.map +0 -1
  71. package/dist/esm/renderer/types.js +0 -2
  72. package/dist/esm/renderer/types.js.map +0 -1
  73. package/dist/esm/server/index.js +0 -2
  74. package/dist/esm/server/index.js.map +0 -1
  75. package/dist/esm/server/serve-express.js +0 -58
  76. package/dist/esm/server/serve-express.js.map +0 -1
  77. package/dist/esm/server/serve.js +0 -41
  78. package/dist/esm/server/serve.js.map +0 -1
  79. package/dist/types/renderer/Extractor.d.ts +0 -68
  80. package/dist/types/renderer/Extractor.d.ts.map +0 -1
  81. package/dist/types/renderer/JSXRenderer.d.ts +0 -71
  82. package/dist/types/renderer/JSXRenderer.d.ts.map +0 -1
  83. package/dist/types/renderer/constants.d.ts.map +0 -1
  84. package/dist/types/renderer/index.d.ts +0 -5
  85. package/dist/types/renderer/index.d.ts.map +0 -1
  86. package/dist/types/renderer/types.d.ts +0 -35
  87. package/dist/types/renderer/types.d.ts.map +0 -1
  88. package/dist/types/server/index.d.ts +0 -2
  89. package/dist/types/server/index.d.ts.map +0 -1
  90. package/dist/types/server/serve-express.d.ts +0 -3
  91. package/dist/types/server/serve-express.d.ts.map +0 -1
  92. package/dist/types/server/serve.d.ts +0 -30
  93. package/dist/types/server/serve.d.ts.map +0 -1
  94. /package/dist/esm/{renderer → lib/renderer}/constants.js +0 -0
  95. /package/dist/types/{renderer → lib/renderer}/constants.d.ts +0 -0
@@ -1,127 +0,0 @@
1
- import { toCamelCase } from "@canonical/utils";
2
- import { NodeWithChildren } from "domhandler";
3
- import { parseDocument } from "htmlparser2";
4
- import React from "react";
5
- const REACT_KEYS_DICTIONARY = {
6
- class: "className",
7
- for: "htmlFor",
8
- crossorigin: "crossOrigin",
9
- charset: "charSet",
10
- };
11
- /**
12
- * Parses an HTML string to extract and convert the <head> tags to React.createElement calls.
13
- * The tags extracted are:
14
- * - title
15
- * - style
16
- * - meta
17
- * - link
18
- * - script
19
- * - base
20
- */
21
- class Extractor {
22
- /**
23
- * A document object representing the DOM of a page.
24
- */
25
- document;
26
- /**
27
- * Creates an Extractor object for a given HTML string.
28
- */
29
- constructor(html) {
30
- this.document = parseDocument(html);
31
- }
32
- /**
33
- * Searches elements with the specified tag in the document.
34
- *
35
- * @remark The method uses the parsed {@link Extractor.document | document} to navigate the
36
- * whole DOM (usinig a stack) and checks for the elements with the tag name that matches
37
- * the given parameter.
38
- */
39
- getElementsByTagName(tagName) {
40
- const elements = [];
41
- const stack = [...this.document.children];
42
- while (stack.length) {
43
- const node = stack.pop();
44
- if (!node)
45
- continue;
46
- if (node.type === "tag" && node.name === tagName) {
47
- elements.push(node);
48
- }
49
- // Check for script tags specifically
50
- if (node.type === "script" && tagName === "script") {
51
- elements.push(node);
52
- }
53
- if (node instanceof NodeWithChildren) {
54
- stack.push(...node.children);
55
- }
56
- }
57
- return elements;
58
- }
59
- /**
60
- * Converts HTML keys to React keys.
61
- *
62
- * @remark There are some HTML attributes that don't map exactly to React with the same name.
63
- * For example, class -> className.
64
- */
65
- convertKeyToReactKey(key) {
66
- const reactKey = REACT_KEYS_DICTIONARY[key.toLowerCase()];
67
- return reactKey ? reactKey : toCamelCase(key);
68
- }
69
- /**
70
- * Converts a parsed {@link domhandler#Element | DOM Element} into a {@link react#React.ReactElement | ReactElement}.
71
- *
72
- * @remark The method takes into account the attributes of the parsed {@link domhandler#Element | Element}
73
- * and passes them as props when creating the {@link react#React.ReactElement | ReactElement}.
74
- * It only handles children of type "text".
75
- */
76
- convertToReactElement(element, index) {
77
- const props = {};
78
- for (const [key, value] of Object.entries(element.attribs)) {
79
- props[this.convertKeyToReactKey(key)] = value;
80
- }
81
- // some tags from <head> have one children of type text
82
- let elementChildren;
83
- if (element.children.length === 1 && element.firstChild?.type === "text") {
84
- elementChildren = element.firstChild.data;
85
- }
86
- props.key = `${element.name}_${index}`;
87
- return React.createElement(element.name, props, elementChildren);
88
- }
89
- /**
90
- * Finds all <link> elements in the {@link Extractor.document | document} and converts them
91
- * into {@link react#React.ReactElement | ReactElements}.
92
- *
93
- * @remark The list of elements returned will be in order of appearance in the DOM.
94
- */
95
- getLinkElements() {
96
- const linkElements = this.getElementsByTagName("link");
97
- // reverse keeps the original order in the HTML (they are extracted with a stack in reverse)
98
- // the order might be important for some scripts (i.e. in Vite Dev mode)
99
- return linkElements.reverse().map(this.convertToReactElement, this);
100
- }
101
- /**
102
- * Finds all <script> elements in the {@link Extractor.document | document} and converts them
103
- * into {@link react#React.ReactElement | ReactElements}.
104
- *
105
- * @remark The list of elements returned will be in order of appearance in the DOM.
106
- */
107
- getScriptElements() {
108
- const scriptElements = this.getElementsByTagName("script");
109
- // reverse keeps the original order in the HTML (they are extracted with a stack in reverse)
110
- // the order might be important for some scripts (i.e. in Vite Dev mode)
111
- return scriptElements.reverse().map(this.convertToReactElement, this);
112
- }
113
- /**
114
- * Finds all the <head> elements which are not "script" or "link" in the {@link Extractor.document | document}
115
- * and converts them into {@link react#React.ReactElement | ReactElements}.
116
- *
117
- * @remark The list of elements returned will be in order of appearance in the DOM.
118
- */
119
- getOtherHeadElements() {
120
- const otherHeadElements = ["title", "style", "meta", "base"].flatMap((elementName) => this.getElementsByTagName(elementName));
121
- // reverse keeps the original order in the HTML (they are extracted with a stack in reverse)
122
- // the order might be important for some scripts (i.e. in Vite Dev mode)
123
- return otherHeadElements.reverse().map(this.convertToReactElement, this);
124
- }
125
- }
126
- export default Extractor;
127
- //# sourceMappingURL=Extractor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Extractor.js","sourceRoot":"","sources":["../../../src/renderer/Extractor.ts"],"names":[],"mappings":"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"}
@@ -1,168 +0,0 @@
1
- import { createElement } from "react";
2
- import { renderToPipeableStream, renderToString, } from "react-dom/server";
3
- import { INITIAL_DATA_KEY } from "./constants.js";
4
- import Extractor from "./Extractor.js";
5
- /**
6
- * This class is responsible for rendering a React JSX component and sending it as response to a client.
7
- * It offers 2 ways of doing it:
8
- * - As string
9
- * - As stream
10
- * Each way has its advantages and inconveniences. You can read more about them in the package README.
11
- */
12
- export default class JSXRenderer {
13
- Component;
14
- initialData;
15
- options;
16
- extractor;
17
- /**
18
- * Creates a renderer instance which can be used to write Server Side Rendered HTML
19
- * into a {@link node:http#ServerResponse | ServerResponse}.
20
- */
21
- constructor(Component, initialData = {}, options = {}) {
22
- this.Component = Component;
23
- this.initialData = initialData;
24
- this.options = options;
25
- this.extractor = this.options.htmlString
26
- ? new Extractor(this.options.htmlString)
27
- : undefined;
28
- }
29
- /**
30
- * Gets the locale to be used for the rendered page.
31
- * Default if there was no locale passed as option is "en".
32
- */
33
- getLocale() {
34
- return this.options.defaultLocale || "en";
35
- }
36
- /**
37
- * Gets the props needed to render the component.
38
- */
39
- getComponentProps() {
40
- return {
41
- lang: this.getLocale(),
42
- scriptElements: this.extractor?.getScriptElements(),
43
- linkElements: this.extractor?.getLinkElements(),
44
- otherHeadElements: this.extractor?.getOtherHeadElements(),
45
- initialData: this.initialData,
46
- };
47
- }
48
- /**
49
- * Gets a list of all the "src" attributes of the given scripts that match the passed type.
50
- */
51
- getScriptSourcesByType(scripts, type) {
52
- return (scripts
53
- .map((script) => script)
54
- .filter((script) => {
55
- if (type === "module") {
56
- return script.props.type === "module";
57
- }
58
- else {
59
- return script.props.type !== "module";
60
- }
61
- })
62
- .map((script) => script.props.src)
63
- .filter((src) => typeof src === "string") || []);
64
- }
65
- /**
66
- * Adds some properties to the options that are passed to {@link react-dom#renderToPipeableStream | renderToPipeableStream}.
67
- *
68
- * @remark The options that are added are:
69
- * - bootstrapScriptContent: includes the initial data passed as prop to the component in a <script> so that it
70
- * is available when rendering the page in the browser (to avoid hydration mismatches).
71
- * - bootstrapScripts: classic scripts which react strips out of the page. The only way to add them is to include them
72
- * in this property.
73
- * - bootstrapModules: module scripts which react also strips out of the page and need to be added like this.
74
- */
75
- enrichRendererOptions(props) {
76
- const enrichedOptions = { ...this.options.renderToPipeableStreamOptions };
77
- // options passed by the user always take priority
78
- if (!enrichedOptions.bootstrapScriptContent) {
79
- if (props.initialData) {
80
- enrichedOptions.bootstrapScriptContent = `window.${INITIAL_DATA_KEY} = ${JSON.stringify(props.initialData)}`;
81
- }
82
- }
83
- if (!enrichedOptions.bootstrapScripts) {
84
- if (props.scriptElements) {
85
- enrichedOptions.bootstrapScripts = this.getScriptSourcesByType(props.scriptElements, "classic");
86
- }
87
- }
88
- if (!enrichedOptions.bootstrapModules) {
89
- if (props.scriptElements) {
90
- enrichedOptions.bootstrapModules = this.getScriptSourcesByType(props.scriptElements, "module");
91
- }
92
- }
93
- return enrichedOptions;
94
- }
95
- /**
96
- * This function is responsible for rendering a React component and sending it to the client through
97
- * a pipeable stream.
98
- *
99
- * @remark See the README to understand the difference between rendering options.
100
- *
101
- * The streaming might improve the time taken for the page to be rendered and interactive
102
- * (at least in part), using React's Suspense/lazy API and pipeable streams.
103
- *
104
- * CAUTION: The resulting HTML rendered this way is not cacheable.
105
- */
106
- renderToStream = (_req, res) => {
107
- const errorRef = { current: undefined };
108
- const props = this.getComponentProps();
109
- const jsx = createElement(this.Component, props);
110
- const { onShellError: onShellErrorCallback, onShellReady: onShellReadyCallback, onAllReady: onAllReadyCallback, onError: onErrorCallback, ...options } = this.enrichRendererOptions(props);
111
- const jsxStream = renderToPipeableStream(jsx, {
112
- ...options,
113
- // Error occurred during rendering, after the shell & headers were sent - store the error for usage after stream is sent
114
- onError(error, errorInfo) {
115
- onErrorCallback?.(error, errorInfo);
116
- errorRef.current = error;
117
- console.error(error);
118
- },
119
- // Early error, before the shell is prepared
120
- onShellError(error) {
121
- onShellErrorCallback?.(error);
122
- if (!res.headersSent) {
123
- res
124
- .writeHead(500, { "Content-Type": "text/html; charset=utf-8" })
125
- .end("<h1>Something went wrong</h1>");
126
- }
127
- console.error(error);
128
- },
129
- onShellReady() {
130
- onShellReadyCallback?.();
131
- if (!res.headersSent) {
132
- res.writeHead(errorRef.current ? 500 : 200, {
133
- "Content-Type": "text/html; charset=utf-8",
134
- });
135
- }
136
- jsxStream.pipe(res);
137
- res.on("finish", () => {
138
- res.end();
139
- });
140
- },
141
- onAllReady() {
142
- onAllReadyCallback?.();
143
- },
144
- });
145
- };
146
- /**
147
- * Renders this renderer's JSX component as a string and writes it to the given
148
- * {@link node:http#ServerResponse | ServerResponse}.
149
- *
150
- * @remark See the README to understand the difference between rendering options.
151
- *
152
- * Rendering to string means all <Suspense> components are loaded synchronously and the response
153
- * won't be sent to the client until all components have finished loading data and processing.
154
- *
155
- * renderToString is useful in Vite Dev mode, as the HMR doesn't work well with Suspense
156
- * and the Pipeable Stream rendering. Also if the resulting document needs to be cached.
157
- */
158
- renderToString = (_req, res) => {
159
- const props = this.getComponentProps();
160
- const jsx = createElement(this.Component, props);
161
- const html = renderToString(jsx);
162
- res
163
- .writeHead(200, { "Content-Type": "text/html; charset=utf-8" })
164
- .write(html);
165
- res.end();
166
- };
167
- }
168
- //# sourceMappingURL=JSXRenderer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"JSXRenderer.js","sourceRoot":"","sources":["../../../src/renderer/JSXRenderer.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/renderer/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC"}
@@ -1,4 +0,0 @@
1
- export * from "./constants.js";
2
- export { default as Extractor } from "./Extractor.js";
3
- export { default as JSXRenderer } from "./JSXRenderer.js";
4
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/renderer/types.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export * from "./serve.js";
2
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env node
2
- import path from "node:path";
3
- import { parseArgs } from "node:util";
4
- import express from "express";
5
- import { serveStream } from "./serve.js";
6
- const { values, positionals } = parseArgs({
7
- args: process.argv.slice(2),
8
- options: {
9
- port: {
10
- type: "string",
11
- alias: "p",
12
- default: "5173",
13
- },
14
- staticFilepath: {
15
- type: "string",
16
- alias: "s",
17
- default: "dist/client/assets",
18
- },
19
- staticRoute: {
20
- type: "string",
21
- alias: "r",
22
- default: "assets",
23
- },
24
- streaming: {
25
- type: "boolean",
26
- default: false,
27
- },
28
- },
29
- strict: true,
30
- allowPositionals: true,
31
- });
32
- const port = values.port || 5173;
33
- const cwd = process.cwd();
34
- const rendererFilePath = path.join(cwd, positionals[0]);
35
- const staticDir = path.join(cwd, values.staticFilepath || "assets");
36
- const staticRoute = values.staticRoute || "assets";
37
- if (!rendererFilePath) {
38
- console.error("Usage: node server.js <renderer-path>");
39
- process.exit(1);
40
- }
41
- const handler = await import(rendererFilePath).then((module) => {
42
- if (values.streaming) {
43
- return module.default.renderToStream;
44
- }
45
- else {
46
- return module.default.renderToString;
47
- }
48
- });
49
- if (typeof handler !== "function") {
50
- throw new Error("Renderer file must default-export a renderer function.");
51
- }
52
- const app = express();
53
- app.use(`/${staticRoute}`, express.static(staticDir));
54
- app.use(serveStream(handler));
55
- app.listen(port, () => {
56
- console.log(`Server started on http://localhost:${port}/`);
57
- });
58
- //# sourceMappingURL=serve-express.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-express.js","sourceRoot":"","sources":["../../../src/server/serve-express.ts"],"names":[],"mappings":";AAEA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACxC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,OAAO,EAAE,MAAM;SAChB;QACD,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,OAAO,EAAE,oBAAoB;SAC9B;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,GAAG;YACV,OAAO,EAAE,QAAQ;SAClB;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;SACf;KACF;IACD,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,IAAI;CACvB,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;AACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,IAAI,QAAQ,CAAC,CAAC;AACpE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC;AAEnD,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAkB,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;IAC5E,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;IACvC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;IAClC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AACtD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAE9B,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACpB,OAAO,CAAC,GAAG,CAAC,sCAAsC,IAAI,GAAG,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC"}
@@ -1,41 +0,0 @@
1
- /**
2
- * Execute a request handler that renders a React component to a stream, then streams it back to the client.
3
- * This function should be used as a request controller in an HTTP server.
4
- * @param handler A request handler that renders a React component to a stream.
5
- * @throws Error if the handler throws an error during rendering.
6
- * @returns The stream generated by the handler
7
- * @example ```ts
8
- * import express from "express";
9
- * import { serveStream } from "@canonical/react-ssr/server";
10
- * import { JSXRenderer } from "@canonical/react-ssr/renderer";
11
- * // htmlString is created by some build process that bundles the client code
12
- * import htmlString from "../../dist/client/index.html?raw";
13
- * import EntryServer from "./entry-server.js";
14
- *
15
- * // `EntryServer` is an instance of `@canonical/react-ssr/renderer/ServerEntrypoint`
16
- * const Renderer = new JSXRenderer(EntryServer, {
17
- * htmlString,
18
- * });
19
- *
20
- * const ssrHandler = Renderer.render;
21
- *
22
- * const app = express();
23
- *
24
- * app.use("/(assets|public)", express.static("dist/client/assets"));
25
- * app.use(serveStream(ssrHandler));
26
- */
27
- export function serveStream(handler) {
28
- return (req, res) => {
29
- try {
30
- res.setHeader("Content-Type", "text/html");
31
- res.setHeader("Transfer-Encoding", "chunked");
32
- handler(req, res);
33
- }
34
- catch (error) {
35
- console.error("Error during rendering:", error);
36
- res.statusCode = 500;
37
- res.end("Internal server error");
38
- }
39
- };
40
- }
41
- //# sourceMappingURL=serve.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/server/serve.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,OAAO,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;QACnD,IAAI,CAAC;YACH,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;YAC3C,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1,68 +0,0 @@
1
- import { type Document, type Element } from "domhandler";
2
- import React from "react";
3
- /**
4
- * Parses an HTML string to extract and convert the <head> tags to React.createElement calls.
5
- * The tags extracted are:
6
- * - title
7
- * - style
8
- * - meta
9
- * - link
10
- * - script
11
- * - base
12
- */
13
- declare class Extractor {
14
- /**
15
- * A document object representing the DOM of a page.
16
- */
17
- protected readonly document: Document;
18
- /**
19
- * Creates an Extractor object for a given HTML string.
20
- */
21
- constructor(html: string);
22
- /**
23
- * Searches elements with the specified tag in the document.
24
- *
25
- * @remark The method uses the parsed {@link Extractor.document | document} to navigate the
26
- * whole DOM (usinig a stack) and checks for the elements with the tag name that matches
27
- * the given parameter.
28
- */
29
- protected getElementsByTagName(tagName: string): Element[];
30
- /**
31
- * Converts HTML keys to React keys.
32
- *
33
- * @remark There are some HTML attributes that don't map exactly to React with the same name.
34
- * For example, class -> className.
35
- */
36
- protected convertKeyToReactKey(key: string): string;
37
- /**
38
- * Converts a parsed {@link domhandler#Element | DOM Element} into a {@link react#React.ReactElement | ReactElement}.
39
- *
40
- * @remark The method takes into account the attributes of the parsed {@link domhandler#Element | Element}
41
- * and passes them as props when creating the {@link react#React.ReactElement | ReactElement}.
42
- * It only handles children of type "text".
43
- */
44
- protected convertToReactElement(element: Element, index: number): React.ReactElement;
45
- /**
46
- * Finds all <link> elements in the {@link Extractor.document | document} and converts them
47
- * into {@link react#React.ReactElement | ReactElements}.
48
- *
49
- * @remark The list of elements returned will be in order of appearance in the DOM.
50
- */
51
- getLinkElements(): React.ReactElement[];
52
- /**
53
- * Finds all <script> elements in the {@link Extractor.document | document} and converts them
54
- * into {@link react#React.ReactElement | ReactElements}.
55
- *
56
- * @remark The list of elements returned will be in order of appearance in the DOM.
57
- */
58
- getScriptElements(): React.ReactElement[];
59
- /**
60
- * Finds all the <head> elements which are not "script" or "link" in the {@link Extractor.document | document}
61
- * and converts them into {@link react#React.ReactElement | ReactElements}.
62
- *
63
- * @remark The list of elements returned will be in order of appearance in the DOM.
64
- */
65
- getOtherHeadElements(): React.ReactElement[];
66
- }
67
- export default Extractor;
68
- //# sourceMappingURL=Extractor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Extractor.d.ts","sourceRoot":"","sources":["../../../src/renderer/Extractor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAoB,MAAM,YAAY,CAAC;AAE3E,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B;;;;;;;;;GASG;AACH,cAAM,SAAS;IACb;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAEtC;;OAEG;gBACS,IAAI,EAAE,MAAM;IAIxB;;;;;;OAMG;IACH,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE;IAwB1D;;;;;OAKG;IACH,SAAS,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKnD;;;;;;OAMG;IACH,SAAS,CAAC,qBAAqB,CAC7B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC,YAAY;IAiBrB;;;;;OAKG;IACI,eAAe,IAAI,KAAK,CAAC,YAAY,EAAE;IAO9C;;;;;OAKG;IACI,iBAAiB,IAAI,KAAK,CAAC,YAAY,EAAE;IAOhD;;;;;OAKG;IACI,oBAAoB,IAAI,KAAK,CAAC,YAAY,EAAE;CAQpD;AAED,eAAe,SAAS,CAAC"}
@@ -1,71 +0,0 @@
1
- import { type RenderToPipeableStreamOptions } from "react-dom/server";
2
- import Extractor from "./Extractor.js";
3
- import type { RendererOptions, RenderHandler, ServerEntrypoint, ServerEntrypointProps } from "./types.js";
4
- /**
5
- * This class is responsible for rendering a React JSX component and sending it as response to a client.
6
- * It offers 2 ways of doing it:
7
- * - As string
8
- * - As stream
9
- * Each way has its advantages and inconveniences. You can read more about them in the package README.
10
- */
11
- export default class JSXRenderer<TComponent extends ServerEntrypoint<InitialData>, InitialData extends Record<string, unknown>> {
12
- protected readonly Component: TComponent;
13
- protected readonly initialData: InitialData;
14
- protected readonly options: RendererOptions;
15
- protected extractor: Extractor | undefined;
16
- /**
17
- * Creates a renderer instance which can be used to write Server Side Rendered HTML
18
- * into a {@link node:http#ServerResponse | ServerResponse}.
19
- */
20
- constructor(Component: TComponent, initialData?: InitialData, options?: RendererOptions);
21
- /**
22
- * Gets the locale to be used for the rendered page.
23
- * Default if there was no locale passed as option is "en".
24
- */
25
- getLocale(): string;
26
- /**
27
- * Gets the props needed to render the component.
28
- */
29
- protected getComponentProps(): ServerEntrypointProps<InitialData>;
30
- /**
31
- * Gets a list of all the "src" attributes of the given scripts that match the passed type.
32
- */
33
- protected getScriptSourcesByType(scripts: React.ReactElement[], type: "module" | "classic"): string[];
34
- /**
35
- * Adds some properties to the options that are passed to {@link react-dom#renderToPipeableStream | renderToPipeableStream}.
36
- *
37
- * @remark The options that are added are:
38
- * - bootstrapScriptContent: includes the initial data passed as prop to the component in a <script> so that it
39
- * is available when rendering the page in the browser (to avoid hydration mismatches).
40
- * - bootstrapScripts: classic scripts which react strips out of the page. The only way to add them is to include them
41
- * in this property.
42
- * - bootstrapModules: module scripts which react also strips out of the page and need to be added like this.
43
- */
44
- protected enrichRendererOptions(props: ServerEntrypointProps<InitialData>): RenderToPipeableStreamOptions;
45
- /**
46
- * This function is responsible for rendering a React component and sending it to the client through
47
- * a pipeable stream.
48
- *
49
- * @remark See the README to understand the difference between rendering options.
50
- *
51
- * The streaming might improve the time taken for the page to be rendered and interactive
52
- * (at least in part), using React's Suspense/lazy API and pipeable streams.
53
- *
54
- * CAUTION: The resulting HTML rendered this way is not cacheable.
55
- */
56
- renderToStream: RenderHandler;
57
- /**
58
- * Renders this renderer's JSX component as a string and writes it to the given
59
- * {@link node:http#ServerResponse | ServerResponse}.
60
- *
61
- * @remark See the README to understand the difference between rendering options.
62
- *
63
- * Rendering to string means all <Suspense> components are loaded synchronously and the response
64
- * won't be sent to the client until all components have finished loading data and processing.
65
- *
66
- * renderToString is useful in Vite Dev mode, as the HMR doesn't work well with Suspense
67
- * and the Pipeable Stream rendering. Also if the resulting document needs to be cached.
68
- */
69
- renderToString: RenderHandler;
70
- }
71
- //# sourceMappingURL=JSXRenderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"JSXRenderer.d.ts","sourceRoot":"","sources":["../../../src/renderer/JSXRenderer.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,6BAA6B,EAGnC,MAAM,kBAAkB,CAAC;AAE1B,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EAEb,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW,CAC9B,UAAU,SAAS,gBAAgB,CAAC,WAAW,CAAC,EAChD,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IASzC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU;IACxC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW;IAC3C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe;IAT7C,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IAE3C;;;OAGG;gBAEkB,SAAS,EAAE,UAAU,EACrB,WAAW,GAAE,WAA+B,EAC5C,OAAO,GAAE,eAAoB;IAOlD;;;OAGG;IACI,SAAS,IAAI,MAAM;IAI1B;;OAEG;IACH,SAAS,CAAC,iBAAiB,IAAI,qBAAqB,CAAC,WAAW,CAAC;IAUjE;;OAEG;IACH,SAAS,CAAC,sBAAsB,CAC9B,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,EAC7B,IAAI,EAAE,QAAQ,GAAG,SAAS,GACzB,MAAM,EAAE;IAsBX;;;;;;;;;OASG;IACH,SAAS,CAAC,qBAAqB,CAC7B,KAAK,EAAE,qBAAqB,CAAC,WAAW,CAAC,GACxC,6BAA6B;IA6BhC;;;;;;;;;;OAUG;IACH,cAAc,EAAE,aAAa,CAqD3B;IAEF;;;;;;;;;;;OAWG;IACH,cAAc,EAAE,aAAa,CAW3B;CACH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/renderer/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,qBAAqB,CAAC"}
@@ -1,5 +0,0 @@
1
- export * from "./constants.js";
2
- export { default as Extractor } from "./Extractor.js";
3
- export { default as JSXRenderer } from "./JSXRenderer.js";
4
- export type { RendererOptions, RenderHandler, RenderResult, ServerEntrypoint, ServerEntrypointProps, } from "./types.js";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -1,35 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from "node:http";
2
- import type * as React from "react";
3
- import type { PipeableStream, RenderToPipeableStreamOptions } from "react-dom/server";
4
- export interface RendererOptions {
5
- defaultLocale?: string;
6
- /** An HTML string to extract the head tags from */
7
- htmlString?: string;
8
- /**
9
- * Options to pass to `react-dom/server.renderToPipeableStream`.
10
- * See https://react.dev/reference/react-dom/server/renderToPipeableStream#parameters.
11
- */
12
- renderToPipeableStreamOptions?: RenderToPipeableStreamOptions;
13
- }
14
- /** The props that the server entrypoint component will receive */
15
- export interface ServerEntrypointProps<InitialData extends Record<string, unknown>> {
16
- /** The language of the page. This is typically read from the request headers. */
17
- lang?: string;
18
- /** The script tags to include in the page */
19
- scriptElements?: React.ReactElement[];
20
- /** The link tags to include in the page */
21
- linkElements?: React.ReactElement[];
22
- /** Other head elements: title, base, style & meta */
23
- otherHeadElements?: React.ReactElement[];
24
- /**
25
- * Initial data used in the server to render the React application, which needs to be
26
- * embedded in the resulting HTML so that the hydration in the client matches that of the server.
27
- */
28
- initialData?: InitialData;
29
- }
30
- export type ServerEntrypoint<InitialData extends Record<string, unknown>> = React.ComponentType<ServerEntrypointProps<InitialData>>;
31
- /** The result of rendering a React component */
32
- export type RenderResult = PipeableStream;
33
- /** A function that renders a React component */
34
- export type RenderHandler = (req: IncomingMessage, res: ServerResponse) => void;
35
- //# sourceMappingURL=types.d.ts.map