@angular/ssr 17.0.0-next.6 → 17.0.0-next.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.
@@ -6,4 +6,4 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  export { CommonEngine } from './src/common-engine';
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljX2FwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXIvc3NyL3B1YmxpY19hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBNkIsTUFBTSxxQkFBcUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5leHBvcnQgeyBDb21tb25FbmdpbmUsIENvbW1vbkVuZ2luZVJlbmRlck9wdGlvbnMgfSBmcm9tICcuL3NyYy9jb21tb24tZW5naW5lJztcbiJdfQ==
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljX2FwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXIvc3NyL3B1YmxpY19hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBa0QsTUFBTSxxQkFBcUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5leHBvcnQgeyBDb21tb25FbmdpbmUsIENvbW1vbkVuZ2luZVJlbmRlck9wdGlvbnMsIENvbW1vbkVuZ2luZU9wdGlvbnMgfSBmcm9tICcuL3NyYy9jb21tb24tZW5naW5lJztcbiJdfQ==
@@ -10,21 +10,18 @@ import * as fs from 'node:fs';
10
10
  import { dirname, resolve } from 'node:path';
11
11
  import { URL } from 'node:url';
12
12
  import { InlineCriticalCssProcessor } from './inline-css-processor';
13
+ import { noopRunMethodAndMeasurePerf, printPerformanceLogs, runMethodAndMeasurePerf, } from './peformance-profiler';
13
14
  const SSG_MARKER_REGEXP = /ng-server-context=["']\w*\|?ssg\|?\w*["']/;
14
15
  /**
15
- * A common rendering engine utility. This abstracts the logic
16
- * for handling the platformServer compiler, the module cache, and
17
- * the document loader
16
+ * A common engine to use to server render an application.
18
17
  */
19
18
  export class CommonEngine {
20
- bootstrap;
21
- providers;
19
+ options;
22
20
  templateCache = new Map();
23
21
  inlineCriticalCssProcessor;
24
22
  pageIsSSG = new Map();
25
- constructor(bootstrap, providers = []) {
26
- this.bootstrap = bootstrap;
27
- this.providers = providers;
23
+ constructor(options) {
24
+ this.options = options;
28
25
  this.inlineCriticalCssProcessor = new InlineCriticalCssProcessor({
29
26
  minify: false,
30
27
  });
@@ -34,38 +31,70 @@ export class CommonEngine {
34
31
  * render options
35
32
  */
36
33
  async render(opts) {
37
- const { inlineCriticalCss = true, url } = opts;
38
- if (opts.publicPath && opts.documentFilePath && url !== undefined) {
39
- const pathname = canParseUrl(url) ? new URL(url).pathname : url;
40
- // Remove leading forward slash.
41
- const pagePath = resolve(opts.publicPath, pathname.substring(1), 'index.html');
42
- if (pagePath !== resolve(opts.documentFilePath)) {
43
- // View path doesn't match with prerender path.
44
- const pageIsSSG = this.pageIsSSG.get(pagePath);
45
- if (pageIsSSG === undefined) {
46
- if (await exists(pagePath)) {
47
- const content = await fs.promises.readFile(pagePath, 'utf-8');
48
- const isSSG = SSG_MARKER_REGEXP.test(content);
49
- this.pageIsSSG.set(pagePath, isSSG);
50
- if (isSSG) {
51
- return content;
52
- }
53
- }
54
- else {
55
- this.pageIsSSG.set(pagePath, false);
34
+ const enablePeformanceProfiler = this.options?.enablePeformanceProfiler;
35
+ const runMethod = enablePeformanceProfiler
36
+ ? runMethodAndMeasurePerf
37
+ : noopRunMethodAndMeasurePerf;
38
+ let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));
39
+ if (html === undefined) {
40
+ html = await runMethod('Render Page', () => this.renderApplication(opts));
41
+ if (opts.inlineCriticalCss !== false) {
42
+ const { content, errors, warnings } = await runMethod('Inline Critical CSS', () =>
43
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
44
+ this.inlineCriticalCss(html, opts));
45
+ html = content;
46
+ // eslint-disable-next-line no-console
47
+ warnings?.forEach((m) => console.warn(m));
48
+ // eslint-disable-next-line no-console
49
+ errors?.forEach((m) => console.error(m));
50
+ }
51
+ }
52
+ if (enablePeformanceProfiler) {
53
+ printPerformanceLogs();
54
+ }
55
+ return html;
56
+ }
57
+ inlineCriticalCss(html, opts) {
58
+ return this.inlineCriticalCssProcessor.process(html, {
59
+ outputPath: opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : ''),
60
+ });
61
+ }
62
+ async retrieveSSGPage(opts) {
63
+ const { publicPath, documentFilePath, url } = opts;
64
+ if (!publicPath || !documentFilePath || url === undefined) {
65
+ return undefined;
66
+ }
67
+ const pathname = canParseUrl(url) ? new URL(url).pathname : url;
68
+ // Remove leading forward slash.
69
+ const pagePath = resolve(publicPath, pathname.substring(1), 'index.html');
70
+ if (pagePath !== resolve(documentFilePath)) {
71
+ // View path doesn't match with prerender path.
72
+ const pageIsSSG = this.pageIsSSG.get(pagePath);
73
+ if (pageIsSSG === undefined) {
74
+ if (await exists(pagePath)) {
75
+ const content = await fs.promises.readFile(pagePath, 'utf-8');
76
+ const isSSG = SSG_MARKER_REGEXP.test(content);
77
+ this.pageIsSSG.set(pagePath, isSSG);
78
+ if (isSSG) {
79
+ return content;
56
80
  }
57
81
  }
58
- else if (pageIsSSG) {
59
- // Serve pre-rendered page.
60
- return fs.promises.readFile(pagePath, 'utf-8');
82
+ else {
83
+ this.pageIsSSG.set(pagePath, false);
61
84
  }
62
85
  }
86
+ else if (pageIsSSG) {
87
+ // Serve pre-rendered page.
88
+ return fs.promises.readFile(pagePath, 'utf-8');
89
+ }
63
90
  }
64
- // if opts.document dosen't exist then opts.documentFilePath must
91
+ return undefined;
92
+ }
93
+ async renderApplication(opts) {
65
94
  const extraProviders = [
66
95
  { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },
67
96
  ...(opts.providers ?? []),
68
- ...this.providers,
97
+ ...(this.options?.providers ?? []),
69
98
  ];
70
99
  let document = opts.document;
71
100
  if (!document && opts.documentFilePath) {
@@ -80,24 +109,13 @@ export class CommonEngine {
80
109
  },
81
110
  });
82
111
  }
83
- const moduleOrFactory = this.bootstrap || opts.bootstrap;
112
+ const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;
84
113
  if (!moduleOrFactory) {
85
114
  throw new Error('A module or bootstrap option must be provided.');
86
115
  }
87
- const html = await (isBootstrapFn(moduleOrFactory)
116
+ return isBootstrapFn(moduleOrFactory)
88
117
  ? renderApplication(moduleOrFactory, { platformProviders: extraProviders })
89
- : renderModule(moduleOrFactory, { extraProviders }));
90
- if (!inlineCriticalCss) {
91
- return html;
92
- }
93
- const { content, errors, warnings } = await this.inlineCriticalCssProcessor.process(html, {
94
- outputPath: opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : ''),
95
- });
96
- // eslint-disable-next-line no-console
97
- warnings?.forEach((m) => console.warn(m));
98
- // eslint-disable-next-line no-console
99
- errors?.forEach((m) => console.error(m));
100
- return content;
118
+ : renderModule(moduleOrFactory, { extraProviders });
101
119
  }
102
120
  /** Retrieve the document from the cache or the filesystem */
103
121
  async getDocument(filePath) {
@@ -131,4 +149,4 @@ function canParseUrl(url) {
131
149
  return false;
132
150
  }
133
151
  }
134
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLWVuZ2luZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXIvc3NyL3NyYy9jb21tb24tZW5naW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUdILE9BQU8sRUFDTCxjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixlQUFlLEdBQ2hCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDN0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVwRSxNQUFNLGlCQUFpQixHQUFHLDJDQUEyQyxDQUFDO0FBb0J0RTs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFNYjtJQUNBO0lBTk8sYUFBYSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQzFDLDBCQUEwQixDQUE2QjtJQUN2RCxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7SUFFeEQsWUFDVSxTQUFzRCxFQUN0RCxZQUE4QixFQUFFO1FBRGhDLGNBQVMsR0FBVCxTQUFTLENBQTZDO1FBQ3RELGNBQVMsR0FBVCxTQUFTLENBQXVCO1FBRXhDLElBQUksQ0FBQywwQkFBMEIsR0FBRyxJQUFJLDBCQUEwQixDQUFDO1lBQy9ELE1BQU0sRUFBRSxLQUFLO1NBQ2QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBK0I7UUFDMUMsTUFBTSxFQUFFLGlCQUFpQixHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFFL0MsSUFBSSxJQUFJLENBQUMsVUFB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QUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVsRCxPQUFPLElBQUksQ0FBQztLQUNiO0lBQUMsTUFBTTtRQUNOLE9BQU8sS0FBSyxDQUFDO0tBQ2Q7QUFDSCxDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsS0FBYztJQUNuQyx1SEFBdUg7SUFDdkgsT0FBTyxPQUFPLEtBQUssS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQsaUZBQWlGO0FBQ2pGLFNBQVMsV0FBVyxDQUFDLEdBQVc7SUFDOUIsSUFBSTtRQUNGLE9BQU8sQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ3ZCO0lBQUMsTUFBTTtRQUNOLE9BQU8sS0FBSyxDQUFDO0tBQ2Q7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEFwcGxpY2F0aW9uUmVmLCBTdGF0aWNQcm92aWRlciwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgSU5JVElBTF9DT05GSUcsXG4gIHJlbmRlckFwcGxpY2F0aW9uLFxuICByZW5kZXJNb2R1bGUsXG4gIMm1U0VSVkVSX0NPTlRFWFQsXG59IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLXNlcnZlcic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IGRpcm5hbWUsIHJlc29sdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgVVJMIH0gZnJvbSAnbm9kZTp1cmwnO1xuaW1wb3J0IHsgSW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3IgfSBmcm9tICcuL2lubGluZS1jc3MtcHJvY2Vzc29yJztcblxuY29uc3QgU1NHX01BUktFUl9SRUdFWFAgPSAvbmctc2VydmVyLWNvbnRleHQ9W1wiJ11cXHcqXFx8P3NzZ1xcfD9cXHcqW1wiJ10vO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbW1vbkVuZ2luZVJlbmRlck9wdGlvbnMge1xuICBib290c3RyYXA/OiBUeXBlPHt9PiB8ICgoKSA9PiBQcm9taXNlPEFwcGxpY2F0aW9uUmVmPik7XG4gIHByb3ZpZGVycz86IFN0YXRpY1Byb3ZpZGVyW107XG4gIHVybD86IHN0cmluZztcbiAgZG9jdW1lbnQ/OiBzdHJpbmc7XG4gIGRvY3VtZW50RmlsZVBhdGg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBSZWR1Y2UgcmVuZGVyIGJsb2NraW5nIHJlcXVlc3RzIGJ5IGlubGluaW5nIGNyaXRpY2FsIENTUy5cbiAgICogRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICovXG4gIGlubGluZUNyaXRpY2FsQ3NzPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEJhc2UgcGF0aCBsb2NhdGlvbiBvZiBpbmRleCBmaWxlLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgJ2RvY3VtZW50RmlsZVBhdGgnIGRpcm5hbWUgd2hlbiBub3QgcHJvdmlkZWQuXG4gICAqL1xuICBwdWJsaWNQYXRoPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgY29tbW9uIHJlbmRlcmluZyBlbmdpbmUgdXRpbGl0eS4gVGhpcyBhYnN0cmFjdHMgdGhlIGxvZ2ljXG4gKiBmb3IgaGFuZGxpbmcgdGhlIHBsYXRmb3JtU2VydmVyIGNvbXBpbGVyLCB0aGUgbW9kdWxlIGNhY2hlLCBhbmRcbiAqIHRoZSBkb2N1bWVudCBsb2FkZXJcbiAqL1xuZXhwb3J0IGNsYXNzIENvbW1vbkVuZ2luZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVtcGxhdGVDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3I6IElubGluZUNyaXRpY2FsQ3NzUHJvY2Vzc29yO1xuICBwcml2YXRlIHJlYWRvbmx5IHBhZ2VJc1NTRyA9IG5ldyBNYXA8c3RyaW5nLCBib29sZWFuPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYm9vdHN0cmFwPzogVHlwZTx7fT4gfCAoKCkgPT4gUHJvbWlzZTxBcHBsaWNhdGlvblJlZj4pLFxuICAgIHByaXZhdGUgcHJvdmlkZXJzOiBTdGF0aWNQcm92aWRlcltdID0gW10sXG4gICkge1xuICAgIHRoaXMuaW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3IgPSBuZXcgSW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3Ioe1xuICAgICAgbWluaWZ5OiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgYW4gSFRNTCBkb2N1bWVudCBmb3IgYSBzcGVjaWZpYyBVUkwgd2l0aCBzcGVjaWZpZWRcbiAgICogcmVuZGVyIG9wdGlvbnNcbiAgICovXG4gIGFzeW5jIHJlbmRlcihvcHRzOiBDb21tb25FbmdpbmVSZW5kZXJPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCB7IGlubGluZUNyaXRpY2FsQ3NzID0gdHJ1ZSwgdXJsIH0gPSBvcHRzO1xuXG4gICAgaWYgKG9wdHMucHVibGljUGF0aCAmJiBvcHRzLmRvY3VtZW50RmlsZVBhdGggJiYgdXJsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHBhdGhuYW1lID0gY2FuUGFyc2VVcmwodXJsKSA/IG5ldyBVUkwodXJsKS5wYXRobmFtZSA6IHVybDtcbiAgICAgIC8vIFJlbW92ZSBsZWFkaW5nIGZvcndhcmQgc2xhc2guXG4gICAgICBjb25zdCBwYWdlUGF0aCA9IHJlc29sdmUob3B0cy5wdWJsaWNQYXRoLCBwYXRobmFtZS5zdWJzdHJpbmcoMSksICdpbmRleC5odG1sJyk7XG5cbiAgICAgIGlmIChwYWdlUGF0aCAhPT0gcmVzb2x2ZShvcHRzLmRvY3VtZW50RmlsZVBhdGgpKSB7XG4gICAgICAgIC8vIFZpZXcgcGF0aCBkb2Vzbid0IG1hdGNoIHdpdGggcHJlcmVuZGVyIHBhdGguXG4gICAgICAgIGNvbnN0IHBhZ2VJc1NTRyA9IHRoaXMucGFnZUlzU1NHLmdldChwYWdlUGF0aCk7XG4gICAgICAgIGlmIChwYWdlSXNTU0cgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChhd2FpdCBleGlzdHMocGFnZVBhdGgpKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucHJvbWlzZXMucmVhZEZpbGUocGFnZVBhdGgsICd1dGYtOCcpO1xuICAgICAgICAgICAgY29uc3QgaXNTU0cgPSBTU0dfTUFSS0VSX1JFR0VYUC50ZXN0KGNvbnRlbnQpO1xuICAgICAgICAgICAgdGhpcy5wYWdlSXNTU0cuc2V0KHBhZ2VQYXRoLCBpc1NTRyk7XG5cbiAgICAgICAgICAgIGlmIChpc1NTRykge1xuICAgICAgICAgICAgICByZXR1cm4gY29udGVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wYWdlSXNTU0cuc2V0KHBhZ2VQYXRoLCBmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHBhZ2VJc1NTRykge1xuICAgICAgICAgIC8vIFNlcnZlIHByZS1yZW5kZXJlZCBwYWdlLlxuICAgICAgICAgIHJldHVybiBmcy5wcm9taXNlcy5yZWFkRmlsZShwYWdlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiBvcHRzLmRvY3VtZW50IGRvc2VuJ3QgZXhpc3QgdGhlbiBvcHRzLmRvY3VtZW50RmlsZVBhdGggbXVzdFxuICAgIGNvbnN0IGV4dHJhUHJvdmlkZXJzOiBTdGF0aWNQcm92aWRlcltdID0gW1xuICAgICAgeyBwcm92aWRlOiDJtVNFUlZFUl9DT05URVhULCB1c2VWYWx1ZTogJ3NzcicgfSxcbiAgICAgIC4uLihvcHRzLnByb3ZpZGVycyA/PyBbXSksXG4gICAgICAuLi50aGlzLnByb3ZpZGVycyxcbiAgICBdO1xuXG4gICAgbGV0IGRvY3VtZW50ID0gb3B0cy5kb2N1bWVudDtcbiAgICBpZiAoIWRvY3VtZW50ICYmIG9wdHMuZG9jdW1lbnRGaWxlUGF0aCkge1xuICAgICAgZG9jdW1lbnQgPSBhd2FpdCB0aGlzLmdldERvY3VtZW50KG9wdHMuZG9jdW1lbnRGaWxlUGF0aCk7XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50KSB7XG4gICAgICBleHRyYVByb3ZpZGVycy5wdXNoKHtcbiAgICAgICAgcHJvdmlkZTogSU5JVElBTF9DT05GSUcsXG4gICAgICAgIHVzZVZhbHVlOiB7XG4gICAgICAgICAgZG9jdW1lbnQsXG4gICAgICAgICAgdXJsOiBvcHRzLnVybCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IG1vZHVsZU9yRmFjdG9yeSA9IHRoaXMuYm9vdHN0cmFwIHx8IG9wdHMuYm9vdHN0cmFwO1xuICAgIGlmICghbW9kdWxlT3JGYWN0b3J5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgbW9kdWxlIG9yIGJvb3RzdHJhcCBvcHRpb24gbXVzdCBiZSBwcm92aWRlZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBodG1sID0gYXdhaXQgKGlzQm9vdHN0cmFwRm4obW9kdWxlT3JGYWN0b3J5KVxuICAgICAgPyByZW5kZXJBcHBsaWNhdGlvbihtb2R1bGVPckZhY3RvcnksIHsgcGxhdGZvcm1Qcm92aWRlcnM6IGV4dHJhUHJvdmlkZXJzIH0pXG4gICAgICA6IHJlbmRlck1vZHVsZShtb2R1bGVPckZhY3RvcnksIHsgZXh0cmFQcm92aWRlcnMgfSkpO1xuXG4gICAgaWYgKCFpbmxpbmVDcml0aWNhbENzcykge1xuICAgICAgcmV0dXJuIGh0bWw7XG4gICAgfVxuXG4gICAgY29uc3QgeyBjb250ZW50LCBlcnJvcnMsIHdhcm5pbmdzIH0gPSBhd2FpdCB0aGlzLmlubGluZUNyaXRpY2FsQ3NzUHJvY2Vzc29yLnByb2Nlc3MoaHRtbCwge1xuICAgICAgb3V0cHV0UGF0aDogb3B0cy5wdWJsaWNQYXRoID8/IChvcHRzLmRvY3VtZW50RmlsZVBhdGggPyBkaXJuYW1lKG9wdHMuZG9jdW1lbnRGaWxlUGF0aCkgOiAnJyksXG4gICAgfSk7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgIHdhcm5pbmdzPy5mb3JFYWNoKChtKSA9PiBjb25zb2xlLndhcm4obSkpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgZXJyb3JzPy5mb3JFYWNoKChtKSA9PiBjb25zb2xlLmVycm9yKG0pKTtcblxuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgLyoqIFJldHJpZXZlIHRoZSBkb2N1bWVudCBmcm9tIHRoZSBjYWNoZSBvciB0aGUgZmlsZXN5c3RlbSAqL1xuICBwcml2YXRlIGFzeW5jIGdldERvY3VtZW50KGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGxldCBkb2MgPSB0aGlzLnRlbXBsYXRlQ2FjaGUuZ2V0KGZpbGVQYXRoKTtcblxuICAgIGlmICghZG9jKSB7XG4gICAgICBkb2MgPSBhd2FpdCBmcy5wcm9taXNlcy5yZWFkRmlsZShmaWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICB0aGlzLnRlbXBsYXRlQ2FjaGUuc2V0KGZpbGVQYXRoLCBkb2MpO1xuICAgIH1cblxuICAgIHJldHVybiBkb2M7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZXhpc3RzKHBhdGg6IGZzLlBhdGhMaWtlKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgZnMucHJvbWlzZXMuYWNjZXNzKHBhdGgsIGZzLmNvbnN0YW50cy5GX09LKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNCb290c3RyYXBGbih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzICgpID0+IFByb21pc2U8QXBwbGljYXRpb25SZWY+IHtcbiAgLy8gV2UgY2FuIGRpZmZlcmVudGlhdGUgYmV0d2VlbiBhIG1vZHVsZSBhbmQgYSBib290c3RyYXAgZnVuY3Rpb24gYnkgcmVhZGluZyBjb21waWxlci1nZW5lcmF0ZWQgYMm1bW9kYCBzdGF0aWMgcHJvcGVydHk6XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgJiYgISgnybVtb2QnIGluIHZhbHVlKTtcbn1cblxuLy8gVGhlIGJlbG93IGNhbiBiZSByZW1vdmVkIGluIGZhdm9yIG9mIFVSTC5jYW5QYXJzZSgpIHdoZW4gTm9kZS5qcyAxOCBpcyBkcm9wcGVkXG5mdW5jdGlvbiBjYW5QYXJzZVVybCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHJldHVybiAhIW5ldyBVUkwodXJsKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iXX0=
152
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLWVuZ2luZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXIvc3NyL3NyYy9jb21tb24tZW5naW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUdILE9BQU8sRUFDTCxjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixlQUFlLEdBQ2hCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDN0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUUsMEJBQTBCLEVBQTJCLE1BQU0sd0JBQXdCLENBQUM7QUFDN0YsT0FBTyxFQUNMLDJCQUEyQixFQUMzQixvQkFBb0IsRUFDcEIsdUJBQXVCLEdBQ3hCLE1BQU0sdUJBQXVCLENBQUM7QUFFL0IsTUFBTSxpQkFBaUIsR0FBRywyQ0FBMkMsQ0FBQztBQStCdEU7O0dBRUc7QUFFSCxNQUFNLE9BQU8sWUFBWTtJQUtIO0lBSkgsYUFBYSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQzFDLDBCQUEwQixDQUE2QjtJQUN2RCxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7SUFFeEQsWUFBb0IsT0FBNkI7UUFBN0IsWUFBTyxHQUFQLE9BQU8sQ0FBc0I7UUFDL0MsSUFBSSxDQUFDLDBCQUEwQixHQUFHLElBQUksMEJBQTBCLENBQUM7WUFDL0QsTUFBTSxFQUFFLEtBQUs7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUErQjtRQUMxQyxNQUFNLHdCQUF3QixHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsd0JBQXdCLENBQUM7UUFFeEUsTUFB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Q0FBQyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQsaUZBQWlGO0FBQ2pGLFNBQVMsV0FBVyxDQUFDLEdBQVc7SUFDOUIsSUFBSTtRQUNGLE9BQU8sQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ3ZCO0lBQUMsTUFBTTtRQUNOLE9BQU8sS0FBSyxDQUFDO0tBQ2Q7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEFwcGxpY2F0aW9uUmVmLCBTdGF0aWNQcm92aWRlciwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgSU5JVElBTF9DT05GSUcsXG4gIHJlbmRlckFwcGxpY2F0aW9uLFxuICByZW5kZXJNb2R1bGUsXG4gIMm1U0VSVkVSX0NPTlRFWFQsXG59IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLXNlcnZlcic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IGRpcm5hbWUsIHJlc29sdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgVVJMIH0gZnJvbSAnbm9kZTp1cmwnO1xuaW1wb3J0IHsgSW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3IsIElubGluZUNyaXRpY2FsQ3NzUmVzdWx0IH0gZnJvbSAnLi9pbmxpbmUtY3NzLXByb2Nlc3Nvcic7XG5pbXBvcnQge1xuICBub29wUnVuTWV0aG9kQW5kTWVhc3VyZVBlcmYsXG4gIHByaW50UGVyZm9ybWFuY2VMb2dzLFxuICBydW5NZXRob2RBbmRNZWFzdXJlUGVyZixcbn0gZnJvbSAnLi9wZWZvcm1hbmNlLXByb2ZpbGVyJztcblxuY29uc3QgU1NHX01BUktFUl9SRUdFWFAgPSAvbmctc2VydmVyLWNvbnRleHQ9W1wiJ11cXHcqXFx8P3NzZ1xcfD9cXHcqW1wiJ10vO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbW1vbkVuZ2luZU9wdGlvbnMge1xuICAvKiogQSBtZXRob2QgdGhhdCB3aGVuIGludm9rZWQgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXR1cm5zIGFuIGBBcHBsaWNhdGlvblJlZmAgaW5zdGFuY2Ugb25jZSByZXNvbHZlZCBvciBhbiBOZ01vZHVsZS4gKi9cbiAgYm9vdHN0cmFwPzogVHlwZTx7fT4gfCAoKCkgPT4gUHJvbWlzZTxBcHBsaWNhdGlvblJlZj4pO1xuICAvKiogQSBzZXQgb2YgcGxhdGZvcm0gbGV2ZWwgcHJvdmlkZXJzIGZvciBhbGwgcmVxdWVzdHMuICovXG4gIHByb3ZpZGVycz86IFN0YXRpY1Byb3ZpZGVyW107XG4gIC8qKiBFbmFibGUgcmVxdWVzdCBwZXJmb3JtYW5jZSBwcm9maWxpbmcgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmludGluZyB0aGUgcmVzdWx0cyBpbiB0aGUgc2VydmVyIGNvbnNvbGUuICovXG4gIGVuYWJsZVBlZm9ybWFuY2VQcm9maWxlcj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbW9uRW5naW5lUmVuZGVyT3B0aW9ucyB7XG4gIC8qKiBBIG1ldGhvZCB0aGF0IHdoZW4gaW52b2tlZCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJldHVybnMgYW4gYEFwcGxpY2F0aW9uUmVmYCBpbnN0YW5jZSBvbmNlIHJlc29sdmVkIG9yIGFuIE5nTW9kdWxlLiAqL1xuICBib290c3RyYXA/OiBUeXBlPHt9PiB8ICgoKSA9PiBQcm9taXNlPEFwcGxpY2F0aW9uUmVmPik7XG4gIC8qKiBBIHNldCBvZiBwbGF0Zm9ybSBsZXZlbCBwcm92aWRlcnMgZm9yIHRoZSBjdXJyZW50IHJlcXVlc3QuICovXG4gIHByb3ZpZGVycz86IFN0YXRpY1Byb3ZpZGVyW107XG4gIHVybD86IHN0cmluZztcbiAgZG9jdW1lbnQ/OiBzdHJpbmc7XG4gIGRvY3VtZW50RmlsZVBhdGg/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBSZWR1Y2UgcmVuZGVyIGJsb2NraW5nIHJlcXVlc3RzIGJ5IGlubGluaW5nIGNyaXRpY2FsIENTUy5cbiAgICogRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICovXG4gIGlubGluZUNyaXRpY2FsQ3NzPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEJhc2UgcGF0aCBsb2NhdGlvbiBvZiBpbmRleCBmaWxlLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgJ2RvY3VtZW50RmlsZVBhdGgnIGRpcm5hbWUgd2hlbiBub3QgcHJvdmlkZWQuXG4gICAqL1xuICBwdWJsaWNQYXRoPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgY29tbW9uIGVuZ2luZSB0byB1c2UgdG8gc2VydmVyIHJlbmRlciBhbiBhcHBsaWNhdGlvbi5cbiAqL1xuXG5leHBvcnQgY2xhc3MgQ29tbW9uRW5naW5lIHtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZW1wbGF0ZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBpbmxpbmVDcml0aWNhbENzc1Byb2Nlc3NvcjogSW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3I7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGFnZUlzU1NHID0gbmV3IE1hcDxzdHJpbmcsIGJvb2xlYW4+KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBvcHRpb25zPzogQ29tbW9uRW5naW5lT3B0aW9ucykge1xuICAgIHRoaXMuaW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3IgPSBuZXcgSW5saW5lQ3JpdGljYWxDc3NQcm9jZXNzb3Ioe1xuICAgICAgbWluaWZ5OiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgYW4gSFRNTCBkb2N1bWVudCBmb3IgYSBzcGVjaWZpYyBVUkwgd2l0aCBzcGVjaWZpZWRcbiAgICogcmVuZGVyIG9wdGlvbnNcbiAgICovXG4gIGFzeW5jIHJlbmRlcihvcHRzOiBDb21tb25FbmdpbmVSZW5kZXJPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBlbmFibGVQZWZvcm1hbmNlUHJvZmlsZXIgPSB0aGlzLm9wdGlvbnM/LmVuYWJsZVBlZm9ybWFuY2VQcm9maWxlcjtcblxuICAgIGNvbnN0IHJ1bk1ldGhvZCA9IGVuYWJsZVBlZm9ybWFuY2VQcm9maWxlclxuICAgICAgPyBydW5NZXRob2RBbmRNZWFzdXJlUGVyZlxuICAgICAgOiBub29wUnVuTWV0aG9kQW5kTWVhc3VyZVBlcmY7XG5cbiAgICBsZXQgaHRtbCA9IGF3YWl0IHJ1bk1ldGhvZCgnUmV0cmlldmUgU1NHIFBhZ2UnLCAoKSA9PiB0aGlzLnJldHJpZXZlU1NHUGFnZShvcHRzKSk7XG5cbiAgICBpZiAoaHRtbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBodG1sID0gYXdhaXQgcnVuTWV0aG9kKCdSZW5kZXIgUGFnZScsICgpID0+IHRoaXMucmVuZGVyQXBwbGljYXRpb24ob3B0cykpO1xuXG4gICAgICBpZiAob3B0cy5pbmxpbmVDcml0aWNhbENzcyAhPT0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgeyBjb250ZW50LCBlcnJvcnMsIHdhcm5pbmdzIH0gPSBhd2FpdCBydW5NZXRob2QoJ0lubGluZSBDcml0aWNhbCBDU1MnLCAoKSA9PlxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgdGhpcy5pbmxpbmVDcml0aWNhbENzcyhodG1sISwgb3B0cyksXG4gICAgICAgICk7XG5cbiAgICAgICAgaHRtbCA9IGNvbnRlbnQ7XG5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgd2FybmluZ3M/LmZvckVhY2goKG0pID0+IGNvbnNvbGUud2FybihtKSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGVycm9ycz8uZm9yRWFjaCgobSkgPT4gY29uc29sZS5lcnJvcihtKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVuYWJsZVBlZm9ybWFuY2VQcm9maWxlcikge1xuICAgICAgcHJpbnRQZXJmb3JtYW5jZUxvZ3MoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIHByaXZhdGUgaW5saW5lQ3JpdGljYWxDc3MoXG4gICAgaHRtbDogc3RyaW5nLFxuICAgIG9wdHM6IENvbW1vbkVuZ2luZVJlbmRlck9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5saW5lQ3JpdGljYWxDc3NSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5pbmxpbmVDcml0aWNhbENzc1Byb2Nlc3Nvci5wcm9jZXNzKGh0bWwsIHtcbiAgICAgIG91dHB1dFBhdGg6IG9wdHMucHVibGljUGF0aCA/PyAob3B0cy5kb2N1bWVudEZpbGVQYXRoID8gZGlybmFtZShvcHRzLmRvY3VtZW50RmlsZVBhdGgpIDogJycpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZXRyaWV2ZVNTR1BhZ2Uob3B0czogQ29tbW9uRW5naW5lUmVuZGVyT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgeyBwdWJsaWNQYXRoLCBkb2N1bWVudEZpbGVQYXRoLCB1cmwgfSA9IG9wdHM7XG4gICAgaWYgKCFwdWJsaWNQYXRoIHx8ICFkb2N1bWVudEZpbGVQYXRoIHx8IHVybCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGhuYW1lID0gY2FuUGFyc2VVcmwodXJsKSA/IG5ldyBVUkwodXJsKS5wYXRobmFtZSA6IHVybDtcbiAgICAvLyBSZW1vdmUgbGVhZGluZyBmb3J3YXJkIHNsYXNoLlxuICAgIGNvbnN0IHBhZ2VQYXRoID0gcmVzb2x2ZShwdWJsaWNQYXRoLCBwYXRobmFtZS5zdWJzdHJpbmcoMSksICdpbmRleC5odG1sJyk7XG5cbiAgICBpZiAocGFnZVBhdGggIT09IHJlc29sdmUoZG9jdW1lbnRGaWxlUGF0aCkpIHtcbiAgICAgIC8vIFZpZXcgcGF0aCBkb2Vzbid0IG1hdGNoIHdpdGggcHJlcmVuZGVyIHBhdGguXG4gICAgICBjb25zdCBwYWdlSXNTU0cgPSB0aGlzLnBhZ2VJc1NTRy5nZXQocGFnZVBhdGgpO1xuICAgICAgaWYgKHBhZ2VJc1NTRyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChhd2FpdCBleGlzdHMocGFnZVBhdGgpKSB7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKHBhZ2VQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICBjb25zdCBpc1NTRyA9IFNTR19NQVJLRVJfUkVHRVhQLnRlc3QoY29udGVudCk7XG4gICAgICAgICAgdGhpcy5wYWdlSXNTU0cuc2V0KHBhZ2VQYXRoLCBpc1NTRyk7XG5cbiAgICAgICAgICBpZiAoaXNTU0cpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnBhZ2VJc1NTRy5zZXQocGFnZVBhdGgsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYWdlSXNTU0cpIHtcbiAgICAgICAgLy8gU2VydmUgcHJlLXJlbmRlcmVkIHBhZ2UuXG4gICAgICAgIHJldHVybiBmcy5wcm9taXNlcy5yZWFkRmlsZShwYWdlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVuZGVyQXBwbGljYXRpb24ob3B0czogQ29tbW9uRW5naW5lUmVuZGVyT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgZXh0cmFQcm92aWRlcnM6IFN0YXRpY1Byb3ZpZGVyW10gPSBbXG4gICAgICB7IHByb3ZpZGU6IMm1U0VSVkVSX0NPTlRFWFQsIHVzZVZhbHVlOiAnc3NyJyB9LFxuICAgICAgLi4uKG9wdHMucHJvdmlkZXJzID8/IFtdKSxcbiAgICAgIC4uLih0aGlzLm9wdGlvbnM/LnByb3ZpZGVycyA/PyBbXSksXG4gICAgXTtcblxuICAgIGxldCBkb2N1bWVudCA9IG9wdHMuZG9jdW1lbnQ7XG4gICAgaWYgKCFkb2N1bWVudCAmJiBvcHRzLmRvY3VtZW50RmlsZVBhdGgpIHtcbiAgICAgIGRvY3VtZW50ID0gYXdhaXQgdGhpcy5nZXREb2N1bWVudChvcHRzLmRvY3VtZW50RmlsZVBhdGgpO1xuICAgIH1cblxuICAgIGlmIChkb2N1bWVudCkge1xuICAgICAgZXh0cmFQcm92aWRlcnMucHVzaCh7XG4gICAgICAgIHByb3ZpZGU6IElOSVRJQUxfQ09ORklHLFxuICAgICAgICB1c2VWYWx1ZToge1xuICAgICAgICAgIGRvY3VtZW50LFxuICAgICAgICAgIHVybDogb3B0cy51cmwsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBtb2R1bGVPckZhY3RvcnkgPSB0aGlzLm9wdGlvbnM/LmJvb3RzdHJhcCA/PyBvcHRzLmJvb3RzdHJhcDtcbiAgICBpZiAoIW1vZHVsZU9yRmFjdG9yeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG1vZHVsZSBvciBib290c3RyYXAgb3B0aW9uIG11c3QgYmUgcHJvdmlkZWQuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzQm9vdHN0cmFwRm4obW9kdWxlT3JGYWN0b3J5KVxuICAgICAgPyByZW5kZXJBcHBsaWNhdGlvbihtb2R1bGVPckZhY3RvcnksIHsgcGxhdGZvcm1Qcm92aWRlcnM6IGV4dHJhUHJvdmlkZXJzIH0pXG4gICAgICA6IHJlbmRlck1vZHVsZShtb2R1bGVPckZhY3RvcnksIHsgZXh0cmFQcm92aWRlcnMgfSk7XG4gIH1cblxuICAvKiogUmV0cmlldmUgdGhlIGRvY3VtZW50IGZyb20gdGhlIGNhY2hlIG9yIHRoZSBmaWxlc3lzdGVtICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0RG9jdW1lbnQoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgbGV0IGRvYyA9IHRoaXMudGVtcGxhdGVDYWNoZS5nZXQoZmlsZVBhdGgpO1xuXG4gICAgaWYgKCFkb2MpIHtcbiAgICAgIGRvYyA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgICAgIHRoaXMudGVtcGxhdGVDYWNoZS5zZXQoZmlsZVBhdGgsIGRvYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRvYztcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBleGlzdHMocGF0aDogZnMuUGF0aExpa2UpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmcy5wcm9taXNlcy5hY2Nlc3MocGF0aCwgZnMuY29uc3RhbnRzLkZfT0spO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0Jvb3RzdHJhcEZuKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgKCkgPT4gUHJvbWlzZTxBcHBsaWNhdGlvblJlZj4ge1xuICAvLyBXZSBjYW4gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIGEgbW9kdWxlIGFuZCBhIGJvb3RzdHJhcCBmdW5jdGlvbiBieSByZWFkaW5nIGNvbXBpbGVyLWdlbmVyYXRlZCBgybVtb2RgIHN0YXRpYyBwcm9wZXJ0eTpcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiAhKCfJtW1vZCcgaW4gdmFsdWUpO1xufVxuXG4vLyBUaGUgYmVsb3cgY2FuIGJlIHJlbW92ZWQgaW4gZmF2b3Igb2YgVVJMLmNhblBhcnNlKCkgd2hlbiBOb2RlLmpzIDE4IGlzIGRyb3BwZWRcbmZ1bmN0aW9uIGNhblBhcnNlVXJsKHVybDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuICEhbmV3IFVSTCh1cmwpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ const PERFORMANCE_MARK_PREFIX = '🅰️';
9
+ export function printPerformanceLogs() {
10
+ let maxWordLength = 0;
11
+ const benchmarks = [];
12
+ for (const { name, duration } of performance.getEntriesByType('measure')) {
13
+ if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {
14
+ continue;
15
+ }
16
+ // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`
17
+ const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';
18
+ if (step.length > maxWordLength) {
19
+ maxWordLength = step.length;
20
+ }
21
+ benchmarks.push([step, `${duration.toFixed(1)}ms`]);
22
+ performance.clearMeasures(name);
23
+ }
24
+ /* eslint-disable no-console */
25
+ console.log('********** Performance results **********');
26
+ for (const [step, value] of benchmarks) {
27
+ const spaces = maxWordLength - step.length + 5;
28
+ console.log(step + ' '.repeat(spaces) + value);
29
+ }
30
+ console.log('*****************************************');
31
+ /* eslint-enable no-console */
32
+ }
33
+ export async function runMethodAndMeasurePerf(label, asyncMethod) {
34
+ const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;
35
+ const startLabel = `start:${labelName}`;
36
+ const endLabel = `end:${labelName}`;
37
+ try {
38
+ performance.mark(startLabel);
39
+ return await asyncMethod();
40
+ }
41
+ finally {
42
+ performance.mark(endLabel);
43
+ performance.measure(labelName, startLabel, endLabel);
44
+ performance.clearMarks(startLabel);
45
+ performance.clearMarks(endLabel);
46
+ }
47
+ }
48
+ export function noopRunMethodAndMeasurePerf(label, asyncMethod) {
49
+ return asyncMethod();
50
+ }
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVmb3JtYW5jZS1wcm9maWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXIvc3NyL3NyYy9wZWZvcm1hbmNlLXByb2ZpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxDQUFDO0FBRXRDLE1BQU0sVUFBVSxvQkFBb0I7SUFDbEMsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLE1BQU0sVUFBVSxHQUFvQyxFQUFFLENBQUM7SUFFdkQsS0FBSyxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUN4RSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFO1lBQzdDLFNBQVM7U0FDVjtRQUVELGtEQUFrRDtRQUNsRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDbEUsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLGFBQWEsRUFBRTtZQUMvQixhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUM3QjtRQUVELFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3BELFdBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDakM7SUFFRCwrQkFBK0I7SUFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO0lBQ3pELEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxVQUFVLEVBQUU7UUFDdEMsTUFBTSxNQUFNLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7S0FDaEQ7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7SUFDekQsOEJBQThCO0FBQ2hDLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLHVCQUF1QixDQUMzQyxLQUFhLEVBQ2IsV0FBNkI7SUFFN0IsTUFBTSxTQUFTLEdBQUcsR0FBRyx1QkFBdUIsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUN4RCxNQUFNLFVBQVUsR0FBRyxTQUFTLFNBQVMsRUFBRSxDQUFDO0lBQ3hDLE1BQU0sUUFBUSxHQUFHLE9BQU8sU0FBUyxFQUFFLENBQUM7SUFFcEMsSUFBSTtRQUNGLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFN0IsT0FBTyxNQUFNLFdBQVcsRUFBRSxDQUFDO0tBQzVCO1lBQVM7UUFDUixXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzNCLFdBQVcsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNyRCxXQUFXLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ25DLFdBQVcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7S0FDbEM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLDJCQUEyQixDQUN6QyxLQUFhLEVBQ2IsV0FBNkI7SUFFN0IsT0FBTyxXQUFXLEVBQUUsQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmNvbnN0IFBFUkZPUk1BTkNFX01BUktfUFJFRklYID0gJ/CfhbDvuI8nO1xuXG5leHBvcnQgZnVuY3Rpb24gcHJpbnRQZXJmb3JtYW5jZUxvZ3MoKTogdm9pZCB7XG4gIGxldCBtYXhXb3JkTGVuZ3RoID0gMDtcbiAgY29uc3QgYmVuY2htYXJrczogW3N0ZXA6IHN0cmluZywgdmFsdWU6IHN0cmluZ11bXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgeyBuYW1lLCBkdXJhdGlvbiB9IG9mIHBlcmZvcm1hbmNlLmdldEVudHJpZXNCeVR5cGUoJ21lYXN1cmUnKSkge1xuICAgIGlmICghbmFtZS5zdGFydHNXaXRoKFBFUkZPUk1BTkNFX01BUktfUFJFRklYKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gYPCfhbDvuI86UmV0cmlldmUgU1NHIFBhZ2VgIC0+IGBSZXRyaWV2ZSBTU0cgUGFnZTpgXG4gICAgY29uc3Qgc3RlcCA9IG5hbWUuc2xpY2UoUEVSRk9STUFOQ0VfTUFSS19QUkVGSVgubGVuZ3RoICsgMSkgKyAnOic7XG4gICAgaWYgKHN0ZXAubGVuZ3RoID4gbWF4V29yZExlbmd0aCkge1xuICAgICAgbWF4V29yZExlbmd0aCA9IHN0ZXAubGVuZ3RoO1xuICAgIH1cblxuICAgIGJlbmNobWFya3MucHVzaChbc3RlcCwgYCR7ZHVyYXRpb24udG9GaXhlZCgxKX1tc2BdKTtcbiAgICBwZXJmb3JtYW5jZS5jbGVhck1lYXN1cmVzKG5hbWUpO1xuICB9XG5cbiAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICBjb25zb2xlLmxvZygnKioqKioqKioqKiBQZXJmb3JtYW5jZSByZXN1bHRzICoqKioqKioqKionKTtcbiAgZm9yIChjb25zdCBbc3RlcCwgdmFsdWVdIG9mIGJlbmNobWFya3MpIHtcbiAgICBjb25zdCBzcGFjZXMgPSBtYXhXb3JkTGVuZ3RoIC0gc3RlcC5sZW5ndGggKyA1O1xuICAgIGNvbnNvbGUubG9nKHN0ZXAgKyAnICcucmVwZWF0KHNwYWNlcykgKyB2YWx1ZSk7XG4gIH1cbiAgY29uc29sZS5sb2coJyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqJyk7XG4gIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuTWV0aG9kQW5kTWVhc3VyZVBlcmY8VD4oXG4gIGxhYmVsOiBzdHJpbmcsXG4gIGFzeW5jTWV0aG9kOiAoKSA9PiBQcm9taXNlPFQ+LFxuKTogUHJvbWlzZTxUPiB7XG4gIGNvbnN0IGxhYmVsTmFtZSA9IGAke1BFUkZPUk1BTkNFX01BUktfUFJFRklYfToke2xhYmVsfWA7XG4gIGNvbnN0IHN0YXJ0TGFiZWwgPSBgc3RhcnQ6JHtsYWJlbE5hbWV9YDtcbiAgY29uc3QgZW5kTGFiZWwgPSBgZW5kOiR7bGFiZWxOYW1lfWA7XG5cbiAgdHJ5IHtcbiAgICBwZXJmb3JtYW5jZS5tYXJrKHN0YXJ0TGFiZWwpO1xuXG4gICAgcmV0dXJuIGF3YWl0IGFzeW5jTWV0aG9kKCk7XG4gIH0gZmluYWxseSB7XG4gICAgcGVyZm9ybWFuY2UubWFyayhlbmRMYWJlbCk7XG4gICAgcGVyZm9ybWFuY2UubWVhc3VyZShsYWJlbE5hbWUsIHN0YXJ0TGFiZWwsIGVuZExhYmVsKTtcbiAgICBwZXJmb3JtYW5jZS5jbGVhck1hcmtzKHN0YXJ0TGFiZWwpO1xuICAgIHBlcmZvcm1hbmNlLmNsZWFyTWFya3MoZW5kTGFiZWwpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub29wUnVuTWV0aG9kQW5kTWVhc3VyZVBlcmY8VD4oXG4gIGxhYmVsOiBzdHJpbmcsXG4gIGFzeW5jTWV0aG9kOiAoKSA9PiBQcm9taXNlPFQ+LFxuKTogUHJvbWlzZTxUPiB7XG4gIHJldHVybiBhc3luY01ldGhvZCgpO1xufVxuIl19
package/fesm2022/ssr.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ɵSERVER_CONTEXT, INITIAL_CONFIG, renderApplication, renderModule } from '@angular/platform-server';
2
2
  import * as fs from 'node:fs';
3
- import { resolve, dirname } from 'node:path';
3
+ import { dirname, resolve } from 'node:path';
4
4
  import { URL } from 'node:url';
5
5
  import Critters from 'critters';
6
6
  import { readFile } from 'node:fs/promises';
@@ -170,21 +170,61 @@ class InlineCriticalCssProcessor {
170
170
  }
171
171
  }
172
172
 
173
+ const PERFORMANCE_MARK_PREFIX = '🅰️';
174
+ function printPerformanceLogs() {
175
+ let maxWordLength = 0;
176
+ const benchmarks = [];
177
+ for (const { name, duration } of performance.getEntriesByType('measure')) {
178
+ if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {
179
+ continue;
180
+ }
181
+ // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`
182
+ const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';
183
+ if (step.length > maxWordLength) {
184
+ maxWordLength = step.length;
185
+ }
186
+ benchmarks.push([step, `${duration.toFixed(1)}ms`]);
187
+ performance.clearMeasures(name);
188
+ }
189
+ /* eslint-disable no-console */
190
+ console.log('********** Performance results **********');
191
+ for (const [step, value] of benchmarks) {
192
+ const spaces = maxWordLength - step.length + 5;
193
+ console.log(step + ' '.repeat(spaces) + value);
194
+ }
195
+ console.log('*****************************************');
196
+ /* eslint-enable no-console */
197
+ }
198
+ async function runMethodAndMeasurePerf(label, asyncMethod) {
199
+ const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;
200
+ const startLabel = `start:${labelName}`;
201
+ const endLabel = `end:${labelName}`;
202
+ try {
203
+ performance.mark(startLabel);
204
+ return await asyncMethod();
205
+ }
206
+ finally {
207
+ performance.mark(endLabel);
208
+ performance.measure(labelName, startLabel, endLabel);
209
+ performance.clearMarks(startLabel);
210
+ performance.clearMarks(endLabel);
211
+ }
212
+ }
213
+ function noopRunMethodAndMeasurePerf(label, asyncMethod) {
214
+ return asyncMethod();
215
+ }
216
+
173
217
  const SSG_MARKER_REGEXP = /ng-server-context=["']\w*\|?ssg\|?\w*["']/;
174
218
  /**
175
- * A common rendering engine utility. This abstracts the logic
176
- * for handling the platformServer compiler, the module cache, and
177
- * the document loader
219
+ * A common engine to use to server render an application.
178
220
  */
179
221
  class CommonEngine {
180
- bootstrap;
181
- providers;
222
+ options;
182
223
  templateCache = new Map();
183
224
  inlineCriticalCssProcessor;
184
225
  pageIsSSG = new Map();
185
- constructor(bootstrap, providers = []) {
186
- this.bootstrap = bootstrap;
187
- this.providers = providers;
226
+ constructor(options) {
227
+ this.options = options;
188
228
  this.inlineCriticalCssProcessor = new InlineCriticalCssProcessor({
189
229
  minify: false,
190
230
  });
@@ -194,38 +234,70 @@ class CommonEngine {
194
234
  * render options
195
235
  */
196
236
  async render(opts) {
197
- const { inlineCriticalCss = true, url } = opts;
198
- if (opts.publicPath && opts.documentFilePath && url !== undefined) {
199
- const pathname = canParseUrl(url) ? new URL(url).pathname : url;
200
- // Remove leading forward slash.
201
- const pagePath = resolve(opts.publicPath, pathname.substring(1), 'index.html');
202
- if (pagePath !== resolve(opts.documentFilePath)) {
203
- // View path doesn't match with prerender path.
204
- const pageIsSSG = this.pageIsSSG.get(pagePath);
205
- if (pageIsSSG === undefined) {
206
- if (await exists(pagePath)) {
207
- const content = await fs.promises.readFile(pagePath, 'utf-8');
208
- const isSSG = SSG_MARKER_REGEXP.test(content);
209
- this.pageIsSSG.set(pagePath, isSSG);
210
- if (isSSG) {
211
- return content;
212
- }
213
- }
214
- else {
215
- this.pageIsSSG.set(pagePath, false);
237
+ const enablePeformanceProfiler = this.options?.enablePeformanceProfiler;
238
+ const runMethod = enablePeformanceProfiler
239
+ ? runMethodAndMeasurePerf
240
+ : noopRunMethodAndMeasurePerf;
241
+ let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));
242
+ if (html === undefined) {
243
+ html = await runMethod('Render Page', () => this.renderApplication(opts));
244
+ if (opts.inlineCriticalCss !== false) {
245
+ const { content, errors, warnings } = await runMethod('Inline Critical CSS', () =>
246
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
247
+ this.inlineCriticalCss(html, opts));
248
+ html = content;
249
+ // eslint-disable-next-line no-console
250
+ warnings?.forEach((m) => console.warn(m));
251
+ // eslint-disable-next-line no-console
252
+ errors?.forEach((m) => console.error(m));
253
+ }
254
+ }
255
+ if (enablePeformanceProfiler) {
256
+ printPerformanceLogs();
257
+ }
258
+ return html;
259
+ }
260
+ inlineCriticalCss(html, opts) {
261
+ return this.inlineCriticalCssProcessor.process(html, {
262
+ outputPath: opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : ''),
263
+ });
264
+ }
265
+ async retrieveSSGPage(opts) {
266
+ const { publicPath, documentFilePath, url } = opts;
267
+ if (!publicPath || !documentFilePath || url === undefined) {
268
+ return undefined;
269
+ }
270
+ const pathname = canParseUrl(url) ? new URL(url).pathname : url;
271
+ // Remove leading forward slash.
272
+ const pagePath = resolve(publicPath, pathname.substring(1), 'index.html');
273
+ if (pagePath !== resolve(documentFilePath)) {
274
+ // View path doesn't match with prerender path.
275
+ const pageIsSSG = this.pageIsSSG.get(pagePath);
276
+ if (pageIsSSG === undefined) {
277
+ if (await exists(pagePath)) {
278
+ const content = await fs.promises.readFile(pagePath, 'utf-8');
279
+ const isSSG = SSG_MARKER_REGEXP.test(content);
280
+ this.pageIsSSG.set(pagePath, isSSG);
281
+ if (isSSG) {
282
+ return content;
216
283
  }
217
284
  }
218
- else if (pageIsSSG) {
219
- // Serve pre-rendered page.
220
- return fs.promises.readFile(pagePath, 'utf-8');
285
+ else {
286
+ this.pageIsSSG.set(pagePath, false);
221
287
  }
222
288
  }
289
+ else if (pageIsSSG) {
290
+ // Serve pre-rendered page.
291
+ return fs.promises.readFile(pagePath, 'utf-8');
292
+ }
223
293
  }
224
- // if opts.document dosen't exist then opts.documentFilePath must
294
+ return undefined;
295
+ }
296
+ async renderApplication(opts) {
225
297
  const extraProviders = [
226
298
  { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },
227
299
  ...(opts.providers ?? []),
228
- ...this.providers,
300
+ ...(this.options?.providers ?? []),
229
301
  ];
230
302
  let document = opts.document;
231
303
  if (!document && opts.documentFilePath) {
@@ -240,24 +312,13 @@ class CommonEngine {
240
312
  },
241
313
  });
242
314
  }
243
- const moduleOrFactory = this.bootstrap || opts.bootstrap;
315
+ const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;
244
316
  if (!moduleOrFactory) {
245
317
  throw new Error('A module or bootstrap option must be provided.');
246
318
  }
247
- const html = await (isBootstrapFn(moduleOrFactory)
319
+ return isBootstrapFn(moduleOrFactory)
248
320
  ? renderApplication(moduleOrFactory, { platformProviders: extraProviders })
249
- : renderModule(moduleOrFactory, { extraProviders }));
250
- if (!inlineCriticalCss) {
251
- return html;
252
- }
253
- const { content, errors, warnings } = await this.inlineCriticalCssProcessor.process(html, {
254
- outputPath: opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : ''),
255
- });
256
- // eslint-disable-next-line no-console
257
- warnings?.forEach((m) => console.warn(m));
258
- // eslint-disable-next-line no-console
259
- errors?.forEach((m) => console.error(m));
260
- return content;
321
+ : renderModule(moduleOrFactory, { extraProviders });
261
322
  }
262
323
  /** Retrieve the document from the cache or the filesystem */
263
324
  async getDocument(filePath) {
@@ -1 +1 @@
1
- {"version":3,"file":"ssr.mjs","sources":["../../../../../../../packages/angular/ssr/src/inline-css-processor.ts","../../../../../../../packages/angular/ssr/src/common-engine.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport Critters from 'critters';\nimport { readFile } from 'node:fs/promises';\n\n/**\n * Pattern used to extract the media query set by Critters in an `onload` handler.\n */\nconst MEDIA_SET_HANDLER_PATTERN = /^this\\.media=[\"'](.*)[\"'];?$/;\n\n/**\n * Name of the attribute used to save the Critters media query so it can be re-assigned on load.\n */\nconst CSP_MEDIA_ATTR = 'ngCspMedia';\n\n/**\n * Script text used to change the media value of the link tags.\n */\nconst LINK_LOAD_SCRIPT_CONTENT = [\n `(() => {`,\n // Save the `children` in a variable since they're a live DOM node collection.\n // We iterate over the direct descendants, instead of going through a `querySelectorAll`,\n // because we know that the tags will be directly inside the `head`.\n ` const children = document.head.children;`,\n // Declare `onLoad` outside the loop to avoid leaking memory.\n // Can't be an arrow function, because we need `this` to refer to the DOM node.\n ` function onLoad() {this.media = this.getAttribute('${CSP_MEDIA_ATTR}');}`,\n // Has to use a plain for loop, because some browsers don't support\n // `forEach` on `children` which is a `HTMLCollection`.\n ` for (let i = 0; i < children.length; i++) {`,\n ` const child = children[i];`,\n ` child.hasAttribute('${CSP_MEDIA_ATTR}') && child.addEventListener('load', onLoad);`,\n ` }`,\n `})();`,\n].join('\\n');\n\nexport interface InlineCriticalCssProcessOptions {\n outputPath?: string;\n}\n\nexport interface InlineCriticalCssProcessorOptions {\n minify?: boolean;\n deployUrl?: string;\n}\n\nexport interface InlineCriticalCssResult {\n content: string;\n warnings?: string[];\n errors?: string[];\n}\n\n/** Partial representation of an `HTMLElement`. */\ninterface PartialHTMLElement {\n getAttribute(name: string): string | null;\n setAttribute(name: string, value: string): void;\n hasAttribute(name: string): boolean;\n removeAttribute(name: string): void;\n appendChild(child: PartialHTMLElement): void;\n remove(): void;\n name: string;\n textContent: string;\n tagName: string | null;\n children: PartialHTMLElement[];\n next: PartialHTMLElement | null;\n prev: PartialHTMLElement | null;\n}\n\n/** Partial representation of an HTML `Document`. */\ninterface PartialDocument {\n head: PartialHTMLElement;\n createElement(tagName: string): PartialHTMLElement;\n querySelector(selector: string): PartialHTMLElement | null;\n}\n\n/** Signature of the `Critters.embedLinkedStylesheet` method. */\ntype EmbedLinkedStylesheetFn = (\n link: PartialHTMLElement,\n document: PartialDocument,\n) => Promise<unknown>;\n\nclass CrittersExtended extends Critters {\n readonly warnings: string[] = [];\n readonly errors: string[] = [];\n private initialEmbedLinkedStylesheet: EmbedLinkedStylesheetFn;\n private addedCspScriptsDocuments = new WeakSet<PartialDocument>();\n private documentNonces = new WeakMap<PartialDocument, string | null>();\n\n // Inherited from `Critters`, but not exposed in the typings.\n protected declare embedLinkedStylesheet: EmbedLinkedStylesheetFn;\n\n constructor(\n readonly optionsExtended: InlineCriticalCssProcessorOptions & InlineCriticalCssProcessOptions,\n private readonly resourceCache: Map<string, string>,\n ) {\n super({\n logger: {\n warn: (s: string) => this.warnings.push(s),\n error: (s: string) => this.errors.push(s),\n info: () => {},\n },\n logLevel: 'warn',\n path: optionsExtended.outputPath,\n publicPath: optionsExtended.deployUrl,\n compress: !!optionsExtended.minify,\n pruneSource: false,\n reduceInlineStyles: false,\n mergeStylesheets: false,\n // Note: if `preload` changes to anything other than `media`, the logic in\n // `embedLinkedStylesheetOverride` will have to be updated.\n preload: 'media',\n noscriptFallback: true,\n inlineFonts: true,\n });\n\n // We can't use inheritance to override `embedLinkedStylesheet`, because it's not declared in\n // the `Critters` .d.ts which means that we can't call the `super` implementation. TS doesn't\n // allow for `super` to be cast to a different type.\n this.initialEmbedLinkedStylesheet = this.embedLinkedStylesheet;\n this.embedLinkedStylesheet = this.embedLinkedStylesheetOverride;\n }\n\n public override async readFile(path: string): Promise<string> {\n let resourceContent = this.resourceCache.get(path);\n if (resourceContent === undefined) {\n resourceContent = await readFile(path, 'utf-8');\n this.resourceCache.set(path, resourceContent);\n }\n\n return resourceContent;\n }\n\n /**\n * Override of the Critters `embedLinkedStylesheet` method\n * that makes it work with Angular's CSP APIs.\n */\n private embedLinkedStylesheetOverride: EmbedLinkedStylesheetFn = async (link, document) => {\n if (link.getAttribute('media') === 'print' && link.next?.name === 'noscript') {\n // Workaround for https://github.com/GoogleChromeLabs/critters/issues/64\n // NB: this is only needed for the webpack based builders.\n const media = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);\n if (media) {\n link.removeAttribute('onload');\n link.setAttribute('media', media[1]);\n link?.next?.remove();\n }\n }\n\n const returnValue = await this.initialEmbedLinkedStylesheet(link, document);\n const cspNonce = this.findCspNonce(document);\n\n if (cspNonce) {\n const crittersMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);\n\n if (crittersMedia) {\n // If there's a Critters-generated `onload` handler and the file has an Angular CSP nonce,\n // we have to remove the handler, because it's incompatible with CSP. We save the value\n // in a different attribute and we generate a script tag with the nonce that uses\n // `addEventListener` to apply the media query instead.\n link.removeAttribute('onload');\n link.setAttribute(CSP_MEDIA_ATTR, crittersMedia[1]);\n this.conditionallyInsertCspLoadingScript(document, cspNonce);\n }\n\n // Ideally we would hook in at the time Critters inserts the `style` tags, but there isn't\n // a way of doing that at the moment so we fall back to doing it any time a `link` tag is\n // inserted. We mitigate it by only iterating the direct children of the `<head>` which\n // should be pretty shallow.\n document.head.children.forEach((child) => {\n if (child.tagName === 'style' && !child.hasAttribute('nonce')) {\n child.setAttribute('nonce', cspNonce);\n }\n });\n }\n\n return returnValue;\n };\n\n /**\n * Finds the CSP nonce for a specific document.\n */\n private findCspNonce(document: PartialDocument): string | null {\n if (this.documentNonces.has(document)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.documentNonces.get(document)!;\n }\n\n // HTML attribute are case-insensitive, but the parser used by Critters is case-sensitive.\n const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]');\n const cspNonce =\n nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce') || null;\n\n this.documentNonces.set(document, cspNonce);\n\n return cspNonce;\n }\n\n /**\n * Inserts the `script` tag that swaps the critical CSS at runtime,\n * if one hasn't been inserted into the document already.\n */\n private conditionallyInsertCspLoadingScript(document: PartialDocument, nonce: string): void {\n if (this.addedCspScriptsDocuments.has(document)) {\n return;\n }\n\n if (document.head.textContent.includes(LINK_LOAD_SCRIPT_CONTENT)) {\n // Script was already added during the build.\n this.addedCspScriptsDocuments.add(document);\n\n return;\n }\n\n const script = document.createElement('script');\n script.setAttribute('nonce', nonce);\n script.textContent = LINK_LOAD_SCRIPT_CONTENT;\n // Append the script to the head since it needs to\n // run as early as possible, after the `link` tags.\n document.head.appendChild(script);\n this.addedCspScriptsDocuments.add(document);\n }\n}\n\nexport class InlineCriticalCssProcessor {\n private readonly resourceCache = new Map<string, string>();\n\n constructor(protected readonly options: InlineCriticalCssProcessorOptions) {}\n\n async process(\n html: string,\n options: InlineCriticalCssProcessOptions,\n ): Promise<InlineCriticalCssResult> {\n const critters = new CrittersExtended({ ...this.options, ...options }, this.resourceCache);\n const content = await critters.process(html);\n\n return {\n content,\n errors: critters.errors.length ? critters.errors : undefined,\n warnings: critters.warnings.length ? critters.warnings : undefined,\n };\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport { ApplicationRef, StaticProvider, Type } from '@angular/core';\nimport {\n INITIAL_CONFIG,\n renderApplication,\n renderModule,\n ɵSERVER_CONTEXT,\n} from '@angular/platform-server';\nimport * as fs from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { URL } from 'node:url';\nimport { InlineCriticalCssProcessor } from './inline-css-processor';\n\nconst SSG_MARKER_REGEXP = /ng-server-context=[\"']\\w*\\|?ssg\\|?\\w*[\"']/;\n\nexport interface CommonEngineRenderOptions {\n bootstrap?: Type<{}> | (() => Promise<ApplicationRef>);\n providers?: StaticProvider[];\n url?: string;\n document?: string;\n documentFilePath?: string;\n /**\n * Reduce render blocking requests by inlining critical CSS.\n * Defaults to true.\n */\n inlineCriticalCss?: boolean;\n /**\n * Base path location of index file.\n * Defaults to the 'documentFilePath' dirname when not provided.\n */\n publicPath?: string;\n}\n\n/**\n * A common rendering engine utility. This abstracts the logic\n * for handling the platformServer compiler, the module cache, and\n * the document loader\n */\nexport class CommonEngine {\n private readonly templateCache = new Map<string, string>();\n private readonly inlineCriticalCssProcessor: InlineCriticalCssProcessor;\n private readonly pageIsSSG = new Map<string, boolean>();\n\n constructor(\n private bootstrap?: Type<{}> | (() => Promise<ApplicationRef>),\n private providers: StaticProvider[] = [],\n ) {\n this.inlineCriticalCssProcessor = new InlineCriticalCssProcessor({\n minify: false,\n });\n }\n\n /**\n * Render an HTML document for a specific URL with specified\n * render options\n */\n async render(opts: CommonEngineRenderOptions): Promise<string> {\n const { inlineCriticalCss = true, url } = opts;\n\n if (opts.publicPath && opts.documentFilePath && url !== undefined) {\n const pathname = canParseUrl(url) ? new URL(url).pathname : url;\n // Remove leading forward slash.\n const pagePath = resolve(opts.publicPath, pathname.substring(1), 'index.html');\n\n if (pagePath !== resolve(opts.documentFilePath)) {\n // View path doesn't match with prerender path.\n const pageIsSSG = this.pageIsSSG.get(pagePath);\n if (pageIsSSG === undefined) {\n if (await exists(pagePath)) {\n const content = await fs.promises.readFile(pagePath, 'utf-8');\n const isSSG = SSG_MARKER_REGEXP.test(content);\n this.pageIsSSG.set(pagePath, isSSG);\n\n if (isSSG) {\n return content;\n }\n } else {\n this.pageIsSSG.set(pagePath, false);\n }\n } else if (pageIsSSG) {\n // Serve pre-rendered page.\n return fs.promises.readFile(pagePath, 'utf-8');\n }\n }\n }\n\n // if opts.document dosen't exist then opts.documentFilePath must\n const extraProviders: StaticProvider[] = [\n { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n ...(opts.providers ?? []),\n ...this.providers,\n ];\n\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = await this.getDocument(opts.documentFilePath);\n }\n\n if (document) {\n extraProviders.push({\n provide: INITIAL_CONFIG,\n useValue: {\n document,\n url: opts.url,\n },\n });\n }\n\n const moduleOrFactory = this.bootstrap || opts.bootstrap;\n if (!moduleOrFactory) {\n throw new Error('A module or bootstrap option must be provided.');\n }\n\n const html = await (isBootstrapFn(moduleOrFactory)\n ? renderApplication(moduleOrFactory, { platformProviders: extraProviders })\n : renderModule(moduleOrFactory, { extraProviders }));\n\n if (!inlineCriticalCss) {\n return html;\n }\n\n const { content, errors, warnings } = await this.inlineCriticalCssProcessor.process(html, {\n outputPath: opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : ''),\n });\n\n // eslint-disable-next-line no-console\n warnings?.forEach((m) => console.warn(m));\n // eslint-disable-next-line no-console\n errors?.forEach((m) => console.error(m));\n\n return content;\n }\n\n /** Retrieve the document from the cache or the filesystem */\n private async getDocument(filePath: string): Promise<string> {\n let doc = this.templateCache.get(filePath);\n\n if (!doc) {\n doc = await fs.promises.readFile(filePath, 'utf-8');\n this.templateCache.set(filePath, doc);\n }\n\n return doc;\n }\n}\n\nasync function exists(path: fs.PathLike): Promise<boolean> {\n try {\n await fs.promises.access(path, fs.constants.F_OK);\n\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isBootstrapFn(value: unknown): value is () => Promise<ApplicationRef> {\n // We can differentiate between a module and a bootstrap function by reading compiler-generated `ɵmod` static property:\n return typeof value === 'function' && !('ɵmod' in value);\n}\n\n// The below can be removed in favor of URL.canParse() when Node.js 18 is dropped\nfunction canParseUrl(url: string): boolean {\n try {\n return !!new URL(url);\n } catch {\n return false;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssr.mjs","sources":["../../../../../../../packages/angular/ssr/src/inline-css-processor.ts","../../../../../../../packages/angular/ssr/src/peformance-profiler.ts","../../../../../../../packages/angular/ssr/src/common-engine.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport Critters from 'critters';\nimport { readFile } from 'node:fs/promises';\n\n/**\n * Pattern used to extract the media query set by Critters in an `onload` handler.\n */\nconst MEDIA_SET_HANDLER_PATTERN = /^this\\.media=[\"'](.*)[\"'];?$/;\n\n/**\n * Name of the attribute used to save the Critters media query so it can be re-assigned on load.\n */\nconst CSP_MEDIA_ATTR = 'ngCspMedia';\n\n/**\n * Script text used to change the media value of the link tags.\n */\nconst LINK_LOAD_SCRIPT_CONTENT = [\n `(() => {`,\n // Save the `children` in a variable since they're a live DOM node collection.\n // We iterate over the direct descendants, instead of going through a `querySelectorAll`,\n // because we know that the tags will be directly inside the `head`.\n ` const children = document.head.children;`,\n // Declare `onLoad` outside the loop to avoid leaking memory.\n // Can't be an arrow function, because we need `this` to refer to the DOM node.\n ` function onLoad() {this.media = this.getAttribute('${CSP_MEDIA_ATTR}');}`,\n // Has to use a plain for loop, because some browsers don't support\n // `forEach` on `children` which is a `HTMLCollection`.\n ` for (let i = 0; i < children.length; i++) {`,\n ` const child = children[i];`,\n ` child.hasAttribute('${CSP_MEDIA_ATTR}') && child.addEventListener('load', onLoad);`,\n ` }`,\n `})();`,\n].join('\\n');\n\nexport interface InlineCriticalCssProcessOptions {\n outputPath?: string;\n}\n\nexport interface InlineCriticalCssProcessorOptions {\n minify?: boolean;\n deployUrl?: string;\n}\n\nexport interface InlineCriticalCssResult {\n content: string;\n warnings?: string[];\n errors?: string[];\n}\n\n/** Partial representation of an `HTMLElement`. */\ninterface PartialHTMLElement {\n getAttribute(name: string): string | null;\n setAttribute(name: string, value: string): void;\n hasAttribute(name: string): boolean;\n removeAttribute(name: string): void;\n appendChild(child: PartialHTMLElement): void;\n remove(): void;\n name: string;\n textContent: string;\n tagName: string | null;\n children: PartialHTMLElement[];\n next: PartialHTMLElement | null;\n prev: PartialHTMLElement | null;\n}\n\n/** Partial representation of an HTML `Document`. */\ninterface PartialDocument {\n head: PartialHTMLElement;\n createElement(tagName: string): PartialHTMLElement;\n querySelector(selector: string): PartialHTMLElement | null;\n}\n\n/** Signature of the `Critters.embedLinkedStylesheet` method. */\ntype EmbedLinkedStylesheetFn = (\n link: PartialHTMLElement,\n document: PartialDocument,\n) => Promise<unknown>;\n\nclass CrittersExtended extends Critters {\n readonly warnings: string[] = [];\n readonly errors: string[] = [];\n private initialEmbedLinkedStylesheet: EmbedLinkedStylesheetFn;\n private addedCspScriptsDocuments = new WeakSet<PartialDocument>();\n private documentNonces = new WeakMap<PartialDocument, string | null>();\n\n // Inherited from `Critters`, but not exposed in the typings.\n protected declare embedLinkedStylesheet: EmbedLinkedStylesheetFn;\n\n constructor(\n readonly optionsExtended: InlineCriticalCssProcessorOptions & InlineCriticalCssProcessOptions,\n private readonly resourceCache: Map<string, string>,\n ) {\n super({\n logger: {\n warn: (s: string) => this.warnings.push(s),\n error: (s: string) => this.errors.push(s),\n info: () => {},\n },\n logLevel: 'warn',\n path: optionsExtended.outputPath,\n publicPath: optionsExtended.deployUrl,\n compress: !!optionsExtended.minify,\n pruneSource: false,\n reduceInlineStyles: false,\n mergeStylesheets: false,\n // Note: if `preload` changes to anything other than `media`, the logic in\n // `embedLinkedStylesheetOverride` will have to be updated.\n preload: 'media',\n noscriptFallback: true,\n inlineFonts: true,\n });\n\n // We can't use inheritance to override `embedLinkedStylesheet`, because it's not declared in\n // the `Critters` .d.ts which means that we can't call the `super` implementation. TS doesn't\n // allow for `super` to be cast to a different type.\n this.initialEmbedLinkedStylesheet = this.embedLinkedStylesheet;\n this.embedLinkedStylesheet = this.embedLinkedStylesheetOverride;\n }\n\n public override async readFile(path: string): Promise<string> {\n let resourceContent = this.resourceCache.get(path);\n if (resourceContent === undefined) {\n resourceContent = await readFile(path, 'utf-8');\n this.resourceCache.set(path, resourceContent);\n }\n\n return resourceContent;\n }\n\n /**\n * Override of the Critters `embedLinkedStylesheet` method\n * that makes it work with Angular's CSP APIs.\n */\n private embedLinkedStylesheetOverride: EmbedLinkedStylesheetFn = async (link, document) => {\n if (link.getAttribute('media') === 'print' && link.next?.name === 'noscript') {\n // Workaround for https://github.com/GoogleChromeLabs/critters/issues/64\n // NB: this is only needed for the webpack based builders.\n const media = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);\n if (media) {\n link.removeAttribute('onload');\n link.setAttribute('media', media[1]);\n link?.next?.remove();\n }\n }\n\n const returnValue = await this.initialEmbedLinkedStylesheet(link, document);\n const cspNonce = this.findCspNonce(document);\n\n if (cspNonce) {\n const crittersMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);\n\n if (crittersMedia) {\n // If there's a Critters-generated `onload` handler and the file has an Angular CSP nonce,\n // we have to remove the handler, because it's incompatible with CSP. We save the value\n // in a different attribute and we generate a script tag with the nonce that uses\n // `addEventListener` to apply the media query instead.\n link.removeAttribute('onload');\n link.setAttribute(CSP_MEDIA_ATTR, crittersMedia[1]);\n this.conditionallyInsertCspLoadingScript(document, cspNonce);\n }\n\n // Ideally we would hook in at the time Critters inserts the `style` tags, but there isn't\n // a way of doing that at the moment so we fall back to doing it any time a `link` tag is\n // inserted. We mitigate it by only iterating the direct children of the `<head>` which\n // should be pretty shallow.\n document.head.children.forEach((child) => {\n if (child.tagName === 'style' && !child.hasAttribute('nonce')) {\n child.setAttribute('nonce', cspNonce);\n }\n });\n }\n\n return returnValue;\n };\n\n /**\n * Finds the CSP nonce for a specific document.\n */\n private findCspNonce(document: PartialDocument): string | null {\n if (this.documentNonces.has(document)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.documentNonces.get(document)!;\n }\n\n // HTML attribute are case-insensitive, but the parser used by Critters is case-sensitive.\n const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]');\n const cspNonce =\n nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce') || null;\n\n this.documentNonces.set(document, cspNonce);\n\n return cspNonce;\n }\n\n /**\n * Inserts the `script` tag that swaps the critical CSS at runtime,\n * if one hasn't been inserted into the document already.\n */\n private conditionallyInsertCspLoadingScript(document: PartialDocument, nonce: string): void {\n if (this.addedCspScriptsDocuments.has(document)) {\n return;\n }\n\n if (document.head.textContent.includes(LINK_LOAD_SCRIPT_CONTENT)) {\n // Script was already added during the build.\n this.addedCspScriptsDocuments.add(document);\n\n return;\n }\n\n const script = document.createElement('script');\n script.setAttribute('nonce', nonce);\n script.textContent = LINK_LOAD_SCRIPT_CONTENT;\n // Append the script to the head since it needs to\n // run as early as possible, after the `link` tags.\n document.head.appendChild(script);\n this.addedCspScriptsDocuments.add(document);\n }\n}\n\nexport class InlineCriticalCssProcessor {\n private readonly resourceCache = new Map<string, string>();\n\n constructor(protected readonly options: InlineCriticalCssProcessorOptions) {}\n\n async process(\n html: string,\n options: InlineCriticalCssProcessOptions,\n ): Promise<InlineCriticalCssResult> {\n const critters = new CrittersExtended({ ...this.options, ...options }, this.resourceCache);\n const content = await critters.process(html);\n\n return {\n content,\n errors: critters.errors.length ? critters.errors : undefined,\n warnings: critters.warnings.length ? critters.warnings : undefined,\n };\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nconst PERFORMANCE_MARK_PREFIX = '🅰️';\n\nexport function printPerformanceLogs(): void {\n let maxWordLength = 0;\n const benchmarks: [step: string, value: string][] = [];\n\n for (const { name, duration } of performance.getEntriesByType('measure')) {\n if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {\n continue;\n }\n\n // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`\n const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';\n if (step.length > maxWordLength) {\n maxWordLength = step.length;\n }\n\n benchmarks.push([step, `${duration.toFixed(1)}ms`]);\n performance.clearMeasures(name);\n }\n\n /* eslint-disable no-console */\n console.log('********** Performance results **********');\n for (const [step, value] of benchmarks) {\n const spaces = maxWordLength - step.length + 5;\n console.log(step + ' '.repeat(spaces) + value);\n }\n console.log('*****************************************');\n /* eslint-enable no-console */\n}\n\nexport async function runMethodAndMeasurePerf<T>(\n label: string,\n asyncMethod: () => Promise<T>,\n): Promise<T> {\n const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;\n const startLabel = `start:${labelName}`;\n const endLabel = `end:${labelName}`;\n\n try {\n performance.mark(startLabel);\n\n return await asyncMethod();\n } finally {\n performance.mark(endLabel);\n performance.measure(labelName, startLabel, endLabel);\n performance.clearMarks(startLabel);\n performance.clearMarks(endLabel);\n }\n}\n\nexport function noopRunMethodAndMeasurePerf<T>(\n label: string,\n asyncMethod: () => Promise<T>,\n): Promise<T> {\n return asyncMethod();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport { ApplicationRef, StaticProvider, Type } from '@angular/core';\nimport {\n INITIAL_CONFIG,\n renderApplication,\n renderModule,\n ɵSERVER_CONTEXT,\n} from '@angular/platform-server';\nimport * as fs from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { URL } from 'node:url';\nimport { InlineCriticalCssProcessor, InlineCriticalCssResult } from './inline-css-processor';\nimport {\n noopRunMethodAndMeasurePerf,\n printPerformanceLogs,\n runMethodAndMeasurePerf,\n} from './peformance-profiler';\n\nconst SSG_MARKER_REGEXP = /ng-server-context=[\"']\\w*\\|?ssg\\|?\\w*[\"']/;\n\nexport interface CommonEngineOptions {\n /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */\n bootstrap?: Type<{}> | (() => Promise<ApplicationRef>);\n /** A set of platform level providers for all requests. */\n providers?: StaticProvider[];\n /** Enable request performance profiling data collection and printing the results in the server console. */\n enablePeformanceProfiler?: boolean;\n}\n\nexport interface CommonEngineRenderOptions {\n /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */\n bootstrap?: Type<{}> | (() => Promise<ApplicationRef>);\n /** A set of platform level providers for the current request. */\n providers?: StaticProvider[];\n url?: string;\n document?: string;\n documentFilePath?: string;\n /**\n * Reduce render blocking requests by inlining critical CSS.\n * Defaults to true.\n */\n inlineCriticalCss?: boolean;\n /**\n * Base path location of index file.\n * Defaults to the 'documentFilePath' dirname when not provided.\n */\n publicPath?: string;\n}\n\n/**\n * A common engine to use to server render an application.\n */\n\nexport class CommonEngine {\n private readonly templateCache = new Map<string, string>();\n private readonly inlineCriticalCssProcessor: InlineCriticalCssProcessor;\n private readonly pageIsSSG = new Map<string, boolean>();\n\n constructor(private options?: CommonEngineOptions) {\n this.inlineCriticalCssProcessor = new InlineCriticalCssProcessor({\n minify: false,\n });\n }\n\n /**\n * Render an HTML document for a specific URL with specified\n * render options\n */\n async render(opts: CommonEngineRenderOptions): Promise<string> {\n const enablePeformanceProfiler = this.options?.enablePeformanceProfiler;\n\n const runMethod = enablePeformanceProfiler\n ? runMethodAndMeasurePerf\n : noopRunMethodAndMeasurePerf;\n\n let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));\n\n if (html === undefined) {\n html = await runMethod('Render Page', () => this.renderApplication(opts));\n\n if (opts.inlineCriticalCss !== false) {\n const { content, errors, warnings } = await runMethod('Inline Critical CSS', () =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.inlineCriticalCss(html!, opts),\n );\n\n html = content;\n\n // eslint-disable-next-line no-console\n warnings?.forEach((m) => console.warn(m));\n // eslint-disable-next-line no-console\n errors?.forEach((m) => console.error(m));\n }\n }\n\n if (enablePeformanceProfiler) {\n printPerformanceLogs();\n }\n\n return html;\n }\n\n private inlineCriticalCss(\n html: string,\n opts: CommonEngineRenderOptions,\n ): Promise<InlineCriticalCssResult> {\n return this.inlineCriticalCssProcessor.process(html, {\n outputPath: opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : ''),\n });\n }\n\n private async retrieveSSGPage(opts: CommonEngineRenderOptions): Promise<string | undefined> {\n const { publicPath, documentFilePath, url } = opts;\n if (!publicPath || !documentFilePath || url === undefined) {\n return undefined;\n }\n\n const pathname = canParseUrl(url) ? new URL(url).pathname : url;\n // Remove leading forward slash.\n const pagePath = resolve(publicPath, pathname.substring(1), 'index.html');\n\n if (pagePath !== resolve(documentFilePath)) {\n // View path doesn't match with prerender path.\n const pageIsSSG = this.pageIsSSG.get(pagePath);\n if (pageIsSSG === undefined) {\n if (await exists(pagePath)) {\n const content = await fs.promises.readFile(pagePath, 'utf-8');\n const isSSG = SSG_MARKER_REGEXP.test(content);\n this.pageIsSSG.set(pagePath, isSSG);\n\n if (isSSG) {\n return content;\n }\n } else {\n this.pageIsSSG.set(pagePath, false);\n }\n } else if (pageIsSSG) {\n // Serve pre-rendered page.\n return fs.promises.readFile(pagePath, 'utf-8');\n }\n }\n\n return undefined;\n }\n\n private async renderApplication(opts: CommonEngineRenderOptions): Promise<string> {\n const extraProviders: StaticProvider[] = [\n { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n ...(opts.providers ?? []),\n ...(this.options?.providers ?? []),\n ];\n\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = await this.getDocument(opts.documentFilePath);\n }\n\n if (document) {\n extraProviders.push({\n provide: INITIAL_CONFIG,\n useValue: {\n document,\n url: opts.url,\n },\n });\n }\n\n const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;\n if (!moduleOrFactory) {\n throw new Error('A module or bootstrap option must be provided.');\n }\n\n return isBootstrapFn(moduleOrFactory)\n ? renderApplication(moduleOrFactory, { platformProviders: extraProviders })\n : renderModule(moduleOrFactory, { extraProviders });\n }\n\n /** Retrieve the document from the cache or the filesystem */\n private async getDocument(filePath: string): Promise<string> {\n let doc = this.templateCache.get(filePath);\n\n if (!doc) {\n doc = await fs.promises.readFile(filePath, 'utf-8');\n this.templateCache.set(filePath, doc);\n }\n\n return doc;\n }\n}\n\nasync function exists(path: fs.PathLike): Promise<boolean> {\n try {\n await fs.promises.access(path, fs.constants.F_OK);\n\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isBootstrapFn(value: unknown): value is () => Promise<ApplicationRef> {\n // We can differentiate between a module and a bootstrap function by reading compiler-generated `ɵmod` static property:\n return typeof value === 'function' && !('ɵmod' in value);\n}\n\n// The below can be removed in favor of URL.canParse() when Node.js 18 is dropped\nfunction canParseUrl(url: string): boolean {\n try {\n return !!new URL(url);\n } catch {\n return false;\n }\n}\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -3,28 +3,39 @@ import { StaticProvider } from '@angular/core';
3
3
  import { Type } from '@angular/core';
4
4
 
5
5
  /**
6
- * A common rendering engine utility. This abstracts the logic
7
- * for handling the platformServer compiler, the module cache, and
8
- * the document loader
6
+ * A common engine to use to server render an application.
9
7
  */
10
8
  export declare class CommonEngine {
11
- private bootstrap?;
12
- private providers;
9
+ private options?;
13
10
  private readonly templateCache;
14
11
  private readonly inlineCriticalCssProcessor;
15
12
  private readonly pageIsSSG;
16
- constructor(bootstrap?: Type<{}> | (() => Promise<ApplicationRef>) | undefined, providers?: StaticProvider[]);
13
+ constructor(options?: CommonEngineOptions | undefined);
17
14
  /**
18
15
  * Render an HTML document for a specific URL with specified
19
16
  * render options
20
17
  */
21
18
  render(opts: CommonEngineRenderOptions): Promise<string>;
19
+ private inlineCriticalCss;
20
+ private retrieveSSGPage;
21
+ private renderApplication;
22
22
  /** Retrieve the document from the cache or the filesystem */
23
23
  private getDocument;
24
24
  }
25
25
 
26
+ export declare interface CommonEngineOptions {
27
+ /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */
28
+ bootstrap?: Type<{}> | (() => Promise<ApplicationRef>);
29
+ /** A set of platform level providers for all requests. */
30
+ providers?: StaticProvider[];
31
+ /** Enable request performance profiling data collection and printing the results in the server console. */
32
+ enablePeformanceProfiler?: boolean;
33
+ }
34
+
26
35
  export declare interface CommonEngineRenderOptions {
36
+ /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */
27
37
  bootstrap?: Type<{}> | (() => Promise<ApplicationRef>);
38
+ /** A set of platform level providers for the current request. */
28
39
  providers?: StaticProvider[];
29
40
  url?: string;
30
41
  document?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/ssr",
3
- "version": "17.0.0-next.6",
3
+ "version": "17.0.0-next.7",
4
4
  "description": "Angular server side rendering utilities",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/angular/angular-cli",