feat(core): `undefined` context dependency
User is able to insert `undefined` value inside of a collection of dependencies to register.
MODIFY
packages/core/src/http/server/http.server.spec.ts
packages/core/src/http/server/http.server.spec.ts
@@ -4,9 +4,11 @@ import * as https from 'https';
import { EventEmitter } from 'events';
import { forkJoin } from 'rxjs';
import { tap, filter, take } from 'rxjs/operators';
+import { pipe, constant } from 'fp-ts/lib/function';
import { HttpServer } from '../http.interface';
-import { lookup } from '../../context/context';
+import { lookup, bindTo } from '../../context/context';
import { useContext } from '../../context/context.hook';
+import { createContextToken } from '../../context/context.token.factory';
import { HttpServerClientToken } from './internal-dependencies/httpServerClient.reader';
import { httpListener } from './http.server.listener';
import { createServer } from './http.server';
@@ -99,10 +101,35 @@ describe('#createServer', () => {
expect(boundServer).toBeDefined();
});
+ test('can register `nullable` context dependency', async () => {
+ // given - context dependency
+ const someToken = createContextToken();
+ const someDependency = 'test';
+
+ // given - server
+ const app = await createServer({
+ listener: httpListener(),
+ dependencies: [
+ bindTo(someToken)(constant(someDependency)),
+ undefined,
+ ],
+ });
+
+ // when
+ server = await app();
+
+ // then
+ const ask = lookup(app.context);
+ const boundDependency = useContext(someToken)(ask);
+
+ expect(boundDependency).toEqual(someDependency);
+ });
+
test(`emits server events`, async done => {
const app = await createServer({
listener: httpListener(),
- event$: event$ => forkJoin(
+ event$: event$ => pipe(
+ forkJoin([
event$.pipe(filter(isErrorEvent), take(1)),
event$.pipe(filter(isClientErrorEvent), take(1)),
event$.pipe(filter(isCloseEvent), take(1)),
@@ -112,7 +139,7 @@ describe('#createServer', () => {
event$.pipe(filter(isUpgradeEvent), take(1)),
event$.pipe(filter(isCheckContinueEvent), take(1)),
event$.pipe(filter(isCheckExpectationEvent), take(1)),
- ).pipe(
+ ]),
tap(() => done()),
),
});

MODIFY
packages/core/src/http/server/http.server.ts
packages/core/src/http/server/http.server.ts
@@ -2,11 +2,12 @@ import * as http from 'http';
import * as https from 'https';
import { merge, EMPTY } from 'rxjs';
import { takeWhile } from 'rxjs/operators';
-import { pipe } from 'fp-ts/lib/pipeable';
+import { pipe } from 'fp-ts/lib/function';
+import { filter } from 'fp-ts/lib/Array';
import { lookup, bindTo, bindEagerlyTo } from '../../context/context';
import { createEffectContext } from '../../effects/effectsContext.factory';
import { isTestingMetadataOn } from '../../+internal/testing';
-import { insertIf } from '../../+internal/utils';
+import { insertIf, isNonNullable } from '../../+internal/utils';
import { HttpServer } from '../http.interface';
import { logContext } from '../../context/context.logger';
import { contextFactory } from '../../context/context.helper';
@@ -40,7 +41,7 @@ export const createServer = async (config: CreateServerConfig) => {
boundHttpServerEvent,
boundHttpRequestBus,
...insertIf(isTestingMetadataOn())(boundHttpRequestMetadataStorage),
- ...dependencies,
+ ...filter(isNonNullable)(dependencies),
);
logContext(LoggerTag.HTTP)(context);

MODIFY
packages/core/src/listener/listener.interface.ts
packages/core/src/listener/listener.interface.ts
@@ -29,5 +29,5 @@ export interface ServerConfig<
> {
event$?: T;
listener: U;
- dependencies?: BoundDependency<any>[];
+ dependencies?: (BoundDependency<any> | undefined | null)[];
}

MODIFY
packages/messaging/src/server/messaging.server.ts
packages/messaging/src/server/messaging.server.ts
import * as E from 'fp-ts/lib/Either';
-import { pipe } from 'fp-ts/lib/pipeable';
-import { identity } from 'fp-ts/lib/function';
+import { identity, pipe } from 'fp-ts/lib/function';
+import { filter } from 'fp-ts/lib/Array';
import { Subject } from 'rxjs';
import { takeWhile, takeUntil, take } from 'rxjs/operators';
import { bindTo, createEffectContext, combineEffects, ServerIO, lookup, logContext, LoggerTag, contextFactory } from '@marblejs/core';
-import { throwException, maskUriComponent } from '@marblejs/core/dist/+internal/utils';
+import { throwException, maskUriComponent, isNonNullable } from '@marblejs/core/dist/+internal/utils';
import { provideTransportLayer } from '../transport/transport.provider';
import { statusLogger$ } from '../middlewares/messaging.statusLogger.middleware';
import { TransportLayerConnection } from '../transport/transport.interface';
@@ -35,7 +35,7 @@ export const createMicroservice = async (config: CreateMicroserviceConfig) => {
boundEventTimerStore,
boundTransportLayer,
boundServerEvents,
- ...dependencies,
+ ...filter(isNonNullable)(dependencies),
);
logContext(LoggerTag.MESSAGING)(context);

MODIFY
packages/websockets/src/server/websocket.server.ts
packages/websockets/src/server/websocket.server.ts
@@ -3,8 +3,9 @@ import * as net from 'net';
import * as WebSocket from 'ws';
import { Observable, of } from 'rxjs';
import { map, takeWhile } from 'rxjs/operators';
+import { filter } from 'fp-ts/lib/Array';
import { Context, contextFactory, createEffectContext, ServerIO, LoggerTag, lookup, logContext, combineEffects } from '@marblejs/core';
-import { createUuid, isNullable } from '@marblejs/core/dist/+internal/utils';
+import { createUuid, isNonNullable, isNullable } from '@marblejs/core/dist/+internal/utils';
import { createServer, handleServerBrokenConnections, handleClientBrokenConnection } from '../server/websocket.server.helper';
import { WebSocketConnectionError } from '../error/websocket.error.model';
import { statusLogger$ } from '../middlewares/websockets.statusLogger.middleware';
@@ -34,7 +35,7 @@ export const createWebSocketServer = async (config: WebSocketServerConfig) => {
);
};
- const context = await contextFactory(...dependencies);
+ const context = await contextFactory(...filter(isNonNullable)(dependencies));
logContext(LoggerTag.WEBSOCKETS)(context);

feat(core): `undefined` context dependency

User is able to insert `undefined` value inside of a collection of dependencies to register.