Skip to content

Commit

Permalink
✨ Add Metadata (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
spontoreau authored Nov 21, 2024
1 parent 3e1a7d0 commit 8a14787
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 9 deletions.
42 changes: 41 additions & 1 deletion src/core/mediator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MessageHandler } from './messageHandler';
import { clear, mediator } from './mediator';
import { UnknownMessageError } from './errors/unknownMessage.error';
import { MultipleHandlersError } from './errors/multipleHandlers.error';
import { should } from 'chai';
import { expect, should } from 'chai';
import { Middleware } from './middlewares';

should();
Expand Down Expand Up @@ -70,6 +70,46 @@ describe('mediator.send', () => {
actual.should.be.deep.equal(expected);
});

it('should return registered metadata when getting metadata from mediator', async () => {
// Arrange
const type1 = 'TYPE_1';
const type2 = 'TYPE_2';
mediator.register(type2, async () => {}, { meta1Prop: 'meta1value' });
mediator.register(type2, async () => {}, { meta2Prop: 'meta2value' });
mediator.register(type1, async () => {}, { meta3Prop: 'meta3value' });

// Act
const actualMessageMetadata = mediator.getMetadata(type2);

const expectedMessageMetadata = {
meta1Prop: 'meta1value',
meta2Prop: 'meta2value',
};

// Assert
expect(actualMessageMetadata).to.be.deep.equal(expectedMessageMetadata);

const actualAllMetadata = mediator.getAllMetadata();

const expectedAllMetadata = [
{
type: type2,
metadata: {
meta1Prop: 'meta1value',
meta2Prop: 'meta2value',
},
},
{
type: type1,
metadata: {
meta3Prop: 'meta3value',
},
},
];

actualAllMetadata.should.deep.equal(expectedAllMetadata);
});

it('should throw error when sending an unknown message through the mediator', async () => {
// Arrange
const type = 'CREATE_PERSON';
Expand Down
20 changes: 17 additions & 3 deletions src/core/mediator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@ import { MessageHandler } from './messageHandler';
import { MessageResult } from './messageResult';
import { MultipleHandlersError } from './errors/multipleHandlers.error';
import { UnknownMessageError } from './errors/unknownMessage.error';
import { AddOptions, Middleware, middlewares } from './middlewares';
import { AddOptions, middlewares } from './middlewares';
import { Metadata } from './metadata';

const registry = new Map<string, Array<MessageHandler>>();
const metadatas = new Map<string, Metadata>();

const register = <TKey extends string, TMessage extends Message<TKey>>(
messageType: TKey,
messageHandler: MessageHandler<TMessage>,
metadata: Metadata = {},
) => {
const handlers = registry.get(messageType) ?? [];
registry.set(messageType, [...handlers, messageHandler as MessageHandler]);
const meta = metadatas.get(messageType);
metadatas.set(messageType, {
...meta,
...metadata,
});
};

const getHandlers = <TKey extends string, TMessage extends Message<TKey>>(
Expand All @@ -23,7 +31,7 @@ const getHandlers = <TKey extends string, TMessage extends Message<TKey>>(
}

const handlers = registry.get(messageType) as Array<MessageHandler<TMessage>>;
return handlers.map((h) => middlewares.apply(messageType, h));
return handlers.map((handler) => middlewares.apply(messageType, handler));
};

const send = async <TMessage extends Message>({
Expand Down Expand Up @@ -51,18 +59,24 @@ const use = <TMessage extends Message>(options: UseOptions<TMessage>) => {
middlewares.add(options);
};

const getMessageTypes = () => [...registry.keys()].sort();
const getMessageTypes = () => Array.from(registry.keys()).sort();
const getMetadata = (type: string) => metadatas.get(type);
const getAllMetadata = () =>
Array.from(metadatas.entries(), ([key, value]) => ({ type: key, metadata: value }));

const mediator = {
register,
send,
publish,
use,
getMessageTypes,
getMetadata,
getAllMetadata,
} as const;

const clear = () => {
registry.clear();
metadatas.clear();
middlewares.clear();
};

Expand Down
1 change: 1 addition & 0 deletions src/core/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Metadata = Record<string, unknown>;
12 changes: 7 additions & 5 deletions src/core/middlewares.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const createChain = <TMessage extends Message>(
const middlewares = [
...globalMiddlewares,
...(messageMiddlewares.get(messageType) ?? []),
...(handlerMiddlewares.get(handler) ?? []),
...(handlerMiddlewares.get(handler as MessageHandler) ?? []),
];

const chain = (): MessageHandler<TMessage> => {
Expand Down Expand Up @@ -54,8 +54,9 @@ const hasMiddlewares = <TMessage extends Message>(
const hasGlobalMiddlewares = !!globalMiddlewares.size;
const hasMessageMiddlewares = !!(messageMiddlewares.get(messageType) || [])
.length;
const hasHandlerMiddlewares = !!(handlerMiddlewares.get(handler) || [])
.length;
const hasHandlerMiddlewares = !!(
handlerMiddlewares.get(handler as MessageHandler) || []
).length;

return hasGlobalMiddlewares || hasMessageMiddlewares || hasHandlerMiddlewares;
};
Expand Down Expand Up @@ -105,9 +106,10 @@ const add = <TMessage extends Message>(options: AddOptions<TMessage>) => {
]);
}
} else if (isAddHandlerMiddlewaresOptions(options)) {
const middlewares = handlerMiddlewares.get(options.handler) ?? [];
const middlewares =
handlerMiddlewares.get(options.handler as MessageHandler) ?? [];

handlerMiddlewares.set(options.handler, [
handlerMiddlewares.set(options.handler as MessageHandler, [
...middlewares,
...(options.middlewares as ReadonlyArray<Middleware>),
]);
Expand Down

0 comments on commit 8a14787

Please sign in to comment.