You need to sign in or sign up before continuing.
Commit adbfce6d authored by nanahira's avatar nanahira

current

parent d2aaf271
...@@ -10,3 +10,4 @@ export * from './src/patch-string-in-object'; ...@@ -10,3 +10,4 @@ export * from './src/patch-string-in-object';
export * from './src/observe-diff'; export * from './src/observe-diff';
export * from './src/memorize'; export * from './src/memorize';
export * from './src/may-be-array'; export * from './src/may-be-array';
export * from './src/app-context';
import { Empty, Prettify } from '../types';
import {
AppContext,
AppServiceClass,
AppProvideArgs,
AppProvidedMerged,
AppProvideOptions,
AppContextUsed,
} from './types';
const ServiceClassPrefix = 'class:';
const ProvidePrefix = 'provide:';
export class AppContextCore<T = Empty, Req = Empty> {
private __current: T;
private __required: Req;
provide<
C extends AppServiceClass<T>,
const P extends string = '',
const M extends (keyof InstanceType<C>)[] = [],
>(
cls: C,
...args: AppProvideArgs<T, C, P, M>
): AppProvidedMerged<T, Req, C, P, M> {
const options = args[args.length - 1] as
| AppProvideOptions<T, C, P, M>
| undefined;
return this as any;
}
get<R>(cls: AppServiceClass<T, any, R>): R {}
use<T2>(ctx: AppContext<T2, T>): AppContext<Prettify<T & T2>, Req> {
return this as any;
}
define(): AppContext<T, Req> {
return this as any;
}
async start(): Promise<AppContext<T, Req>> {
return this as any;
}
}
export const createAppContext = <Req = Empty>() =>
new AppContextCore<Req, Req>() as AppContext<Req, Req>;
// testing code below
class Foo {
constructor(
public ctx: AppContext,
private foo = 3,
) {}
getFoo() {
return this.foo;
}
}
class Bar {
constructor(
public ctx: AppContext<{ foo: Foo }>,
private bar: number,
) {}
getBar() {
return this.bar + this.ctx.foo.getFoo();
}
}
class Baz {
constructor(public ctx: AppContext<{ foo: Foo }>) {}
getBaz() {
return this.ctx.foo.getFoo() * 2;
}
}
async function test() {
const ctx1 = createAppContext()
.provide(Foo, 3, { provide: 'foo' })
.provide(Bar, 5, {
merge: ['getBar'],
})
.provide(Foo, 3, { provide: 'foo22' })
.define();
const ctx2 = createAppContext<{ foo: Foo }>()
.provide(Baz, {
provide: 'baz',
})
.define();
const ctx = await createAppContext().use(ctx2).define().start();
}
import { Empty } from '../types';
import { AppContext } from './types';
export class AppServiceBase<T = Empty, Config extends any[] = []> {
constructor(
public ctx: AppContext<T>,
...args: Config
) {}
async init() {}
}
export * from './types';
export * from './app-context';
export * from './app-service-base';
import { Awaitable, Empty, Prettify } from '../types';
import { AppContextCore } from './app-context';
export type AppContext<T = Empty, Req = Empty> = AppContextCore<T, Req> & T;
export type AppServiceClass<T = Empty, A extends any[] = any[], R = any> = new (
ctx: AppContext<T>,
...args: A
) => R;
export type AppServiceConfig<C extends AppServiceClass> = C extends new (
first: any,
...args: infer A
) => any
? A
: never;
export type AppProvideOptions<
T,
C extends AppServiceClass<T>,
P extends string,
M extends (keyof InstanceType<C>)[],
> = {
provide?: P;
merge?: M;
useValue?: InstanceType<C>;
useFactory?: (
ctx: AppContext<T>,
...args: ConstructorParameters<C>
) => Awaitable<InstanceType<C>>;
useClass?: new (...args: ConstructorParameters<C>) => InstanceType<C>;
};
export type AppProvideArgs<
T,
C extends AppServiceClass<T>,
P extends string,
M extends (keyof InstanceType<C>)[],
> = [...args: AppServiceConfig<C>, options?: AppProvideOptions<T, C, P, M>];
export type AppProvidedMerged<
T,
Req,
C extends AppServiceClass<any>,
P extends string,
M extends (keyof InstanceType<C>)[],
> = AppContext<
Prettify<
T & {
[K in M[number]]: InstanceType<C>[K];
} & (P extends '' ? Empty : { [K in P]: InstanceType<C> })
>,
Req
>;
export type Awaitable<T> = T | Promise<T>; export type Awaitable<T> = T | Promise<T>;
export type AnyClass = new (...args: any[]) => any; export type AnyClass = new (...args: any[]) => any;
export type ClassType<T = any> = new (...args: any[]) => T; export type ClassType<T = any> = new (...args: any[]) => T;
export interface Empty {}
export type Prettify<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
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