Commit 6e4df9a2 authored by nanahira's avatar nanahira

rework typing system

parent d2b7c7cb
{ {
"name": "myproject", "name": "cordis-decorators",
"version": "1.0.7", "version": "1.0.7",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "myproject", "name": "cordis-decorators",
"version": "1.0.7", "version": "1.0.7",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
......
import { PluginRegistrar } from '../plugin-def'; import { PluginRegistrar } from '../plugin-def';
import PluginClass = PluginRegistrar.PluginClass; import PluginClass = PluginRegistrar.PluginClass;
import { Context } from 'cordis';
export type Awaitable<T> = [T] extends [Promise<unknown>] ? T : T | Promise<T>; export type Awaitable<T> = [T] extends [Promise<unknown>] ? T : T | Promise<T>;
export type TypedMethodDecorator<F extends (...args: any[]) => any> = < export type TypedMethodDecorator<F extends (...args: any[]) => any> = <
...@@ -13,23 +11,6 @@ export type TypedMethodDecorator<F extends (...args: any[]) => any> = < ...@@ -13,23 +11,6 @@ export type TypedMethodDecorator<F extends (...args: any[]) => any> = <
descriptor: TypedPropertyDescriptor<T>, descriptor: TypedPropertyDescriptor<T>,
) => void; ) => void;
export type FunctionParam<F extends (...args: any[]) => any> = F extends (
...args: infer R
) => any
? R
: never;
export type FunctionReturn<F extends (...args: any[]) => any> = F extends (
...args: any[]
) => infer R
? R
: never;
export type PickEventFunction<M, K extends keyof M = keyof M> = M[K] extends (
...args: any[]
) => any
? (...args: FunctionParam<M[K]>) => Awaitable<FunctionReturn<M[K]>>
: M[K];
export type ParamRenderer = <T>(v: T) => T; export type ParamRenderer = <T>(v: T) => T;
export interface ControlTypeMap { export interface ControlTypeMap {
...@@ -57,6 +38,18 @@ export type ParamsFromClass<T> = T extends { new (...args: infer U): any } ...@@ -57,6 +38,18 @@ export type ParamsFromClass<T> = T extends { new (...args: infer U): any }
? U ? U
: never; : never;
export type FunctionParams<F extends (...args: any[]) => any> = F extends (
...args: infer U
) => any
? U
: never;
export type FunctionReturn<F extends (...args: any[]) => any> = F extends (
...args: any
) => infer U
? U
: never;
export type Prop<T> = T; export type Prop<T> = T;
export type PartialDeep<T> = T extends export type PartialDeep<T> = T extends
......
import { Context, Plugin } from 'cordis'; import { Context, Plugin } from 'cordis';
import Schema from 'schemastery'; import Schema from 'schemastery';
import { ClassType } from 'schemastery-gen'; import { ClassType } from 'schemastery-gen';
import type { Registrar } from '../registrar';
// eslint-disable-next-line @typescript-eslint/no-namespace // eslint-disable-next-line @typescript-eslint/no-namespace
export namespace PluginRegistrar { export namespace PluginRegistrar {
...@@ -20,7 +19,7 @@ export namespace PluginRegistrar { ...@@ -20,7 +19,7 @@ export namespace PluginRegistrar {
name?: string; name?: string;
schema?: Schema<T> | ClassType<T>; schema?: Schema<T> | ClassType<T>;
Config?: Schema<T> | ClassType<T>; Config?: Schema<T> | ClassType<T>;
using?: Registrar.ServiceName<Ctx>[]; using?: string[];
reusable?: boolean; reusable?: boolean;
} }
......
import { Context } from 'cordis'; import { Context } from 'cordis';
import { Registrar } from './registrar'; import { Registrar } from './registrar';
import { generateRenderer, renderObject } from './utility/render-object'; import { generateRenderer } from './utility/render-object';
import { extractObjectMethod } from './utility/utility'; import { extractObjectMethod } from './utility/utility';
import { ControlType } from './def'; import { ControlType } from './def';
import { import {
...@@ -9,13 +9,10 @@ import { ...@@ -9,13 +9,10 @@ import {
Observable, Observable,
ObservableInput, ObservableInput,
ObservedValueOf, ObservedValueOf,
of,
} from 'rxjs'; } from 'rxjs';
import _ from 'lodash'; import _ from 'lodash';
import ContextTransformer = Registrar.ContextTransformer;
type RecursiveUnwrapObservable<T> = T extends ObservableInput<any> import { RegisterMeta } from './utility/register-meta';
? RecursiveUnwrapObservable<ObservedValueOf<T>>
: T;
export class RegistrarAspect<Ctx extends Context, T = any> { export class RegistrarAspect<Ctx extends Context, T = any> {
constructor( constructor(
...@@ -45,8 +42,11 @@ export class RegistrarAspect<Ctx extends Context, T = any> { ...@@ -45,8 +42,11 @@ export class RegistrarAspect<Ctx extends Context, T = any> {
this.obj, this.obj,
key, key,
); );
const r = generateRenderer({ ...this.view, ...extraView }); return this.registrar.transformContext(
return this.registrar.transformContext(ctx, contextFilters, r); ctx,
contextFilters as RegisterMeta<ContextTransformer<Ctx, any[]>>[],
{ ...this.view, ...extraView },
);
} }
registerMethod( registerMethod(
...@@ -57,12 +57,18 @@ export class RegistrarAspect<Ctx extends Context, T = any> { ...@@ -57,12 +57,18 @@ export class RegistrarAspect<Ctx extends Context, T = any> {
const data = this.registrar.reflector.get('CordisRegister', this.obj, key); const data = this.registrar.reflector.get('CordisRegister', this.obj, key);
if (!data) return; if (!data) return;
const specificCtx = this.getScopeContext(ctx, key, extraView, false); const specificCtx = this.getScopeContext(ctx, key, extraView, false);
const result = data.action( const result = data.run(
{ ...this.view, ...extraView },
specificCtx, specificCtx,
extractObjectMethod(this.obj, key), extractObjectMethod(this.obj, key),
...renderObject(data.args, { ...this.view, ...extraView }),
); );
return { ...data, key: key, result, ctx: specificCtx }; return {
...data,
type: data.info.type,
key: key,
result,
ctx: specificCtx,
};
} }
private registerWithLoopControl( private registerWithLoopControl(
...@@ -98,7 +104,7 @@ export class RegistrarAspect<Ctx extends Context, T = any> { ...@@ -98,7 +104,7 @@ export class RegistrarAspect<Ctx extends Context, T = any> {
private runLayersWith<R extends ObservableInput<any>>( private runLayersWith<R extends ObservableInput<any>>(
ctx: Ctx, ctx: Ctx,
cb: Registrar.ContextFunction<Ctx, R>, cb: Registrar.ContextFunction<Ctx, R>,
layers: Registrar.ContextCallbackLayer<Ctx>[], layers: RegisterMeta<Registrar.ContextCallbackLayer<Ctx>>[],
): Observable<ObservedValueOf<R>> { ): Observable<ObservedValueOf<R>> {
const rest = [...layers]; const rest = [...layers];
const layer = rest.pop(); const layer = rest.pop();
...@@ -106,7 +112,7 @@ export class RegistrarAspect<Ctx extends Context, T = any> { ...@@ -106,7 +112,7 @@ export class RegistrarAspect<Ctx extends Context, T = any> {
return from(cb(ctx)); return from(cb(ctx));
} }
return new Observable((subscriber) => { return new Observable((subscriber) => {
layer(ctx, async (nextCtx) => { layer.run(this.view, ctx, async (nextCtx) => {
if (!rest.length) { if (!rest.length) {
const result = cb(nextCtx); const result = cb(nextCtx);
if (result) { if (result) {
...@@ -134,7 +140,11 @@ export class RegistrarAspect<Ctx extends Context, T = any> { ...@@ -134,7 +140,11 @@ export class RegistrarAspect<Ctx extends Context, T = any> {
this.obj, this.obj,
key as string, key as string,
); );
return this.runLayersWith(ctx, cb, layers); return this.runLayersWith(
ctx,
cb,
layers as RegisterMeta<Registrar.ContextCallbackLayer<Ctx>>[],
);
} }
registerFor(ctx: Ctx, key: keyof T & string) { registerFor(ctx: Ctx, key: keyof T & string) {
...@@ -169,6 +179,8 @@ export class RegistrarAspect<Ctx extends Context, T = any> { ...@@ -169,6 +179,8 @@ export class RegistrarAspect<Ctx extends Context, T = any> {
this.registrar.reflector.getArray('CordisTopLevelAction', this.obj), this.registrar.reflector.getArray('CordisTopLevelAction', this.obj),
); );
const renderer = generateRenderer({ ...this.view, ...extraView }); const renderer = generateRenderer({ ...this.view, ...extraView });
actions.forEach((action) => action(ctx, this.obj, renderer)); actions.forEach((action) =>
action.run({ ...this.view, ...extraView }, ctx, this.obj, renderer),
);
} }
} }
import 'reflect-metadata'; import 'reflect-metadata';
import { Context, Events, Fork } from 'cordis'; import { Context, GetEvents } from 'cordis';
import { ClassType, SchemaClass } from 'schemastery-gen'; import { ClassType, SchemaClass } from 'schemastery-gen';
import { MetadataSetter, Reflector } from 'typed-reflector'; import { MetadataSetter, Reflector } from 'typed-reflector';
import type { import type {
Awaitable, Awaitable,
Condition, Condition,
ControlType, ControlType,
FunctionParam,
FunctionReturn,
ParamRenderer,
PartialDeep, PartialDeep,
PickEventFunction,
TypedMethodDecorator, TypedMethodDecorator,
} from './def'; } from './def';
import { RegistrarAspect } from './registrar-aspect'; import { RegistrarAspect } from './registrar-aspect';
import Schema from 'schemastery'; import Schema from 'schemastery';
import { PluginRegistrar } from './plugin-def'; import { PluginRegistrar } from './plugin-def';
import _ from 'lodash'; import _ from 'lodash';
import { RegisterMeta } from './utility/register-meta';
declare module 'cordis' { declare module 'cordis' {
interface Context { interface Context {
...@@ -26,119 +23,100 @@ declare module 'cordis' { ...@@ -26,119 +23,100 @@ declare module 'cordis' {
// eslint-disable-next-line @typescript-eslint/no-namespace // eslint-disable-next-line @typescript-eslint/no-namespace
export namespace Registrar { export namespace Registrar {
export interface Methods<Ctx extends Context> { export interface MetadataArrayMap {
on(event: keyof Events<Ctx>, prepend?: boolean): () => boolean; CordisRegisterKeys: string;
plugin(): Awaitable<Fork<Ctx>>; CordisContextTransformer: RegisterMeta<ContextTransformer<Context>>;
apply(): Awaitable<any>; CordisTopLevelAction: RegisterMeta<TopLevelActionDef<Context>>;
CordisContextLayers: RegisterMeta<ContextCallbackLayer<Context>>;
CordisControl: ControlType;
CordisPluginUsing: string;
CordisPluginProvide: ProvideDefinition<Context>;
CordisPluginInjectKeys: string;
CordisPluginSystemKeys: string;
} }
export interface MethodLimitations<Ctx extends Context> { export interface MetadataMap {
on: PickEventFunction<Events<Ctx>>; CordisRegister: MethodMeta<Context>;
plugin( CordisPluginInject: string;
...args: any[] CordisPluginSystem: PluginRegistrar.SystemInjectFun<Context>;
): Awaitable<PluginRegistrar.PluginDefinition<Ctx> | undefined>; CordisPluginPredefineSchema: Schema | ClassType<any>;
CordisPluginPredefineName: string;
CordisPluginFork: PluginRegistrar.PluginClass<Context>;
CordisPluginReusable: boolean;
} }
export type MethodType<Ctx extends Context> = keyof Methods<Ctx>; export type DecorateFunctionParam<
export type MethodBody< Ctx extends Context,
C extends Context, A extends any[] = any[],
K extends keyof Methods<C> = keyof Methods<C>, R = any,
> = Methods<C>[K]; > = (ctx: Ctx, ...args: A) => R;
export type MethodParams<
C extends Context,
K extends keyof Methods<C> = keyof Methods<C>,
> = FunctionParam<MethodBody<C, K>>;
export type MethodReturn<
C extends Context,
K extends keyof Methods<C> = keyof Methods<C>,
> = FunctionReturn<MethodBody<C, K>>;
export type MethodClassMethodFunction<
C extends Context,
K extends keyof Methods<C> = keyof Methods<C>,
> = K extends keyof MethodLimitations<C>
? MethodLimitations<C>[K]
: (...args: any[]) => any;
export type MethodResolver<
C extends Context,
K extends keyof Methods<C> = keyof Methods<C>,
> = (
ctx: C,
fun: MethodClassMethodFunction<C, K>,
...args: MethodParams<C, K>
) => MethodReturn<C, K>;
export interface RegisterInfo<C extends Context> {
type: MethodType<C>;
args: MethodParams<C>;
action: MethodResolver<C>;
}
export interface RegisterResult< export type DecorateFunctionParamSingle<
C extends Context, Ctx extends Context,
T, P,
K extends keyof Methods<C> = keyof Methods<C>, A extends any[] = any[],
> extends RegisterInfo<C> { R = any,
> = (ctx: Ctx, param: P, ...args: A) => R;
export type MethodResolver<
Ctx extends Context,
A extends any[] = any[],
F extends (...args: any[]) => any = (...args: any[]) => any,
> = DecorateFunctionParamSingle<Ctx, F, A>;
export type MethodMeta<Ctx extends Context> = RegisterMeta<
MethodResolver<Ctx>,
{ type: string }
>;
export type RegisterResult<Ctx extends Context, T> = Omit<
MethodMeta<Ctx>,
'run'
> & {
type: string;
key: keyof T & string; key: keyof T & string;
result: MethodReturn<C, K>; result: any;
ctx: C; ctx: Ctx;
} };
export interface ProvideOptions extends Context.ServiceOptions { export interface ProvideOptions extends Context.ServiceOptions {
immediate?: boolean; immediate?: boolean;
} }
export interface ProvideDefinition<C extends Context> extends ProvideOptions { export interface ProvideDefinition<C extends Context> extends ProvideOptions {
serviceName: ServiceName<C>; serviceName: string;
} }
export type ContextFunction<C extends Context, T> = (ctx: C) => T; export type ContextFunction<Ctx extends Context, T> = DecorateFunctionParam<
export type RenderedContextTransformer<C extends Context> = ( Ctx,
ctx: C, [],
r: ParamRenderer, T
) => C; >;
export type ContextCallbackLayer<C extends Context, T = any> = (
ctx: C, export type ContextTransformer<
cb: ContextFunction<C, void>, Ctx extends Context,
) => T; A extends any[] = any[],
> = DecorateFunctionParam<Ctx, A, Ctx>;
export type ServiceName<C extends Context> = string;
export type ContextCallbackLayer<
export type TopLevelActionDef<C extends Context> = ( Ctx extends Context,
ctx: C, A extends any[] = any[],
obj: any, > = DecorateFunctionParamSingle<Ctx, ContextFunction<Ctx, void>, A>;
renderer: ParamRenderer,
) => void; export type TopLevelActionDef<
Ctx extends Context,
export interface MetadataArrayMap<C extends Context> { A extends any[] = any[],
CordisRegisterKeys: string; > = DecorateFunctionParamSingle<Ctx, any, A>;
CordisContextTransformer: RenderedContextTransformer<C>;
CordisTopLevelAction: TopLevelActionDef<C>;
CordisContextLayers: ContextCallbackLayer<C>;
CordisControl: ControlType;
CordisPluginUsing: ServiceName<C>;
CordisPluginProvide: ProvideDefinition<C>;
CordisPluginInjectKeys: string;
CordisPluginSystemKeys: string;
}
export interface MetadataMap<C extends Context> {
CordisRegister: RegisterInfo<C>;
CordisPluginInject: ServiceName<C>;
CordisPluginSystem: PluginRegistrar.SystemInjectFun<C>;
CordisPluginPredefineSchema: Schema | ClassType<any>;
CordisPluginPredefineName: string;
CordisPluginFork: PluginRegistrar.PluginClass<C>;
CordisPluginReusable: boolean;
}
} }
const ThirdEyeSym = Symbol('ThirdEyeSym'); const ThirdEyeSym = Symbol('ThirdEyeSym');
export class Registrar<Ctx extends Context> { export class Registrar<Ctx extends Context> {
metadata = new MetadataSetter< metadata = new MetadataSetter<
Registrar.MetadataMap<Ctx>, Registrar.MetadataMap,
Registrar.MetadataArrayMap<Ctx> Registrar.MetadataArrayMap
>(); >();
reflector = new Reflector< reflector = new Reflector<
Registrar.MetadataMap<Ctx>, Registrar.MetadataMap,
Registrar.MetadataArrayMap<Ctx> Registrar.MetadataArrayMap
>(); >();
constructor(public contextClass: ClassType<Ctx>) {} constructor(public contextClass: ClassType<Ctx>) {}
...@@ -146,34 +124,46 @@ export class Registrar<Ctx extends Context> { ...@@ -146,34 +124,46 @@ export class Registrar<Ctx extends Context> {
return new RegistrarAspect(this, obj, view); return new RegistrarAspect(this, obj, view);
} }
decorateMethod<K extends keyof Registrar.Methods<Ctx>>( decorateMethod<A extends any[], F extends (...args: any[]) => any>(
type: K, type: string,
action: Registrar.MethodResolver<Ctx, K>, action: Registrar.MethodResolver<Ctx, A, F>,
) { ) {
return (...args: Registrar.MethodParams<Ctx, K>) => return (...args: A): TypedMethodDecorator<F> =>
this.metadata.set( this.metadata.set(
'CordisRegister', 'CordisRegister',
{ new RegisterMeta(action, args, { type }),
type,
args,
action,
},
'CordisRegisterKeys', 'CordisRegisterKeys',
) as TypedMethodDecorator<Registrar.MethodClassMethodFunction<Ctx, K>>; );
} }
decorateTransformer( decorateTransformer<A extends any[]>(
transformer: Registrar.RenderedContextTransformer<Ctx>, transformer: Registrar.ContextTransformer<Ctx, A>,
): ClassDecorator & MethodDecorator { ) {
return this.metadata.append('CordisContextTransformer', transformer); return (...args: A): ClassDecorator & MethodDecorator =>
this.metadata.append(
'CordisContextTransformer',
new RegisterMeta(transformer, args),
);
} }
decorateTopLevelAction(action: Registrar.TopLevelActionDef<Ctx>) { decorateTopLevelAction<A extends any[]>(
return this.metadata.append('CordisTopLevelAction', action); action: Registrar.TopLevelActionDef<Ctx, A>,
) {
return (...args: A): ClassDecorator =>
this.metadata.append(
'CordisTopLevelAction',
new RegisterMeta(action, args),
);
} }
decorateContextLayer(layer: Registrar.ContextCallbackLayer<Ctx>) { decorateContextLayer<A extends any[]>(
return this.metadata.append('CordisContextLayers', layer); action: Registrar.ContextCallbackLayer<Ctx, A>,
) {
return (...args: A): ClassDecorator & MethodDecorator =>
this.metadata.append(
'CordisContextLayers',
new RegisterMeta(action, args),
);
} }
private getFork(obj: any) { private getFork(obj: any) {
...@@ -184,9 +174,7 @@ export class Registrar<Ctx extends Context> { ...@@ -184,9 +174,7 @@ export class Registrar<Ctx extends Context> {
return this.plugin()(fork); return this.plugin()(fork);
} }
afterPluginMethodRegistration( afterPluginMethodRegistration(result: Registrar.RegisterResult<Ctx, any>) {
result: Registrar.RegisterResult<Ctx, any, keyof Registrar.Methods<Ctx>>,
) {
// for override // for override
} }
...@@ -434,34 +422,41 @@ export class Registrar<Ctx extends Context> { ...@@ -434,34 +422,41 @@ export class Registrar<Ctx extends Context> {
return { return {
UseEvent: this.decorateMethod( UseEvent: this.decorateMethod(
'on', 'on',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment (ctx, fun, event: keyof GetEvents<Ctx>, prepend?: boolean) =>
// @ts-ignore ctx.on(event as any, fun, prepend),
(ctx, fun, event, prepend) => ctx.on(event, fun, prepend),
), ),
UsePlugin: this.decorateMethod('plugin', (ctx, fun) => { UsePlugin: this.decorateMethod(
const result = fun(); 'plugin',
const register = (def: PluginRegistrar.PluginDefinition<Ctx, any>) => { (
if (!def) { ctx,
return; fun: (
...args: any[]
) => Awaitable<PluginRegistrar.PluginDefinition<Ctx>>,
) => {
const result = fun();
const register = (def: PluginRegistrar.PluginDefinition<Ctx>) => {
if (!def) {
return;
}
return ctx.plugin(def.plugin, def.options);
};
if (result instanceof Promise) {
return result.then(register);
} else {
return register(result);
} }
return ctx.plugin(def.plugin, def.options); },
}; ),
if (result instanceof Promise) {
return result.then(register);
} else {
return register(result);
}
}),
Apply: this.decorateMethod('apply', (ctx, fun) => fun()), Apply: this.decorateMethod('apply', (ctx, fun) => fun()),
}; };
} }
scopeDecorators() { scopeDecorators() {
return { return {
Isolate: (...services: Registrar.ServiceName<Ctx>[]) => Isolate: (...services: string[]) =>
this.decorateTransformer((ctx, r) => ctx.isolate(r(services))), this.decorateTransformer((ctx, r) => ctx.isolate(r(services))),
UsingService: ( UsingService: (
...services: Registrar.ServiceName<Ctx>[] ...services: string[]
): ClassDecorator & MethodDecorator => { ): ClassDecorator & MethodDecorator => {
return (obj, key?) => { return (obj, key?) => {
if (!key) { if (!key) {
...@@ -472,7 +467,9 @@ export class Registrar<Ctx extends Context> { ...@@ -472,7 +467,9 @@ export class Registrar<Ctx extends Context> {
const dec = this.decorateContextLayer((ctx, cb) => const dec = this.decorateContextLayer((ctx, cb) =>
ctx.using(services, cb), ctx.using(services, cb),
); );
dec(obj, key); // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
dec()(obj, key);
} }
}; };
}, },
...@@ -510,7 +507,7 @@ export class Registrar<Ctx extends Context> { ...@@ -510,7 +507,7 @@ export class Registrar<Ctx extends Context> {
condition: func, condition: func,
}), }),
Provide: ( Provide: (
name: Registrar.ServiceName<Ctx>, name: string,
options?: Registrar.ProvideOptions, options?: Registrar.ProvideOptions,
): ClassDecorator => { ): ClassDecorator => {
Context.service(name, options); Context.service(name, options);
...@@ -563,14 +560,16 @@ export class Registrar<Ctx extends Context> { ...@@ -563,14 +560,16 @@ export class Registrar<Ctx extends Context> {
}; };
} }
transformContext( transformContext<_Ctx extends Ctx>(
ctx: Ctx, ctx: _Ctx,
filters: Registrar.RenderedContextTransformer<Ctx>[], filters: RegisterMeta<Registrar.ContextTransformer<Ctx>>[],
r: ParamRenderer = (v) => v, view: any,
) { ) {
let targetCtx = ctx; let targetCtx = ctx;
for (const fun of filters) { for (const fun of filters) {
targetCtx = fun(targetCtx, r) || targetCtx; // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
targetCtx = fun.run(view, ctx) || targetCtx;
} }
return targetCtx; return targetCtx;
} }
......
import { renderObject } from './render-object';
import { FunctionParams, FunctionReturn } from '../def';
export class RegisterMeta<F extends (...args: any[]) => any, I = any> {
constructor(public action: F, public args: any[], public info?: I) {}
run(view: any, ...extras: FunctionParams<F>): FunctionReturn<F> {
return this.action(...extras, ...renderObject(this.args, view));
}
}
...@@ -14,8 +14,8 @@ declare module 'cordis' { ...@@ -14,8 +14,8 @@ declare module 'cordis' {
} }
interface Events { interface Events {
'pang'(message: string): Promise<string>; 'pang'(message: string): string;
'pong'(message: string): Promise<string>; 'pong'(message: string): string;
} }
} }
...@@ -101,14 +101,14 @@ class MyPartialConsumer { ...@@ -101,14 +101,14 @@ class MyPartialConsumer {
@UsingService('dummyProvider') @UsingService('dummyProvider')
@UseEvent('pang') @UseEvent('pang')
async onPang(content: string) { onPang(content: string) {
const msg = `pang: ${content}`; const msg = `pang: ${content}`;
console.log(msg); console.log(msg);
return msg; return msg;
} }
@UseEvent('pong') @UseEvent('pong')
async onPong(content: string) { onPong(content: string) {
const msg = `pong: ${content}`; const msg = `pong: ${content}`;
console.log(msg); console.log(msg);
return msg; return msg;
...@@ -157,16 +157,16 @@ describe('On service', () => { ...@@ -157,16 +157,16 @@ describe('On service', () => {
await app.start(); await app.start();
app.plugin(MyPartialConsumer); app.plugin(MyPartialConsumer);
expect(app.myPartialConsumer).toBeDefined(); expect(app.myPartialConsumer).toBeDefined();
expect(await app.parallel('pang', 'hello')).toEqual('hello'); expect(app.bail('pang', 'hello')).toBeUndefined();
expect(await app.parallel('pong', 'hello')).toEqual('pong: hello'); expect(app.bail('pong', 'hello')).toEqual('pong: hello');
app.dummyProvider = { foo: 'bar' }; app.dummyProvider = { foo: 'bar' };
expect(await app.parallel('pang', 'hello')).toEqual('pang: hello'); expect(app.bail('pang', 'hello')).toEqual('pang: hello');
expect(await app.parallel('pong', 'hello')).toEqual('pong: hello'); expect(app.bail('pong', 'hello')).toEqual('pong: hello');
app.dummyProvider = undefined; app.dummyProvider = undefined;
expect(await app.parallel('pang', 'hi')).toEqual('hi'); expect(app.bail('pang', 'hi')).toBeUndefined();
expect(await app.parallel('pong', 'hi')).toEqual('pong: hi'); expect(app.bail('pong', 'hi')).toEqual('pong: hi');
app.dummyProvider = { foo: 'baz' }; app.dummyProvider = { foo: 'baz' };
expect(await app.parallel('pang', 'hi')).toEqual('pang: hi'); expect(app.bail('pang', 'hi')).toEqual('pang: hi');
expect(await app.parallel('pong', 'hi')).toEqual('pong: hi'); expect(app.bail('pong', 'hi')).toEqual('pong: hi');
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment