@angular/ssr 19.0.0-next.0 → 19.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/private_export.mjs +10 -0
- package/esm2022/public_api.mjs +1 -1
- package/esm2022/src/app-engine.mjs +18 -40
- package/esm2022/src/app.mjs +110 -28
- package/esm2022/src/assets.mjs +1 -1
- package/esm2022/src/routes/ng-routes.mjs +6 -4
- package/fesm2022/ssr.mjs +603 -6
- package/fesm2022/ssr.mjs.map +1 -1
- package/index.d.ts +258 -0
- package/package.json +8 -8
- package/esm2022/src/render.mjs +0 -74
|
@@ -0,0 +1,10 @@
|
|
|
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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
export { getRoutesFromAngularRouterConfig as ɵgetRoutesFromAngularRouterConfig } from './src/routes/ng-routes';
|
|
9
|
+
export { ServerRenderContext as ɵServerRenderContext, getOrCreateAngularServerApp as ɵgetOrCreateAngularServerApp, destroyAngularServerApp as ɵdestroyAngularServerApp, } from './src/app';
|
|
10
|
+
export { setAngularAppManifest as ɵsetAngularAppManifest, setAngularAppEngineManifest as ɵsetAngularAppEngineManifest, } from './src/manifest';
|
package/esm2022/public_api.mjs
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
8
|
export { CommonEngine, } from './src/common-engine/common-engine';
|
|
9
|
-
export
|
|
9
|
+
export * from './private_export';
|
|
@@ -16,38 +16,30 @@ import { getAngularAppEngineManifest } from './manifest';
|
|
|
16
16
|
export class AngularAppEngine {
|
|
17
17
|
/**
|
|
18
18
|
* Hooks for extending or modifying the behavior of the server application.
|
|
19
|
-
*
|
|
19
|
+
* These hooks are used by the Angular CLI when running the development server and
|
|
20
|
+
* provide extensibility points for the application lifecycle.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
20
23
|
*/
|
|
21
24
|
static hooks = new Hooks();
|
|
22
25
|
/**
|
|
23
|
-
*
|
|
24
|
-
* This
|
|
26
|
+
* Provides access to the hooks for extending or modifying the server application's behavior.
|
|
27
|
+
* This allows attaching custom functionality to various server application lifecycle events.
|
|
28
|
+
*
|
|
25
29
|
* @internal
|
|
26
30
|
*/
|
|
27
31
|
get hooks() {
|
|
28
32
|
return AngularAppEngine.hooks;
|
|
29
33
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Specifies if the application is operating in development mode.
|
|
32
|
-
* This property controls the activation of features intended for production, such as caching mechanisms.
|
|
33
|
-
* @internal
|
|
34
|
-
*/
|
|
35
|
-
static isDevMode = false;
|
|
36
34
|
/**
|
|
37
35
|
* The manifest for the server application.
|
|
38
36
|
*/
|
|
39
37
|
manifest = getAngularAppEngineManifest();
|
|
40
38
|
/**
|
|
41
|
-
*
|
|
42
|
-
* Each instance represents an Angular server application.
|
|
43
|
-
*/
|
|
44
|
-
appsCache = new Map();
|
|
45
|
-
/**
|
|
46
|
-
* Renders an HTTP request using the appropriate Angular server application and returns a response.
|
|
39
|
+
* Renders a response for the given HTTP request using the server application.
|
|
47
40
|
*
|
|
48
|
-
* This method
|
|
49
|
-
* and
|
|
50
|
-
* the cache is bypassed and a new instance is created for each request.
|
|
41
|
+
* This method processes the request, determines the appropriate route and rendering context,
|
|
42
|
+
* and returns an HTTP response.
|
|
51
43
|
*
|
|
52
44
|
* If the request URL appears to be for a file (excluding `/index.html`), the method returns `null`.
|
|
53
45
|
* A request to `https://www.example.com/page/index.html` will render the Angular route
|
|
@@ -65,18 +57,9 @@ export class AngularAppEngine {
|
|
|
65
57
|
if (!entryPoint) {
|
|
66
58
|
return null;
|
|
67
59
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const { AngularServerApp } = await loadModule();
|
|
72
|
-
serverApp = new AngularServerApp({
|
|
73
|
-
isDevMode: AngularAppEngine.isDevMode,
|
|
74
|
-
hooks: this.hooks,
|
|
75
|
-
});
|
|
76
|
-
if (!AngularAppEngine.isDevMode) {
|
|
77
|
-
this.appsCache.set(locale, serverApp);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
60
|
+
const { ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp } = await entryPoint();
|
|
61
|
+
const serverApp = getOrCreateAngularServerApp();
|
|
62
|
+
serverApp.hooks = this.hooks;
|
|
80
63
|
return serverApp.render(request, requestContext);
|
|
81
64
|
}
|
|
82
65
|
/**
|
|
@@ -86,21 +69,16 @@ export class AngularAppEngine {
|
|
|
86
69
|
* If there is only one entry point available, it is returned regardless of the URL.
|
|
87
70
|
* Otherwise, the method extracts a potential locale identifier from the URL and looks up the corresponding entry point.
|
|
88
71
|
*
|
|
89
|
-
* @param url - The URL used to derive the locale and determine the entry point.
|
|
90
|
-
* @returns
|
|
91
|
-
*
|
|
92
|
-
* - The second element is a function that returns a promise resolving to an object with the `AngularServerApp` type.
|
|
93
|
-
*
|
|
94
|
-
* Returns `null` if no matching entry point is found for the extracted locale.
|
|
72
|
+
* @param url - The URL used to derive the locale and determine the appropriate entry point.
|
|
73
|
+
* @returns A function that returns a promise resolving to an object with the `EntryPointExports` type,
|
|
74
|
+
* or `undefined` if no matching entry point is found for the extracted locale.
|
|
95
75
|
*/
|
|
96
76
|
getEntryPointFromUrl(url) {
|
|
97
|
-
// Find bundle for locale
|
|
98
77
|
const { entryPoints, basePath } = this.manifest;
|
|
99
78
|
if (entryPoints.size === 1) {
|
|
100
|
-
return entryPoints.
|
|
79
|
+
return entryPoints.values().next().value;
|
|
101
80
|
}
|
|
102
81
|
const potentialLocale = getPotentialLocaleIdFromUrl(url, basePath);
|
|
103
|
-
|
|
104
|
-
return entryPoint ? [potentialLocale, entryPoint] : null;
|
|
82
|
+
return entryPoints.get(potentialLocale);
|
|
105
83
|
}
|
|
106
84
|
}
|
package/esm2022/src/app.mjs
CHANGED
|
@@ -5,56 +5,47 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
+
import { ɵConsole, ɵresetCompiledComponents } from '@angular/core';
|
|
9
|
+
import { ɵSERVER_CONTEXT as SERVER_CONTEXT } from '@angular/platform-server';
|
|
8
10
|
import { ServerAssets } from './assets';
|
|
11
|
+
import { Console } from './console';
|
|
9
12
|
import { Hooks } from './hooks';
|
|
10
13
|
import { getAngularAppManifest } from './manifest';
|
|
11
|
-
import { ServerRenderContext, render } from './render';
|
|
12
14
|
import { ServerRouter } from './routes/router';
|
|
15
|
+
import { REQUEST, REQUEST_CONTEXT, RESPONSE_INIT } from './tokens';
|
|
16
|
+
import { renderAngular } from './utils/ng';
|
|
17
|
+
/**
|
|
18
|
+
* Enum representing the different contexts in which server rendering can occur.
|
|
19
|
+
*/
|
|
20
|
+
export var ServerRenderContext;
|
|
21
|
+
(function (ServerRenderContext) {
|
|
22
|
+
ServerRenderContext["SSR"] = "ssr";
|
|
23
|
+
ServerRenderContext["SSG"] = "ssg";
|
|
24
|
+
ServerRenderContext["AppShell"] = "app-shell";
|
|
25
|
+
})(ServerRenderContext || (ServerRenderContext = {}));
|
|
13
26
|
/**
|
|
14
27
|
* Represents a locale-specific Angular server application managed by the server application engine.
|
|
15
28
|
*
|
|
16
29
|
* The `AngularServerApp` class handles server-side rendering and asset management for a specific locale.
|
|
17
30
|
*/
|
|
18
31
|
export class AngularServerApp {
|
|
19
|
-
options;
|
|
20
|
-
/**
|
|
21
|
-
* The manifest associated with this server application.
|
|
22
|
-
* @internal
|
|
23
|
-
*/
|
|
24
|
-
manifest = getAngularAppManifest();
|
|
25
32
|
/**
|
|
26
33
|
* Hooks for extending or modifying the behavior of the server application.
|
|
27
34
|
* This instance can be used to attach custom functionality to various events in the server application lifecycle.
|
|
28
|
-
* @internal
|
|
29
35
|
*/
|
|
30
|
-
hooks;
|
|
36
|
+
hooks = new Hooks();
|
|
31
37
|
/**
|
|
32
|
-
*
|
|
33
|
-
* This property controls the activation of features intended for production, such as caching mechanisms.
|
|
34
|
-
* @internal
|
|
38
|
+
* The manifest associated with this server application.
|
|
35
39
|
*/
|
|
36
|
-
|
|
40
|
+
manifest = getAngularAppManifest();
|
|
37
41
|
/**
|
|
38
42
|
* An instance of ServerAsset that handles server-side asset.
|
|
39
|
-
* @internal
|
|
40
43
|
*/
|
|
41
44
|
assets = new ServerAssets(this.manifest);
|
|
42
45
|
/**
|
|
43
46
|
* The router instance used for route matching and handling.
|
|
44
47
|
*/
|
|
45
48
|
router;
|
|
46
|
-
/**
|
|
47
|
-
* Creates a new `AngularServerApp` instance with the provided configuration options.
|
|
48
|
-
*
|
|
49
|
-
* @param options - The configuration options for the server application.
|
|
50
|
-
* - `isDevMode`: Flag indicating if the application is in development mode.
|
|
51
|
-
* - `hooks`: Optional hooks for customizing application behavior.
|
|
52
|
-
*/
|
|
53
|
-
constructor(options) {
|
|
54
|
-
this.options = options;
|
|
55
|
-
this.isDevMode = options.isDevMode ?? false;
|
|
56
|
-
this.hooks = options.hooks ?? new Hooks();
|
|
57
|
-
}
|
|
58
49
|
/**
|
|
59
50
|
* Renders a response for the given HTTP request using the server application.
|
|
60
51
|
*
|
|
@@ -66,7 +57,38 @@ export class AngularServerApp {
|
|
|
66
57
|
*
|
|
67
58
|
* @returns A promise that resolves to the HTTP response object resulting from the rendering, or null if no match is found.
|
|
68
59
|
*/
|
|
69
|
-
|
|
60
|
+
render(request, requestContext, serverContext = ServerRenderContext.SSR) {
|
|
61
|
+
return Promise.race([
|
|
62
|
+
this.createAbortPromise(request),
|
|
63
|
+
this.handleRendering(request, requestContext, serverContext),
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Creates a promise that rejects when the request is aborted.
|
|
68
|
+
*
|
|
69
|
+
* @param request - The HTTP request to monitor for abortion.
|
|
70
|
+
* @returns A promise that never resolves but rejects with an `AbortError` if the request is aborted.
|
|
71
|
+
*/
|
|
72
|
+
createAbortPromise(request) {
|
|
73
|
+
return new Promise((_, reject) => {
|
|
74
|
+
request.signal.addEventListener('abort', () => {
|
|
75
|
+
const abortError = new Error(`Request for: ${request.url} was aborted.\n${request.signal.reason}`);
|
|
76
|
+
abortError.name = 'AbortError';
|
|
77
|
+
reject(abortError);
|
|
78
|
+
}, { once: true });
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Handles the server-side rendering process for the given HTTP request.
|
|
83
|
+
* This method matches the request URL to a route and performs rendering if a matching route is found.
|
|
84
|
+
*
|
|
85
|
+
* @param request - The incoming HTTP request to be processed.
|
|
86
|
+
* @param requestContext - Optional additional context for rendering, such as request metadata.
|
|
87
|
+
* @param serverContext - The rendering context. Defaults to server-side rendering (SSR).
|
|
88
|
+
*
|
|
89
|
+
* @returns A promise that resolves to the rendered response, or null if no matching route is found.
|
|
90
|
+
*/
|
|
91
|
+
async handleRendering(request, requestContext, serverContext = ServerRenderContext.SSR) {
|
|
70
92
|
const url = new URL(request.url);
|
|
71
93
|
this.router ??= await ServerRouter.from(this.manifest, url);
|
|
72
94
|
const matchedRoute = this.router.match(url);
|
|
@@ -80,6 +102,66 @@ export class AngularServerApp {
|
|
|
80
102
|
// See: https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect_static#status
|
|
81
103
|
return Response.redirect(new URL(redirectTo, url), 302);
|
|
82
104
|
}
|
|
83
|
-
|
|
105
|
+
const platformProviders = [
|
|
106
|
+
{
|
|
107
|
+
provide: SERVER_CONTEXT,
|
|
108
|
+
useValue: serverContext,
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
// An Angular Console Provider that does not print a set of predefined logs.
|
|
112
|
+
provide: ɵConsole,
|
|
113
|
+
// Using `useClass` would necessitate decorating `Console` with `@Injectable`,
|
|
114
|
+
// which would require switching from `ts_library` to `ng_module`. This change
|
|
115
|
+
// would also necessitate various patches of `@angular/bazel` to support ESM.
|
|
116
|
+
useFactory: () => new Console(),
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
const isSsrMode = serverContext === ServerRenderContext.SSR;
|
|
120
|
+
const responseInit = {};
|
|
121
|
+
if (isSsrMode) {
|
|
122
|
+
platformProviders.push({
|
|
123
|
+
provide: REQUEST,
|
|
124
|
+
useValue: request,
|
|
125
|
+
}, {
|
|
126
|
+
provide: REQUEST_CONTEXT,
|
|
127
|
+
useValue: requestContext,
|
|
128
|
+
}, {
|
|
129
|
+
provide: RESPONSE_INIT,
|
|
130
|
+
useValue: responseInit,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
134
|
+
// Need to clean up GENERATED_COMP_IDS map in `@angular/core`.
|
|
135
|
+
// Otherwise an incorrect component ID generation collision detected warning will be displayed in development.
|
|
136
|
+
// See: https://github.com/angular/angular-cli/issues/25924
|
|
137
|
+
ɵresetCompiledComponents();
|
|
138
|
+
}
|
|
139
|
+
const { manifest, hooks, assets } = this;
|
|
140
|
+
let html = await assets.getIndexServerHtml();
|
|
141
|
+
// Skip extra microtask if there are no pre hooks.
|
|
142
|
+
if (hooks.has('html:transform:pre')) {
|
|
143
|
+
html = await hooks.run('html:transform:pre', { html });
|
|
144
|
+
}
|
|
145
|
+
return new Response(await renderAngular(html, manifest.bootstrap(), new URL(request.url), platformProviders), responseInit);
|
|
84
146
|
}
|
|
85
147
|
}
|
|
148
|
+
let angularServerApp;
|
|
149
|
+
/**
|
|
150
|
+
* Retrieves or creates an instance of `AngularServerApp`.
|
|
151
|
+
* - If an instance of `AngularServerApp` already exists, it will return the existing one.
|
|
152
|
+
* - If no instance exists, it will create a new one with the provided options.
|
|
153
|
+
* @returns The existing or newly created instance of `AngularServerApp`.
|
|
154
|
+
*/
|
|
155
|
+
export function getOrCreateAngularServerApp() {
|
|
156
|
+
return (angularServerApp ??= new AngularServerApp());
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Destroys the existing `AngularServerApp` instance, releasing associated resources and resetting the
|
|
160
|
+
* reference to `undefined`.
|
|
161
|
+
*
|
|
162
|
+
* This function is primarily used to enable the recreation of the `AngularServerApp` instance,
|
|
163
|
+
* typically when server configuration or application state needs to be refreshed.
|
|
164
|
+
*/
|
|
165
|
+
export function destroyAngularServerApp() {
|
|
166
|
+
angularServerApp = undefined;
|
|
167
|
+
}
|
package/esm2022/src/assets.mjs
CHANGED
|
@@ -26,7 +26,7 @@ export class ServerAssets {
|
|
|
26
26
|
* @throws Error If the asset path is not found in the manifest, an error is thrown.
|
|
27
27
|
*/
|
|
28
28
|
async getServerAsset(path) {
|
|
29
|
-
const asset = this.manifest.assets
|
|
29
|
+
const asset = this.manifest.assets.get(path);
|
|
30
30
|
if (!asset) {
|
|
31
31
|
throw new Error(`Server asset '${path}' does not exist.`);
|
|
32
32
|
}
|
|
@@ -95,10 +95,12 @@ function resolveRedirectTo(routePath, redirectTo) {
|
|
|
95
95
|
* @returns A promise that resolves to an object of type `AngularRouterConfigResult`.
|
|
96
96
|
*/
|
|
97
97
|
export async function getRoutesFromAngularRouterConfig(bootstrap, document, url) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
99
|
+
// Need to clean up GENERATED_COMP_IDS map in `@angular/core`.
|
|
100
|
+
// Otherwise an incorrect component ID generation collision detected warning will be displayed in development.
|
|
101
|
+
// See: https://github.com/angular/angular-cli/issues/25924
|
|
102
|
+
ɵresetCompiledComponents();
|
|
103
|
+
}
|
|
102
104
|
const { protocol, host } = url;
|
|
103
105
|
// Create and initialize the Angular platform for server-side rendering.
|
|
104
106
|
const platformRef = createPlatformFactory(platformCore, 'server', [
|