Skip to content
This repository has been archived by the owner on Nov 22, 2024. It is now read-only.

Commit

Permalink
refactor(aspnetcore-engine): use async/await function
Browse files Browse the repository at this point in the history
  • Loading branch information
alan-agius4 committed Dec 19, 2019
1 parent 9da7415 commit d7b403c
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 111 deletions.
115 changes: 45 additions & 70 deletions modules/aspnetcore-engine/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ function _getUniversalData(doc: Document): UniversalData {
};
}

export function ngAspnetCoreEngine(options: Readonly<IEngineOptions>)
: Promise<IEngineRenderResult> {
export async function ngAspnetCoreEngine(options: Readonly<IEngineOptions>)
: Promise<IEngineRenderResult> {
if (!options.appSelector) {
const selector = `" appSelector: '<${appSelector}></${appSelector}>' "`;
throw new Error(`appSelector is required! Pass in ${selector},
Expand All @@ -111,52 +111,37 @@ export function ngAspnetCoreEngine(options: Readonly<IEngineOptions>)
}
]);

return new Promise((resolve, reject) => {

try {
const moduleOrFactory = options.ngModule;
if (!moduleOrFactory) {
throw new Error('You must pass in a NgModule or NgModuleFactory to be bootstrapped');
}

let extraProviders = options.providers || [];

extraProviders = extraProviders.concat(getReqResProviders(options.request.origin,
options.request.data.request));

getFactory(moduleOrFactory, compiler)
.then(factory => {
return renderModuleFactory(factory, {
document: options.document || options.appSelector,
url: options.url || options.request.absoluteUrl,
extraProviders: extraProviders
});
})
.then(result => {
const doc = result.moduleRef.injector.get(DOCUMENT);
const universalData = _getUniversalData(doc);

resolve({
html: universalData.appNode,
moduleRef: result.moduleRef,
globals: {
styles: universalData.styles,
title: universalData.title,
scripts: universalData.scripts,
meta: universalData.meta,
links: universalData.links
}
});
}, (err) => {
reject(err);
});

} catch (ex) {
reject(ex);
}
const moduleOrFactory = options.ngModule;
if (!moduleOrFactory) {
throw new Error('You must pass in a NgModule or NgModuleFactory to be bootstrapped');
}

const extraProviders = [
...(options.providers || []),
getReqResProviders(options.request.origin, options.request.data.request),
];

const factory = await getFactory(moduleOrFactory, compiler);
const result = await renderModuleFactory(factory, {
document: options.document || options.appSelector,
url: options.url || options.request.absoluteUrl,
extraProviders,
});

const doc = result.moduleRef.injector.get(DOCUMENT);
const universalData = _getUniversalData(doc);

return {
html: universalData.appNode,
moduleRef: result.moduleRef,
globals: {
styles: universalData.styles,
title: universalData.title,
scripts: universalData.scripts,
meta: universalData.meta,
links: universalData.links
}
};
}

/**
Expand All @@ -178,32 +163,22 @@ function getReqResProviders(origin: string, request: string): StaticProvider[] {

/* @internal */
const factoryCacheMap = new Map<Type<{}>, NgModuleFactory<{}>>();
function getFactory(
async function getFactory(
moduleOrFactory: Type<{}> | NgModuleFactory<{}>, compiler: Compiler
): Promise<NgModuleFactory<{}>> {

return new Promise<NgModuleFactory<{}>>((resolve, reject) => {
// If module has been compiled AoT
if (moduleOrFactory instanceof NgModuleFactory) {
resolve(moduleOrFactory);
return;
} else {
let moduleFactory = factoryCacheMap.get(moduleOrFactory);

// If module factory is cached
if (moduleFactory) {
resolve(moduleFactory);
return;
}

// Compile the module and cache it
compiler.compileModuleAsync(moduleOrFactory)
.then((factory) => {
factoryCacheMap.set(moduleOrFactory, factory);
resolve(factory);
}, (err => {
reject(err);
}));
// If module has been compiled AoT
if (moduleOrFactory instanceof NgModuleFactory) {
return moduleOrFactory;
} else {
let moduleFactory = factoryCacheMap.get(moduleOrFactory);
// If module factory is cached
if (moduleFactory) {
return moduleFactory;
}
});

// Compile the module and cache it
const factory = await compiler.compileModuleAsync(moduleOrFactory);
factoryCacheMap.set(moduleOrFactory, factory);
return factory;
}
}
61 changes: 28 additions & 33 deletions modules/aspnetcore-engine/src/platform-server-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
INITIAL_CONFIG,
PlatformState
} from '@angular/platform-server';
import {filter, take} from 'rxjs/operators';
import {first} from 'rxjs/operators';

interface PlatformOptions {
document?: string;
Expand All @@ -51,42 +51,37 @@ function _getPlatform(
]);
}

function _render<T>(platform: PlatformRef,
async function _render<T>(platform: PlatformRef,
moduleRefPromise: Promise<NgModuleRef<T>>): Promise<ModuleRenderResult<T>> {
return moduleRefPromise.then(moduleRef => {
const transitionId = moduleRef.injector.get(ɵTRANSITION_ID, null);
if (!transitionId) {
throw new Error(
`renderModule[Factory]() requires the use of BrowserModule.withServerTransition() to ensure
const moduleRef = await moduleRefPromise;
const transitionId = moduleRef.injector.get(ɵTRANSITION_ID, null);
if (!transitionId) {
throw new Error(`renderModule[Factory]() requires the use of BrowserModule.withServerTransition() to ensure
the server-rendered app can be properly bootstrapped into a client app.`);
}
const applicationRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
return applicationRef.isStable
.pipe(
filter((isStable: boolean) => isStable),
take(1)
).toPromise()
.then(() => {
const platformState = platform.injector.get(PlatformState);
}

// Run any BEFORE_APP_SERIALIZED callbacks just before rendering to string.
const callbacks = moduleRef.injector.get(BEFORE_APP_SERIALIZED, null);
if (callbacks) {
for (const callback of callbacks) {
try {
callback();
} catch (e) {
// Ignore exceptions.
console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e);
}
}
}
const applicationRef = moduleRef.injector.get(ApplicationRef);
await applicationRef.isStable
.pipe(
first(isStable => isStable),
).toPromise();

const output = platformState.renderToString();
platform.destroy();
return { html: output, moduleRef };
});
});
const platformState = platform.injector.get(PlatformState);
// Run any BEFORE_APP_SERIALIZED callbacks just before rendering to string.
const callbacks = moduleRef.injector.get(BEFORE_APP_SERIALIZED, null);
if (callbacks) {
for (const callback of callbacks) {
try {
callback();
} catch (e) {
// Ignore exceptions.
console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e);
}
}
}
const output = platformState.renderToString();
platform.destroy();
return { html: output, moduleRef };
}

/**
Expand Down
14 changes: 6 additions & 8 deletions modules/common/engine/src/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,23 @@ export class CommonEngine {
}

/** Return the factory for a given engine instance */
getFactory(moduleOrFactory: Type<{}> | NgModuleFactory<{}>): Promise<NgModuleFactory<{}>> {
async getFactory(moduleOrFactory: Type<{}> | NgModuleFactory<{}>): Promise<NgModuleFactory<{}>> {
// If module has been compiled AoT
if (moduleOrFactory instanceof NgModuleFactory) {
return Promise.resolve(moduleOrFactory);
return moduleOrFactory;
} else {
// we're in JIT mode
let moduleFactory = this.factoryCacheMap.get(moduleOrFactory);

// If module factory is cached
if (moduleFactory) {
return Promise.resolve(moduleFactory);
return moduleFactory;
}

// Compile the module and cache it
return this.getCompiler().compileModuleAsync(moduleOrFactory)
.then((factory) => {
this.factoryCacheMap.set(moduleOrFactory, factory);
return factory;
});
const factory = await this.getCompiler().compileModuleAsync(moduleOrFactory);
this.factoryCacheMap.set(moduleOrFactory, factory);
return factory;
}
}

Expand Down

0 comments on commit d7b403c

Please sign in to comment.