@foblex/ng-mediator
Version:
A mediator library for Angular facilitating a clean architecture with a better command-query separation.
192 lines (179 loc) • 6.73 kB
JavaScript
import { switchMap, of, throwError } from 'rxjs';
import * as i0 from '@angular/core';
import { Injectable, InjectionToken, Inject, NgModule } from '@angular/core';
import { switchMap as switchMap$1, catchError } from 'rxjs/operators';
class FCommandBase {
handle(request) {
const result = this.execute(request);
return result;
}
}
class FQueryBase {
handle(request) {
const result = this.execute(request);
return result;
}
}
class ValidationFailed {
constructor(errors) {
this.errors = errors;
this.isValid = false;
}
}
class ValidationSuccess {
constructor() {
this.isValid = true;
}
}
class FValidatorBase {
handle(request) {
return this.validate(request).pipe(switchMap((errors) => {
if (errors && errors.length > 0) {
return of(new ValidationFailed(errors));
}
return of(new ValidationSuccess());
}));
}
}
class FEmptyValidator extends FValidatorBase {
validate(request) {
return of([]);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FEmptyValidator, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FEmptyValidator, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FEmptyValidator, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}] });
const F_FEATURE_TOKEN = new InjectionToken('F_FEATURE_TOKEN');
class FMediator {
constructor(featureProviders) {
this.features = new Map();
for (const feature of featureProviders) {
this.features.set(feature.requestType, feature);
}
}
send(requestType, request) {
const feature = this.features.get(requestType.name);
if (!feature) {
return throwError(() => Error('Pipeline not registered for request type.'));
}
return feature.execute(request);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FMediator, deps: [{ token: F_FEATURE_TOKEN }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FMediator, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FMediator, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [F_FEATURE_TOKEN]
}] }] });
class Pipeline {
constructor(requestType, validator, requestHandler) {
this.requestType = requestType;
this.validator = validator;
this.requestHandler = requestHandler;
}
execute(request) {
return this.validator.handle(request).pipe(switchMap$1((result) => {
if (!result.isValid) {
return throwError(() => result.errors);
}
return this.requestHandler.handle(request).pipe(catchError((error) => throwError(() => [error])));
}));
}
}
class FMediatorModule {
static forRoot() {
return {
ngModule: FMediatorModule,
providers: [FMediator]
};
}
static forFeature(requestType, validatorType, handlerType) {
return {
ngModule: FMediatorModule,
providers: [
validatorType,
handlerType,
{
provide: F_FEATURE_TOKEN,
useFactory: (validator, handler) => {
return new Pipeline(requestType.name, validator, handler);
},
deps: [validatorType, handlerType],
multi: true
}
]
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FMediatorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.2.2", ngImport: i0, type: FMediatorModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FMediatorModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: FMediatorModule, decorators: [{
type: NgModule
}] });
class MockRequest {
}
// Validators
class SuccessValidator extends FValidatorBase {
validate(request) {
return of([]);
}
}
class FailureValidator extends FValidatorBase {
validate(request) {
return of([new Error('Validation Error')]);
}
}
// Handlers
class SuccessHandler extends FCommandBase {
execute(request) {
return of('Success');
}
}
class FailureHandler extends FQueryBase {
execute(request) {
return throwError(() => new Error('Handler Error'));
}
}
// describe('FMediator', () => {
// let mediator: FMediator;
//
// function setupModule(validator: Type<FValidatorBase<MockRequest, string>>, handler: Type<IRequestHandler<MockRequest, string>>) {
// TestBed.configureTestingModule({
// imports: [ FMediatorModule.forRoot(), FMediatorModule.forFeature(MockRequest, validator, handler) ]
// });
// mediator = TestBed.inject(FMediator);
// }
//
// it('should return success when there are no errors', fakeAsync(() => {
// setupModule(SuccessValidator, SuccessHandler);
// mediator.send(MockRequest, new MockRequest()).subscribe(response => {
// expect(response).toEqual('Success');
// });
// tick();
// }));
//
// it('should return validation error when validator fails', fakeAsync(() => {
// setupModule(FailureValidator, SuccessHandler);
// mediator.send(MockRequest, new MockRequest()).pipe(catchError((err, o) => {
// expect(err).toEqual([ new Error('Validation Error') ]);
// return o;
// })).subscribe();
// tick();
// }));
// });
/**
* Generated bundle index. Do not edit.
*/
export { FCommandBase, FEmptyValidator, FMediator, FMediatorModule, FQueryBase, FValidatorBase, F_FEATURE_TOKEN, Pipeline, ValidationFailed, ValidationSuccess };
//# sourceMappingURL=foblex-ng-mediator.mjs.map