@happy-dom/server-renderer 19.0.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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/bin/lib/happy-dom-sr.d.ts +3 -0
  4. package/bin/lib/happy-dom-sr.d.ts.map +1 -0
  5. package/bin/lib/happy-dom-sr.js +25 -0
  6. package/bin/lib/happy-dom-sr.js.map +1 -0
  7. package/bin/src/happy-dom-sr.ts +30 -0
  8. package/lib/ServerRenderer.d.ts +36 -0
  9. package/lib/ServerRenderer.d.ts.map +1 -0
  10. package/lib/ServerRenderer.js +270 -0
  11. package/lib/ServerRenderer.js.map +1 -0
  12. package/lib/ServerRendererBrowser.d.ts +26 -0
  13. package/lib/ServerRendererBrowser.d.ts.map +1 -0
  14. package/lib/ServerRendererBrowser.js +244 -0
  15. package/lib/ServerRendererBrowser.js.map +1 -0
  16. package/lib/ServerRendererServer.d.ts +22 -0
  17. package/lib/ServerRendererServer.d.ts.map +1 -0
  18. package/lib/ServerRendererServer.js +263 -0
  19. package/lib/ServerRendererServer.js.map +1 -0
  20. package/lib/ServerRendererWorker.d.ts +10 -0
  21. package/lib/ServerRendererWorker.d.ts.map +1 -0
  22. package/lib/ServerRendererWorker.js +25 -0
  23. package/lib/ServerRendererWorker.js.map +1 -0
  24. package/lib/config/DefaultServerRendererConfiguration.d.ts +4 -0
  25. package/lib/config/DefaultServerRendererConfiguration.d.ts.map +1 -0
  26. package/lib/config/DefaultServerRendererConfiguration.js +40 -0
  27. package/lib/config/DefaultServerRendererConfiguration.js.map +1 -0
  28. package/lib/enums/ServerRendererLogLevelEnum.d.ts +9 -0
  29. package/lib/enums/ServerRendererLogLevelEnum.d.ts.map +1 -0
  30. package/lib/enums/ServerRendererLogLevelEnum.js +10 -0
  31. package/lib/enums/ServerRendererLogLevelEnum.js.map +1 -0
  32. package/lib/index.d.ts +9 -0
  33. package/lib/index.d.ts.map +1 -0
  34. package/lib/index.js +5 -0
  35. package/lib/index.js.map +1 -0
  36. package/lib/types/IOptionalServerRendererConfiguration.d.ts +108 -0
  37. package/lib/types/IOptionalServerRendererConfiguration.d.ts.map +1 -0
  38. package/lib/types/IOptionalServerRendererConfiguration.js +2 -0
  39. package/lib/types/IOptionalServerRendererConfiguration.js.map +1 -0
  40. package/lib/types/IServerRendererConfiguration.d.ts +108 -0
  41. package/lib/types/IServerRendererConfiguration.d.ts.map +1 -0
  42. package/lib/types/IServerRendererConfiguration.js +2 -0
  43. package/lib/types/IServerRendererConfiguration.js.map +1 -0
  44. package/lib/types/IServerRendererItem.d.ts +8 -0
  45. package/lib/types/IServerRendererItem.d.ts.map +1 -0
  46. package/lib/types/IServerRendererItem.js +2 -0
  47. package/lib/types/IServerRendererItem.js.map +1 -0
  48. package/lib/types/IServerRendererResult.d.ts +14 -0
  49. package/lib/types/IServerRendererResult.d.ts.map +1 -0
  50. package/lib/types/IServerRendererResult.js +2 -0
  51. package/lib/types/IServerRendererResult.js.map +1 -0
  52. package/lib/utilities/BrowserWindowPolyfill.d.ts +13 -0
  53. package/lib/utilities/BrowserWindowPolyfill.d.ts.map +1 -0
  54. package/lib/utilities/BrowserWindowPolyfill.js +92 -0
  55. package/lib/utilities/BrowserWindowPolyfill.js.map +1 -0
  56. package/lib/utilities/HelpPrinter.d.ts +10 -0
  57. package/lib/utilities/HelpPrinter.d.ts.map +1 -0
  58. package/lib/utilities/HelpPrinter.js +32 -0
  59. package/lib/utilities/HelpPrinter.js.map +1 -0
  60. package/lib/utilities/HelpPrinterRows.d.ts +3 -0
  61. package/lib/utilities/HelpPrinterRows.d.ts.map +1 -0
  62. package/lib/utilities/HelpPrinterRows.js +261 -0
  63. package/lib/utilities/HelpPrinterRows.js.map +1 -0
  64. package/lib/utilities/PackageVersion.d.ts +10 -0
  65. package/lib/utilities/PackageVersion.d.ts.map +1 -0
  66. package/lib/utilities/PackageVersion.js +13 -0
  67. package/lib/utilities/PackageVersion.js.map +1 -0
  68. package/lib/utilities/ProcessArgumentsParser.d.ts +20 -0
  69. package/lib/utilities/ProcessArgumentsParser.d.ts.map +1 -0
  70. package/lib/utilities/ProcessArgumentsParser.js +319 -0
  71. package/lib/utilities/ProcessArgumentsParser.js.map +1 -0
  72. package/lib/utilities/ServerRendererConfigurationFactory.d.ts +23 -0
  73. package/lib/utilities/ServerRendererConfigurationFactory.d.ts.map +1 -0
  74. package/lib/utilities/ServerRendererConfigurationFactory.js +82 -0
  75. package/lib/utilities/ServerRendererConfigurationFactory.js.map +1 -0
  76. package/package.json +61 -0
  77. package/src/ServerRenderer.ts +345 -0
  78. package/src/ServerRendererBrowser.ts +286 -0
  79. package/src/ServerRendererServer.ts +337 -0
  80. package/src/ServerRendererWorker.ts +29 -0
  81. package/src/config/DefaultServerRendererConfiguration.ts +41 -0
  82. package/src/enums/ServerRendererLogLevelEnum.ts +9 -0
  83. package/src/index.ts +17 -0
  84. package/src/types/IOptionalServerRendererConfiguration.ts +108 -0
  85. package/src/types/IServerRendererConfiguration.ts +108 -0
  86. package/src/types/IServerRendererItem.ts +5 -0
  87. package/src/types/IServerRendererResult.ts +11 -0
  88. package/src/utilities/BrowserWindowPolyfill.ts +93 -0
  89. package/src/utilities/HelpPrinter.ts +36 -0
  90. package/src/utilities/HelpPrinterRows.ts +260 -0
  91. package/src/utilities/PackageVersion.ts +12 -0
  92. package/src/utilities/ProcessArgumentsParser.ts +294 -0
  93. package/src/utilities/ServerRendererConfigurationFactory.ts +91 -0
@@ -0,0 +1,244 @@
1
+ import Browser from 'happy-dom/lib/browser/Browser.js';
2
+ import HTMLSerializer from 'happy-dom/lib/html-serializer/HTMLSerializer.js';
3
+ import FS from 'fs';
4
+ import Path from 'path';
5
+ import BrowserWindowPolyfill from './utilities/BrowserWindowPolyfill.js';
6
+ /**
7
+ * Server renderer browser.
8
+ */
9
+ export default class ServerRendererBrowser {
10
+ #configuration;
11
+ #browser;
12
+ #isCacheLoaded = false;
13
+ #createdDirectories = new Set();
14
+ /**
15
+ * Constructor.
16
+ *
17
+ * @param configuration Configuration.
18
+ */
19
+ constructor(configuration) {
20
+ this.#configuration = configuration;
21
+ const settings = configuration.debug && configuration.browser.debug?.traceWaitUntilComplete === -1
22
+ ? {
23
+ ...configuration.browser,
24
+ debug: {
25
+ ...configuration.browser.debug,
26
+ traceWaitUntilComplete: configuration.render.timeout
27
+ }
28
+ }
29
+ : configuration.browser;
30
+ this.#browser = new Browser({ settings });
31
+ }
32
+ /**
33
+ * Renders URLs.
34
+ *
35
+ * @param items Items.
36
+ */
37
+ async render(items) {
38
+ const browser = this.#browser;
39
+ await this.#loadCache(browser);
40
+ let results;
41
+ if (items.length > this.#configuration.render.maxConcurrency) {
42
+ results = [];
43
+ while (items.length) {
44
+ const chunk = items.splice(0, this.#configuration.render.maxConcurrency);
45
+ const promises = [];
46
+ for (const url of chunk) {
47
+ promises.push(this.#renderURL(browser, url).then((result) => {
48
+ results.push(result);
49
+ }));
50
+ }
51
+ await Promise.all(promises);
52
+ }
53
+ }
54
+ else {
55
+ const promises = [];
56
+ for (const url of items) {
57
+ promises.push(this.#renderURL(browser, url));
58
+ }
59
+ results = await Promise.all(promises);
60
+ }
61
+ await this.#saveCache(browser);
62
+ return results;
63
+ }
64
+ /**
65
+ * Closes the browser.
66
+ */
67
+ async close() {
68
+ await this.#browser.close();
69
+ this.#browser = null;
70
+ this.#isCacheLoaded = false;
71
+ }
72
+ /**
73
+ * Renders a page.
74
+ *
75
+ * @param browser Browser.
76
+ * @param item Item.
77
+ */
78
+ async #renderURL(browser, item) {
79
+ const responseCache = browser.defaultContext.responseCache;
80
+ const preflightResponseCache = browser.defaultContext.preflightResponseCache;
81
+ const configuration = this.#configuration;
82
+ const context = configuration.render.incognitoContext || configuration.cache.disable
83
+ ? browser.newIncognitoContext()
84
+ : browser.defaultContext;
85
+ const page = context.newPage();
86
+ if (configuration.render.incognitoContext && !configuration.cache.disable) {
87
+ // @ts-ignore
88
+ context.responseCache = responseCache;
89
+ // @ts-ignore
90
+ context.preflightResponseCache = preflightResponseCache;
91
+ }
92
+ const pageErrors = [];
93
+ const response = (await page.goto(item.url, {
94
+ timeout: configuration.render.timeout,
95
+ headers: item.headers,
96
+ beforeContentCallback(window) {
97
+ window.addEventListener('error', (event) => {
98
+ if (event.error) {
99
+ pageErrors.push(event.error.stack);
100
+ }
101
+ });
102
+ if (!configuration.render.disablePolyfills) {
103
+ BrowserWindowPolyfill.applyPolyfills(window);
104
+ }
105
+ }
106
+ }));
107
+ const headers = {};
108
+ for (const [key, value] of response.headers) {
109
+ if (key !== 'content-encoding') {
110
+ headers[key] = value;
111
+ }
112
+ }
113
+ if (!response.ok) {
114
+ const pageConsole = page.virtualConsolePrinter.readAsString();
115
+ await page.close();
116
+ return {
117
+ url: item.url,
118
+ content: null,
119
+ status: response.status,
120
+ statusText: response.statusText,
121
+ headers,
122
+ outputFile: item.outputFile ?? null,
123
+ error: `Failed to render page ${item.url} (${response.status} ${response.statusText})`,
124
+ pageConsole,
125
+ pageErrors
126
+ };
127
+ }
128
+ let timeoutError = null;
129
+ const timeout = this.#browser.settings.debug.traceWaitUntilComplete === -1
130
+ ? setTimeout(() => {
131
+ timeoutError = `The page was not rendered within the defined time of ${configuration.render.timeout}ms and the operation was aborted. You can increase this value with the "render.timeout" setting.\n\nThe page may contain scripts with timer loops that prevent it from completing. You can debug open handles by setting "debug" to true, or prevent timer loops by setting "browser.timer.preventTimerLoops" to true. Read more about this in the documentation.`;
132
+ page.abort();
133
+ }, configuration.render.timeout)
134
+ : null;
135
+ try {
136
+ await page.waitUntilComplete();
137
+ }
138
+ catch (error) {
139
+ const pageConsole = page.virtualConsolePrinter.readAsString();
140
+ await page.close();
141
+ return {
142
+ url: item.url,
143
+ content: null,
144
+ status: response.status,
145
+ statusText: response.statusText,
146
+ headers,
147
+ outputFile: item.outputFile ?? null,
148
+ error: error.stack,
149
+ pageConsole,
150
+ pageErrors
151
+ };
152
+ }
153
+ // Wait for errors to be printed
154
+ await new Promise((resolve) => setTimeout(resolve, 10));
155
+ if (timeout) {
156
+ clearTimeout(timeout);
157
+ }
158
+ const pageConsole = page.virtualConsolePrinter.readAsString();
159
+ if (timeoutError) {
160
+ page.close();
161
+ return {
162
+ url: item.url,
163
+ content: null,
164
+ status: response.status,
165
+ statusText: response.statusText,
166
+ headers,
167
+ outputFile: null,
168
+ error: timeoutError,
169
+ pageConsole,
170
+ pageErrors
171
+ };
172
+ }
173
+ const serializer = new HTMLSerializer({
174
+ allShadowRoots: configuration.render.allShadowRoots,
175
+ serializableShadowRoots: configuration.render.serializableShadowRoots,
176
+ excludeShadowRootTags: configuration.render.excludeShadowRootTags
177
+ });
178
+ const result = serializer.serializeToString(page.mainFrame.document);
179
+ await page.close();
180
+ if (!item.outputFile) {
181
+ return {
182
+ url: item.url,
183
+ content: result,
184
+ status: response.status,
185
+ statusText: response.statusText,
186
+ headers,
187
+ outputFile: null,
188
+ error: null,
189
+ pageConsole,
190
+ pageErrors
191
+ };
192
+ }
193
+ const directory = Path.dirname(item.outputFile);
194
+ if (!this.#createdDirectories.has(directory)) {
195
+ this.#createdDirectories.add(directory);
196
+ try {
197
+ await FS.promises.mkdir(directory, {
198
+ recursive: true
199
+ });
200
+ }
201
+ catch {
202
+ // Ignore
203
+ }
204
+ }
205
+ await FS.promises.writeFile(item.outputFile, result);
206
+ return {
207
+ url: item.url,
208
+ content: null,
209
+ status: response.status,
210
+ statusText: response.statusText,
211
+ headers,
212
+ outputFile: item.outputFile,
213
+ error: null,
214
+ pageConsole,
215
+ pageErrors
216
+ };
217
+ }
218
+ /**
219
+ * Loads cache from disk.
220
+ *
221
+ * @param browser Browser.
222
+ */
223
+ async #loadCache(browser) {
224
+ if (this.#configuration.cache.disable ||
225
+ !this.#configuration.cache.directory ||
226
+ this.#isCacheLoaded) {
227
+ return;
228
+ }
229
+ this.#isCacheLoaded = true;
230
+ await browser.defaultContext.responseCache.fileSystem.load(this.#configuration.cache.directory);
231
+ }
232
+ /**
233
+ * Saves cache to disk.
234
+ *
235
+ * @param browser Browser.
236
+ */
237
+ async #saveCache(browser) {
238
+ if (this.#configuration.cache.disable || !this.#configuration.cache.directory) {
239
+ return;
240
+ }
241
+ await browser.defaultContext.responseCache.fileSystem.save(this.#configuration.cache.directory);
242
+ }
243
+ }
244
+ //# sourceMappingURL=ServerRendererBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerRendererBrowser.js","sourceRoot":"","sources":["../src/ServerRendererBrowser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import IOptionalServerRendererConfiguration from './types/IOptionalServerRendererConfiguration.js';
2
+ /**
3
+ * Server renderer proxy HTTP2 server.
4
+ */
5
+ export default class ServerRendererServer {
6
+ #private;
7
+ /**
8
+ * Constructor.
9
+ *
10
+ * @param configuration Configuration.
11
+ */
12
+ constructor(configuration?: IOptionalServerRendererConfiguration);
13
+ /**
14
+ * Starts the server.
15
+ */
16
+ start(): Promise<void>;
17
+ /**
18
+ * Stops the server.
19
+ */
20
+ stop(): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=ServerRendererServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerRendererServer.d.ts","sourceRoot":"","sources":["../src/ServerRendererServer.ts"],"names":[],"mappings":"AACA,OAAO,oCAAoC,MAAM,iDAAiD,CAAC;AAcnG;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;;IAgBxC;;;;OAIG;gBACS,aAAa,CAAC,EAAE,oCAAoC;IAKhE;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+DnC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA+NlC"}
@@ -0,0 +1,263 @@
1
+ import Http2 from 'http2';
2
+ import ServerRendererConfigurationFactory from './utilities/ServerRendererConfigurationFactory.js';
3
+ import ServerRenderer from './ServerRenderer.js';
4
+ import FetchHTTPSCertificate from 'happy-dom/lib/fetch/certificate/FetchHTTPSCertificate.js';
5
+ import ZLib from 'node:zlib';
6
+ import Stream from 'node:stream/promises';
7
+ import OS from 'node:os';
8
+ // eslint-disable-next-line import/no-named-as-default
9
+ import Chalk from 'chalk';
10
+ import ServerRendererLogLevelEnum from './enums/ServerRendererLogLevelEnum.js';
11
+ import PackageVersion from './utilities/PackageVersion.js';
12
+ /**
13
+ * Server renderer proxy HTTP2 server.
14
+ */
15
+ export default class ServerRendererServer {
16
+ #configuration;
17
+ #serverRenderer;
18
+ #server = null;
19
+ #cache = new Map();
20
+ #cacheQueue = new Map();
21
+ /**
22
+ * Constructor.
23
+ *
24
+ * @param configuration Configuration.
25
+ */
26
+ constructor(configuration) {
27
+ this.#configuration = ServerRendererConfigurationFactory.createConfiguration(configuration);
28
+ this.#serverRenderer = new ServerRenderer(this.#configuration);
29
+ }
30
+ /**
31
+ * Starts the server.
32
+ */
33
+ async start() {
34
+ let url;
35
+ try {
36
+ url = new URL(this.#configuration.server.serverURL);
37
+ }
38
+ catch (error) {
39
+ throw new Error('Failed to start server. The setting "server.serverURL" is not a valid URL.');
40
+ }
41
+ if (!this.#configuration.server.targetOrigin) {
42
+ throw new Error('Failed to start server. The setting "server.targetOrigin" is not set.');
43
+ }
44
+ let targetOrigin;
45
+ try {
46
+ targetOrigin = new URL(this.#configuration.server.targetOrigin);
47
+ }
48
+ catch (error) {
49
+ throw new Error('Failed to start server. The setting "server.targetOrigin" is not a valid URL.');
50
+ }
51
+ switch (url.protocol) {
52
+ case 'http:':
53
+ this.#server = Http2.createServer((request, response) => this.#onIncomingRequest(request, response));
54
+ break;
55
+ case 'https:':
56
+ this.#server = Http2.createSecureServer({
57
+ key: FetchHTTPSCertificate.key,
58
+ cert: FetchHTTPSCertificate.cert
59
+ }, (request, response) => this.#onIncomingRequest(request, response));
60
+ break;
61
+ default:
62
+ throw new Error(`Unsupported protocol "${url.protocol}". Only "http:" and "https:" are supported.`);
63
+ }
64
+ this.#server.listen(url.port ? Number(url.port) : url.protocol === 'https:' ? 443 : 80);
65
+ // eslint-disable-next-line no-console
66
+ console.log(Chalk.green(`\nHappy DOM Proxy Server ${await PackageVersion.getVersion()}\n`));
67
+ // eslint-disable-next-line no-console
68
+ console.log(` ${Chalk.green('➜')} ${Chalk.bold('Local:')} ${Chalk.cyan(`${url.protocol}//localhost:${url.port}/`)}\n ${Chalk.green('➜')} ${Chalk.bold('Network:')} ${Chalk.cyan(`${url.protocol}//${this.#getNetworkIP()}:${url.port}/`)}\n ${Chalk.green('➜')} ${Chalk.bold('Target:')} ${Chalk.cyan(`${targetOrigin.protocol}//${targetOrigin.host}/`)}\n\n ${Chalk.green('➜')} ${Chalk.bold('URL:')} ${Chalk.cyan(`${url.protocol}//localhost:${url.port}${url.pathname}${url.search}${url.hash}`)}\n`);
69
+ }
70
+ /**
71
+ * Stops the server.
72
+ */
73
+ async stop() {
74
+ if (this.#server) {
75
+ this.#server.close();
76
+ }
77
+ if (this.#serverRenderer) {
78
+ await this.#serverRenderer.close();
79
+ }
80
+ }
81
+ /**
82
+ * Triggered on incoming request.
83
+ *
84
+ * @param request Request.
85
+ * @param response Response.
86
+ * @returns Promise.
87
+ */
88
+ async #onIncomingRequest(request, response) {
89
+ const url = new URL(request.url, this.#configuration.server.targetOrigin);
90
+ const headers = {};
91
+ for (const name of Object.keys(request.headers)) {
92
+ if (name[0] !== ':' && name.toLowerCase() !== 'transfer-encoding') {
93
+ headers[name] = Array.isArray(request.headers[name])
94
+ ? request.headers[name].join(', ')
95
+ : request.headers[name];
96
+ }
97
+ }
98
+ const fetchResponse = await fetch(url.href, { headers });
99
+ const isCacheEnabled = !this.#configuration.server.disableCache && this.#configuration.server.cacheTime > 0;
100
+ const isCacheQueueEnabled = isCacheEnabled && !this.#configuration.server.disableCacheQueue;
101
+ const cacheKey = this.#getCacheKey(url, headers, fetchResponse.status);
102
+ let result = null;
103
+ response.statusCode = fetchResponse.status;
104
+ // HTML files should be served from the server renderer.
105
+ if (fetchResponse.headers.get('content-type')?.startsWith('text/html') &&
106
+ fetchResponse.status === 200) {
107
+ if (isCacheEnabled) {
108
+ const cached = this.#cache.get(cacheKey);
109
+ if (cached) {
110
+ if (Date.now() - cached.timestamp < this.#configuration.server.cacheTime) {
111
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.info) {
112
+ // eslint-disable-next-line no-console
113
+ console.log(Chalk.bold(`• Using cached response for ${url.href}`));
114
+ }
115
+ result = cached.result;
116
+ }
117
+ else {
118
+ this.#cache.delete(cacheKey);
119
+ }
120
+ }
121
+ }
122
+ if (!result && isCacheQueueEnabled) {
123
+ const cacheQueue = this.#cacheQueue.get(cacheKey);
124
+ if (cacheQueue) {
125
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.info) {
126
+ // eslint-disable-next-line no-console
127
+ console.log(Chalk.bold(`• Waiting for ongoing rendering of ${url.href}`));
128
+ }
129
+ result = await new Promise((resolve, reject) => {
130
+ cacheQueue.push({ resolve, reject });
131
+ });
132
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.info) {
133
+ // eslint-disable-next-line no-console
134
+ console.log(Chalk.bold(`• Using cached response for ${url.href}`));
135
+ }
136
+ }
137
+ else {
138
+ this.#cacheQueue.set(cacheKey, []);
139
+ }
140
+ }
141
+ if (!result) {
142
+ result = (await this.#serverRenderer.render([{ url: url.href, headers }], { keepAlive: true }))[0];
143
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.info) {
144
+ // eslint-disable-next-line no-console
145
+ console.log(Chalk.bold(`• Rendered ${url.href}`));
146
+ }
147
+ }
148
+ if (isCacheQueueEnabled) {
149
+ const cacheQueue = this.#cacheQueue.get(cacheKey);
150
+ if (cacheQueue) {
151
+ this.#cacheQueue.delete(cacheKey);
152
+ for (const { resolve } of cacheQueue) {
153
+ resolve(result);
154
+ }
155
+ }
156
+ }
157
+ for (const key of Object.keys(result.headers)) {
158
+ const lowerKey = key.toLowerCase();
159
+ if (lowerKey !== 'transfer-encoding' &&
160
+ lowerKey !== 'content-length' &&
161
+ lowerKey !== 'content-encoding') {
162
+ response.setHeader(key, result.headers[key]);
163
+ }
164
+ }
165
+ response.statusCode = result.error ? 500 : result.status;
166
+ if (result.error) {
167
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.error) {
168
+ // eslint-disable-next-line no-console
169
+ console.log(Chalk.red(`\n✖ Failed to render ${url.href}:\n${result.error}\n`));
170
+ }
171
+ response.setHeader('Content-Type', 'text/html; charset=utf-8');
172
+ response.end(`<h1>Internal Server Error</h1><br><p>${result.error.replace(/\n/gm, '<br>')}</p>`);
173
+ return;
174
+ }
175
+ if (isCacheEnabled) {
176
+ this.#cache.set(cacheKey, {
177
+ timestamp: Date.now(),
178
+ result
179
+ });
180
+ }
181
+ response.setHeader('Content-Encoding', 'gzip');
182
+ response.setHeader('Content-Type', 'text/html; charset=utf-8');
183
+ try {
184
+ await Stream.pipeline(result.content, ZLib.createGzip(), response);
185
+ }
186
+ catch (error) {
187
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.error) {
188
+ // eslint-disable-next-line no-console
189
+ console.log(Chalk.red(`\n✖ Failed to send response: ${error}\n`));
190
+ }
191
+ response.statusCode = 500;
192
+ response.setHeader('Content-Type', 'text/plain; charset=utf-8');
193
+ response.write('Internal Server Error');
194
+ }
195
+ response.end();
196
+ return;
197
+ }
198
+ for (const [key, value] of fetchResponse.headers.entries()) {
199
+ if (key.toLowerCase() !== 'transfer-encoding') {
200
+ response.setHeader(key, value);
201
+ }
202
+ }
203
+ response.statusCode = fetchResponse.status;
204
+ if (fetchResponse.headers.get('Content-Encoding')) {
205
+ response.setHeader('Content-Encoding', 'gzip');
206
+ response.removeHeader('Content-Length');
207
+ try {
208
+ await Stream.pipeline(fetchResponse.body, ZLib.createGzip(), response);
209
+ }
210
+ catch (error) {
211
+ if (this.#configuration.logLevel >= ServerRendererLogLevelEnum.error) {
212
+ // eslint-disable-next-line no-console
213
+ console.log(Chalk.red(`\n✖ Failed to send response: ${error}\n`));
214
+ }
215
+ response.statusCode = 500;
216
+ response.setHeader('Content-Type', 'text/plain; charset=utf-8');
217
+ response.write('Internal Server Error');
218
+ }
219
+ }
220
+ else if (fetchResponse.body) {
221
+ const reader = fetchResponse.body.getReader();
222
+ while (true) {
223
+ const { done, value } = await reader.read();
224
+ if (done) {
225
+ break;
226
+ }
227
+ response.write(value);
228
+ }
229
+ }
230
+ response.end();
231
+ }
232
+ /**
233
+ * Returns the network IP address of the server.
234
+ *
235
+ * @returns The network IP address.
236
+ */
237
+ #getNetworkIP() {
238
+ const interfaces = OS.networkInterfaces();
239
+ for (const interfaceName in interfaces) {
240
+ const networkInterface = interfaces[interfaceName];
241
+ if (networkInterface) {
242
+ for (const address of networkInterface) {
243
+ if (address.family === 'IPv4' && !address.internal) {
244
+ return address.address;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ return '';
250
+ }
251
+ /**
252
+ * Returns the cache key for the given request.
253
+ *
254
+ * @param url Request URL.
255
+ * @param headers Request headers.
256
+ * @param statusCode Response status code.
257
+ * @returns The cache key.§
258
+ */
259
+ #getCacheKey(url, headers, statusCode) {
260
+ return `${url.href}|${JSON.stringify(headers)}|${statusCode}`;
261
+ }
262
+ }
263
+ //# sourceMappingURL=ServerRendererServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerRendererServer.js","sourceRoot":"","sources":["../src/ServerRendererServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Server renderer worker.
3
+ */
4
+ export default class ServerRendererWorker {
5
+ /**
6
+ * Connects to the worker.
7
+ */
8
+ static connect(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=ServerRendererWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerRendererWorker.d.ts","sourceRoot":"","sources":["../src/ServerRendererWorker.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACxC;;OAEG;WACiB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAe5C"}
@@ -0,0 +1,25 @@
1
+ import ServerRendererBrowser from './ServerRendererBrowser.js';
2
+ import { parentPort, workerData } from 'worker_threads';
3
+ import Inspector from 'node:inspector';
4
+ /**
5
+ * Server renderer worker.
6
+ */
7
+ export default class ServerRendererWorker {
8
+ /**
9
+ * Connects to the worker.
10
+ */
11
+ static async connect() {
12
+ const { configuration } = workerData;
13
+ if (configuration.inspect) {
14
+ Inspector.open();
15
+ Inspector.waitForDebugger();
16
+ }
17
+ const browser = new ServerRendererBrowser(configuration);
18
+ parentPort?.on('message', async ({ items }) => {
19
+ const results = await browser.render(items);
20
+ parentPort?.postMessage({ status: 'done', results });
21
+ });
22
+ }
23
+ }
24
+ ServerRendererWorker.connect();
25
+ //# sourceMappingURL=ServerRendererWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServerRendererWorker.js","sourceRoot":"","sources":["../src/ServerRendererWorker.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAEvC;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACxC;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO;QAC1B,MAAM,EAAE,aAAa,EAAE,GAAG,UAAU,CAAC;QAErC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC3B,SAAS,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,eAAe,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,aAAa,CAAC,CAAC;QAEzD,UAAU,EAAE,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YAC7C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACJ,CAAC;CACD;AAED,oBAAoB,CAAC,OAAO,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type IServerRendererConfiguration from '../types/IServerRendererConfiguration.js';
2
+ declare const _default: IServerRendererConfiguration;
3
+ export default _default;
4
+ //# sourceMappingURL=DefaultServerRendererConfiguration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultServerRendererConfiguration.d.ts","sourceRoot":"","sources":["../../src/config/DefaultServerRendererConfiguration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,4BAA4B,MAAM,0CAA0C,CAAC;wBAIzE,4BAA4B;AAA5C,wBAkCE"}
@@ -0,0 +1,40 @@
1
+ import DefaultBrowserSettings from 'happy-dom/lib/browser/DefaultBrowserSettings.js';
2
+ import ServerRendererLogLevelEnum from '../enums/ServerRendererLogLevelEnum.js';
3
+ import OS from 'os';
4
+ import { BrowserErrorCaptureEnum } from 'happy-dom';
5
+ export default {
6
+ browser: { ...DefaultBrowserSettings, errorCapture: BrowserErrorCaptureEnum.processLevel },
7
+ outputDirectory: './happy-dom/render',
8
+ logLevel: ServerRendererLogLevelEnum.info,
9
+ debug: false,
10
+ inspect: false,
11
+ help: false,
12
+ cache: {
13
+ disable: false,
14
+ directory: './happy-dom/cache',
15
+ warmup: false
16
+ },
17
+ worker: {
18
+ disable: false,
19
+ maxConcurrency: Math.max(1, Math.floor(OS.cpus().length / 2))
20
+ },
21
+ render: {
22
+ maxConcurrency: 10,
23
+ timeout: 30000, // 30 seconds
24
+ incognitoContext: false,
25
+ serializableShadowRoots: false,
26
+ allShadowRoots: false,
27
+ excludeShadowRootTags: null,
28
+ disablePolyfills: false
29
+ },
30
+ urls: null,
31
+ server: {
32
+ start: false,
33
+ serverURL: 'https://localhost:3000',
34
+ targetOrigin: null,
35
+ disableCache: false,
36
+ disableCacheQueue: false,
37
+ cacheTime: 60000 // 60 seconds
38
+ }
39
+ };
40
+ //# sourceMappingURL=DefaultServerRendererConfiguration.js.map