Skip to content

Commit

Permalink
fix: service kind
Browse files Browse the repository at this point in the history
  • Loading branch information
izatop committed Aug 19, 2020
1 parent 28170ca commit d32c142
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 24 deletions.
9 changes: 5 additions & 4 deletions packages/unit/src/Context/Context.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {isInstanceOf, Logger} from "@typesafeunit/util";
import {Service} from "../Service";
import {Logger} from "@typesafeunit/util";
import {IServiceResolver} from "../interfaces";
import {isService, Service} from "../Service";
import {ApplyContext, ResolveService} from "./interfaces";

const cache = new WeakMap();

export class Context {
public static logger = Logger.factory(Context);

public static async resolve<T extends Service<any>>(value: T): Promise<ResolveService<T>> {
if (isInstanceOf(value, Service)) {
public static async resolve<T extends IServiceResolver<any>>(value: T): Promise<ResolveService<T>> {
if (isService(value)) {
return value.resolve();
}

Expand Down
3 changes: 1 addition & 2 deletions packages/unit/src/Context/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {IServiceResolver} from "../interfaces";
import {Service} from "../Service";
import {Context} from "./Context";

export type ResolveService<T extends any> = T extends Service<infer S> ? Promise<S> : T;
export type ResolveService<T extends any> = T extends IServiceResolver<infer S> ? Promise<S> : T;

export type ApplyContext<C extends Context> = {
[K in keyof C]: C[K] extends IServiceResolver<infer M>
Expand Down
3 changes: 3 additions & 0 deletions packages/unit/src/Service/Service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {Ctor, DecoratorTarget} from "@typesafeunit/util";
import {IServiceResolver} from "../interfaces";
import {SERVICE_KIND} from "./fn";
import {ServiceRef} from "./ServiceRef";

export abstract class Service<T> implements IServiceResolver<T> {
public readonly [SERVICE_KIND]: true;

public static getReferences(target: unknown, base: Ctor | null = null): PropertyKey[] {
const references = [];
for (const proto of this.getPrototypes(target, base)) {
Expand Down
18 changes: 18 additions & 0 deletions packages/unit/src/Service/fn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {isInstanceOf, isObject} from "@typesafeunit/util";
import {IServiceResolver} from "../interfaces";
import {Service} from "./Service";

export const SERVICE_KIND = Symbol.for("SERVICE_KIND");

export function isService<T>(maybe: unknown): maybe is IServiceResolver<T> {
if (!isObject(maybe)) {
return false;
}

return isInstanceOf(maybe, Service)
|| (SERVICE_KIND in maybe && "resolve" in maybe);
}

export const resolve: PropertyDecorator = (p, k) => {
Service.resolve()(p, k);
};
2 changes: 1 addition & 1 deletion packages/unit/src/Service/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from "./Service";
export * from "./ServiceFactory";
export * from "./resolve";
export * from "./fn";
5 changes: 0 additions & 5 deletions packages/unit/src/Service/resolve.ts

This file was deleted.

39 changes: 27 additions & 12 deletions packages/unit/test/src/Service.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import {ServiceFactory} from "@typesafeunit/unit";
import {MemoryDb} from "../../../test/src/context/services/MemoryDb";
import {MemoryDbServiceResolver} from "../../../test/src/context/services/MemoryDbServiceResolver";
import {Context} from "../../src/Context";
import {Service, SERVICE_KIND} from "../../src/Service";

const table: [string, (v: string) => any][] = [
["p1", (p) => new MemoryDbServiceResolver(p)],
["p2", (p) => new ServiceFactory(() => MemoryDb.connect(p))],
["p3", (p) => ServiceFactory.create(() => MemoryDb.connect(p))],
["p4", (p) => ServiceFactory.create(MemoryDb.connect(p))],
];
describe("Service", () => {
const table: [string, (v: string) => any][] = [
["p1", (p) => new MemoryDbServiceResolver(p)],
["p2", (p) => new ServiceFactory(() => MemoryDb.connect(p))],
["p3", (p) => ServiceFactory.create(() => MemoryDb.connect(p))],
["p4", (p) => ServiceFactory.create(MemoryDb.connect(p))],
];

test("Service", async () => {
for (const [p, f] of table) {
const service = await f(p).resolve();
expect(service).toBeInstanceOf(MemoryDb);
expect(service.prefix).toBe(p);
}
test("Resolve", async () => {
for (const [p, f] of table) {
const service = await f(p).resolve();
expect(service).toBeInstanceOf(MemoryDb);
expect(service.prefix).toBe(p);
}
});

test("Ref", async () => {
const service = {
[SERVICE_KIND]: true,
async resolve() {
return {service: "test"};
},
};

expect(await Context.resolve(service)).toEqual({service: "test"});
});
});

0 comments on commit d32c142

Please sign in to comment.