feat(core): uniform Listener interface + factory
ADD
packages/core/src/context/context.reader.factory.ts
+import { pipe } from 'fp-ts/lib/pipeable';
+import * as R from 'fp-ts/lib/Reader';
+import { ContextProvider, reader } from './context.factory';
+
+export type ReaderHandler<T> = (ask: ContextProvider) => T;
+
+export const createReader = <T>(handler: ReaderHandler<T>) =>
+ pipe(reader, R.map(handler));

MODIFY
packages/core/src/http/effects/http.effects.interface.ts
packages/core/src/http/effects/http.effects.interface.ts
@@ -19,7 +19,7 @@ export interface HttpErrorEffect<
export interface HttpServerEffect<
Ev extends Event = Event
-> extends HttpEffect<Ev, any, HttpServer> {}
+> extends HttpEffect<Ev, any> {}
export interface HttpOutputEffect<
Req extends HttpRequest = HttpRequest,
@@ -29,5 +29,4 @@ export interface HttpOutputEffect<
export interface HttpEffect<
I = HttpRequest,
O = HttpEffectResponse,
- Client = HttpServer,
-> extends Effect<I, O, Client> {}
+> extends Effect<I, O, HttpServer> {}

MODIFY
packages/core/src/http/server/http.server.listener.ts
packages/core/src/http/server/http.server.listener.ts
import { IncomingMessage, OutgoingMessage } from 'http';
-import { pipe } from 'fp-ts/lib/pipeable';
-import * as R from 'fp-ts/lib/Reader';
import { HttpMiddlewareEffect, HttpErrorEffect, HttpOutputEffect } from '../effects/http.effects.interface';
import { HttpRequest, HttpResponse } from '../http.interface';
import { handleResponse } from '../response/http.responseHandler';
-import { RouteEffect, RouteEffectGroup, RoutingItem } from '../router/http.router.interface';
+import { RouteEffect, RouteEffectGroup, Routing } from '../router/http.router.interface';
import { resolveRouting } from '../router/http.router.resolver.v2';
import { factorizeRoutingWithDefaults } from '../router/http.router.factory';
import { ROUTE_NOT_FOUND_ERROR } from '../router/http.router.effects';
-import { Context, lookup } from '../../context/context.factory';
import { createEffectContext } from '../../effects/effectsContext.factory';
import { useContext } from '../../context/context.hook';
+import { createListener } from '../../listener/listener.factory';
import { ServerClientToken } from './http.server.tokens';
export interface HttpListenerConfig {
+ effects?: (RouteEffect | RouteEffectGroup)[];
middlewares?: HttpMiddlewareEffect[];
- effects: (RouteEffect | RouteEffectGroup)[];
error$?: HttpErrorEffect;
output$?: HttpOutputEffect;
}
export interface HttpListener {
(req: IncomingMessage, res: OutgoingMessage): void;
- config: { routing: RoutingItem[] };
+ config: { routing: Routing };
};
-export const httpListener = ({
+export const httpListener = createListener<HttpListenerConfig, HttpListener>(config => ask => {
+ const {
+ effects = [],
middlewares = [],
- effects,
output$,
error$,
-}: HttpListenerConfig): R.Reader<Context, HttpListener> => pipe(
- R.ask<Context>(),
- R.map(ctx => {
- const ask = lookup(ctx);
+ } = config;
+
const client = useContext(ServerClientToken)(ask);
const effectContext = createEffectContext({ ask, client });
- const routing = factorizeRoutingWithDefaults(effects, middlewares);
+ const routing = factorizeRoutingWithDefaults(effects, middlewares ?? []);
const { resolve, errorSubject } = resolveRouting(routing, effectContext)(output$, error$);
const httpServer = (req: IncomingMessage, res: OutgoingMessage) => {
@@ -58,5 +55,4 @@ export const httpListener = ({
httpServer.config = { routing };
return httpServer;
- }),
-);
+});

MODIFY
packages/core/src/index.ts
packages/core/src/index.ts
@@ -29,7 +29,12 @@ export * from './operators';
export * from './event/event.factory';
export * from './event/event.interface';
+// core - listener
+export * from './listener/listener.factory';
+export * from './listener/listener.interface';
+
// core - context
export * from './context/context.factory';
export * from './context/context.hook';
+export * from './context/context.reader.factory';
export * from './context/context.token.factory';

ADD
packages/core/src/listener/listener.factory.ts
+import { flow } from 'fp-ts/lib/function';
+import { createReader, ReaderHandler } from '../context/context.reader.factory';
+import { ListenerConfig, Listener } from './listener.interface';
+
+export type ListenerHandler<T extends ListenerConfig, U> =
+ (config: T) => ReaderHandler<U>;
+
+export const createListener = <T extends ListenerConfig, U>(
+ handler: ListenerHandler<T, U>
+): Listener<T, U> => flow(handler, createReader);

ADD
packages/core/src/listener/listener.interface.ts
+import { Reader } from 'fp-ts/lib/Reader';
+import { Effect } from '../effects/effects.interface';
+import { Context } from '../context/context.factory';
+
+export interface ListenerConfig<T = any> {
+ effects?: any[];
+ middlewares?: any[];
+ error$?: Effect<any, any, T>;
+ output$?: Effect<any, any, T>;
+}
+
+export interface Listener<T extends ListenerConfig, U> {
+ (config: T): Reader<Context, U>;
+}

feat(core): uniform Listener interface + factory