Skip to content

Commit

Permalink
feat: use async local storage as singleton
Browse files Browse the repository at this point in the history
BREAKING CHANGE: use async local storage as singleton
  • Loading branch information
etienne-bechara committed Aug 3, 2021
1 parent a98a876 commit 2220cf6
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 63 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"test": "jest --verbose --forceExit --passWithNoTests --config .config/jest/jest.config.js"
},
"peerDependencies": {
"@bechara/nestjs-core": "^2.0.0"
"@bechara/nestjs-core": "^3.0.0"
},
"dependencies": {
"@mikro-orm/core": "4.5.7",
Expand All @@ -46,7 +46,7 @@
},
"devDependencies": {
"@bechara/eslint-config-bechara-ts": "1.2.0",
"@bechara/nestjs-core": "2.8.2",
"@bechara/nestjs-core": "3.0.0",
"@commitlint/cli": "13.1.0",
"@commitlint/config-conventional": "13.1.0",
"@nestjs/testing": "8.0.5",
Expand Down
87 changes: 39 additions & 48 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions source/orm/orm.controller.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { UseInterceptors } from '@bechara/nestjs-core';

import { OrmEntitySerializer } from './orm.interceptor';
import { OrmEntityManager } from './orm.interceptor';
import { OrmReadArguments } from './orm.interface';
import { OrmService } from './orm.service';

@UseInterceptors(OrmEntitySerializer)
@UseInterceptors(OrmEntityManager)
export abstract class OrmController<Entity> {

public constructor(
Expand Down
2 changes: 1 addition & 1 deletion source/orm/orm.interceptor/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './orm.entity.serializer';
export * from './orm.entity.manager';
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import { CallHandler, ExecutionContext, Injectable, map, NestInterceptor } from '@bechara/nestjs-core';
import { CallHandler, ExecutionContext, Injectable, map, NestInterceptor, RequestService } from '@bechara/nestjs-core';
import { MikroORM } from '@mikro-orm/core';

@Injectable()
export class OrmEntitySerializer implements NestInterceptor {
export class OrmEntityManager implements NestInterceptor {

public constructor(
private readonly mikroOrm: MikroORM,
private readonly requestService: RequestService,
) { }

/**
* If returning data contain entity classes, calls their stringify method
* to prevent sending private data or exceeding call stack size.
* Before a new request arrives at controller, creates a fresh entity
* manager for manipulation.
*
* After processing, if returning data contain entity classes, call
* their stringify method as well as remove reference recursion.
* @param context
* @param next
*/
public intercept(context: ExecutionContext, next: CallHandler): any {
const store = this.requestService.getStore();
store.set('em', this.mikroOrm.em.fork(true, true));

return next
.handle()
.pipe(
Expand Down
10 changes: 4 additions & 6 deletions source/orm/orm.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AppConfig, AppEnvironment, DynamicModule, LoggerService, Module, Scope, UtilModule } from '@bechara/nestjs-core';
import { AppConfig, AppEnvironment, DynamicModule, LoggerService, Module, RequestStorage, UtilModule } from '@bechara/nestjs-core';
import { EntityManager, MikroORMOptions } from '@mikro-orm/core';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { AsyncLocalStorage } from 'async_hooks';

import { SyncModuleOptions } from '../sync/sync.interface';
import { SyncModule } from '../sync/sync.module';
Expand All @@ -14,8 +13,8 @@ export class OrmModule {

/**
* Configure the underlying ORM component with the following additions:
* Adds built-in logger service for debugging (local only)
* Adds programmatically schema sync.
* - Adds built-in logger service for debugging (local only)
* - Adds programmatically schema sync.
* @param options
*/
public static registerAsync(options: OrmAsyncModuleOptions): DynamicModule {
Expand Down Expand Up @@ -45,11 +44,10 @@ export class OrmModule {
imports: [
MikroOrmModule.forRootAsync({
inject: [ OrmInjectionToken.ORM_PROVIDER_OPTIONS ],
scope: Scope.REQUEST,
useFactory: (mikroOrmOptions: OrmModuleOptions) => ({
...mikroOrmOptions,
registerRequestContext: false,
context: (): EntityManager => new AsyncLocalStorage<EntityManager>().getStore(),
context: (): EntityManager => RequestStorage.getStore()?.get('em'),
}),
}),

Expand Down

0 comments on commit 2220cf6

Please sign in to comment.