Skip to content

Commit

Permalink
refactor(@angular/ssr): remove singleton helpers
Browse files Browse the repository at this point in the history
This commit removes the singleton helpers and instead exposes the
classes directly.
  • Loading branch information
alan-agius4 committed Sep 6, 2024
1 parent 41fb2ed commit 7d9ce24
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 141 deletions.
9 changes: 2 additions & 7 deletions goldens/public-api/angular/ssr/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@
```ts

// @public
export interface AngularServerAppManager {
export class AngularAppEngine {
getHeaders(request: Request): Readonly<Map<string, string>>;
render(request: Request, requestContext?: unknown): Promise<Response | null>;
static ɵhooks: Hooks;
}

// @public
export function destroyAngularAppEngine(): void;

// @public
export function getOrCreateAngularAppEngine(): AngularServerAppManager;

// (No @packageDocumentation comment for this package)

```
8 changes: 1 addition & 7 deletions goldens/public-api/angular/ssr/node/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { StaticProvider } from '@angular/core';
import { Type } from '@angular/core';

// @public
export interface AngularNodeServerAppManager {
export class AngularNodeAppEngine {
getHeaders(request: IncomingMessage): Readonly<Map<string, string>>;
render(request: IncomingMessage, requestContext?: unknown): Promise<Response | null>;
}
Expand Down Expand Up @@ -46,12 +46,6 @@ export interface CommonEngineRenderOptions {
// @public
export function createWebRequestFromNodeRequest(nodeRequest: IncomingMessage): Request;

// @public
export function destroyAngularNodeAppEngine(): void;

// @public
export function getOrCreateAngularNodeAppEngine(): AngularNodeServerAppManager;

// @public
export function writeResponseToNodeResponse(source: Response, destination: ServerResponse): Promise<void>;

Expand Down
6 changes: 1 addition & 5 deletions packages/angular/ssr/node/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ export {
type CommonEngineOptions,
} from './src/common-engine/common-engine';

export {
type AngularNodeServerAppManager,
destroyAngularNodeAppEngine,
getOrCreateAngularNodeAppEngine,
} from './src/app-engine';
export { AngularNodeAppEngine } from './src/app-engine';

export { writeResponseToNodeResponse } from './src/response';
export { createWebRequestFromNodeRequest } from './src/request';
64 changes: 14 additions & 50 deletions packages/angular/ssr/node/src/app-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,23 @@
* found in the LICENSE file at https://angular.dev/license
*/

import { destroyAngularAppEngine, getOrCreateAngularAppEngine } from '@angular/ssr';
import { AngularAppEngine } from '@angular/ssr';
import type { IncomingMessage } from 'node:http';
import { createWebRequestFromNodeRequest } from './request';

/**
* Angular server application engine.
* Manages Angular server applications (including localized ones) and handles rendering requests.
* Manages Angular server applications (including localized ones), handles rendering requests,
* and optionally transforms index HTML before rendering.
*
* @note This class should be instantiated once and used as a singleton across the server-side
* application to ensure consistent handling of rendering requests and resource management.
*
* @developerPreview
*/
export interface AngularNodeServerAppManager {
export class AngularNodeAppEngine {
private readonly angularAppEngine = new AngularAppEngine();

/**
* Renders an HTTP response based on the incoming request using the Angular server application.
*
Expand All @@ -32,7 +38,9 @@ export interface AngularNodeServerAppManager {
* @returns A promise that resolves to a `Response` object, or `null` if the request URL is for a static file
* (e.g., `./logo.png`) rather than an application route.
*/
render(request: IncomingMessage, requestContext?: unknown): Promise<Response | null>;
render(request: IncomingMessage, requestContext?: unknown): Promise<Response | null> {
return this.angularAppEngine.render(createWebRequestFromNodeRequest(request), requestContext);
}

/**
* Retrieves HTTP headers for a request associated with statically generated (SSG) pages,
Expand All @@ -43,7 +51,7 @@ export interface AngularNodeServerAppManager {
* @note This function should be used exclusively for retrieving headers of SSG pages.
* @example
* ```typescript
* const angularAppEngine = getOrCreateAngularNodeAppEngine();
* const angularAppEngine = new AngularNodeAppEngine();
*
* app.use(express.static('dist/browser', {
* setHeaders: (res, path) => {
Expand All @@ -58,51 +66,7 @@ export interface AngularNodeServerAppManager {
}));
* ```
*/
getHeaders(request: IncomingMessage): Readonly<Map<string, string>>;
}

/**
* Angular server application engine.
* Manages Angular server applications (including localized ones), handles rendering requests,
* and optionally transforms index HTML before rendering.
*/
class AngularNodeAppEngine implements AngularNodeServerAppManager {
private readonly angularAppEngine = getOrCreateAngularAppEngine();

render(request: IncomingMessage, requestContext?: unknown): Promise<Response | null> {
return this.angularAppEngine.render(createWebRequestFromNodeRequest(request), requestContext);
}

getHeaders(request: IncomingMessage): Readonly<Map<string, string>> {
return this.angularAppEngine.getHeaders(createWebRequestFromNodeRequest(request));
}
}

let angularNodeAppEngine: AngularNodeAppEngine | undefined;

/**
* Retrieves the existing `AngularNodeAppEngine` instance or creates a new one if it doesn't exist.
*
* This method ensures that a single instance of `AngularNodeAppEngine` is used throughout the application's lifecycle,
* promoting efficient resource management. If an instance does not exist, it will be instantiated upon the first call.
*
* @developerPreview
* @returns The existing or newly created instance of `AngularNodeAppEngine`.
*/
export function getOrCreateAngularNodeAppEngine(): AngularNodeServerAppManager {
return (angularNodeAppEngine ??= new AngularNodeAppEngine());
}

/**
* Destroys the current `AngularNodeAppEngine` instance and releases any associated resources.
*
* This method resets the reference to the `AngularNodeAppEngine` instance to `undefined`, allowing for the creation
* of a new instance on subsequent calls to `getOrCreateAngularNodeAppEngine()`. This is typically used when
* reinitializing the server environment or refreshing the application state.
*
* @developerPreview
*/
export function destroyAngularNodeAppEngine(): void {
angularNodeAppEngine = undefined;
destroyAngularAppEngine();
}
2 changes: 0 additions & 2 deletions packages/angular/ssr/private_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ export {
setAngularAppEngineManifest as ɵsetAngularAppEngineManifest,
} from './src/manifest';

export { AngularAppEngine as ɵAngularAppEngine } from './src/app-engine';

export { InlineCriticalCssProcessor as ɵInlineCriticalCssProcessor } from './src/utils/inline-critical-css';
6 changes: 1 addition & 5 deletions packages/angular/ssr/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@

export * from './private_export';

export {
type AngularServerAppManager,
getOrCreateAngularAppEngine,
destroyAngularAppEngine,
} from './src/app-engine';
export { AngularAppEngine } from './src/app-engine';
69 changes: 4 additions & 65 deletions packages/angular/ssr/src/app-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,17 @@ import { getPotentialLocaleIdFromUrl } from './i18n';
import { EntryPointExports, getAngularAppEngineManifest } from './manifest';
import { stripIndexHtmlFromURL } from './utils/url';

/**
* Angular server application engine.
* Manages Angular server applications (including localized ones) and handles rendering requests.
* @developerPreview
*/
export interface AngularServerAppManager {
/**
* Renders a response for the given HTTP request using the server application.
*
* This method processes the request, determines the appropriate route and rendering context,
* and returns an HTTP response.
*
* If the request URL appears to be for a file (excluding `/index.html`), the method returns `null`.
* A request to `https://www.example.com/page/index.html` will render the Angular route
* corresponding to `https://www.example.com/page`.
*
* @param request - The incoming HTTP request object to be rendered.
* @param requestContext - Optional additional context for the request, such as metadata.
* @returns A promise that resolves to a Response object, or `null` if the request URL represents a file (e.g., `./logo.png`)
* rather than an application route.
*/
render(request: Request, requestContext?: unknown): Promise<Response | null>;

/**
* Retrieves HTTP headers for a request associated with statically generated (SSG) pages,
* based on the URL pathname.
*
* @param request - The incoming request object.
* @returns A `Map` containing the HTTP headers as key-value pairs.
* @note This function should be used exclusively for retrieving headers of SSG pages.
*/
getHeaders(request: Request): Readonly<Map<string, string>>;
}

/**
* Angular server application engine.
* Manages Angular server applications (including localized ones), handles rendering requests,
* and optionally transforms index HTML before rendering.
*
* @note This class should be instantiated once and used as a singleton across the server-side
* application to ensure consistent handling of rendering requests and resource management.
*
* @developerPreview
*/
export class AngularAppEngine implements AngularServerAppManager {
export class AngularAppEngine {
/**
* Hooks for extending or modifying the behavior of the server application.
* These hooks are used by the Angular CLI when running the development server and
Expand Down Expand Up @@ -153,32 +121,3 @@ export class AngularAppEngine implements AngularServerAppManager {
return new Map(headers);
}
}

let angularAppEngine: AngularAppEngine | undefined;

/**
* Retrieves an existing `AngularAppEngine` instance or creates a new one if none exists.
*
* This method ensures that only a single instance of `AngularAppEngine` is created and reused across
* the application lifecycle, providing efficient resource management. If the instance does not exist,
* it will be instantiated upon the first call.
*
* @developerPreview
* @returns The existing or newly created instance of `AngularAppEngine`.
*/
export function getOrCreateAngularAppEngine(): AngularServerAppManager {
return (angularAppEngine ??= new AngularAppEngine());
}

/**
* Destroys the current `AngularAppEngine` instance, releasing any associated resources.
*
* This method resets the reference to the `AngularAppEngine` instance to `undefined`, allowing
* a new instance to be created on the next call to `getOrCreateAngularAppEngine()`. It is typically
* used when reinitializing the server environment or refreshing the application state is necessary.
*
* @developerPreview
*/
export function destroyAngularAppEngine(): void {
angularAppEngine = undefined;
}

0 comments on commit 7d9ce24

Please sign in to comment.