Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.
/ cakets Public archive

Cake pattern for TypeScript!

License

Notifications You must be signed in to change notification settings

taxfix/cakets

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CakeTS

Inspired by Scala's Cake Pattern, CakeTS is an attempt to provide a minimalistic, and consistent dependency injection pattern for the TypeScript world.

How?

So let's say you want to write a file module that needs some external dependencies, this is how you do it:

import { inject } from 'cakets';
import { DatabaseModule } from './database.module';
import { QueueModule } from './queue.module';

export default inject(({database, queue}: DatabaseModule & QueueModule) => ({
    myFunction: (a: number) => queue.send(database.get(a.toString(2)))
}));

What about those DatabaseModule and QueueModule?

Nothing fancy, there are just typed depencies:

// database.module.ts
import * as database from './database';
import { declare } from 'cakets';

export interface DatabaseModule {
    database: typeof database;
}

export default declare({ database });

declare is just syntax sugar for modules which do not have any dependencies:

// the following is equivalent to: declare({ database })
inject((nothing: {}) => ({ database }));

Now compose all your modules to create your Application

import DatabaseModule from './database.module';
import QueueModule from './queue.module';
import Example1 from './example1';
import Example2 from './example2';


const app = Example2(Example1(QueueModule(DatabaseModule())))();

app.myFunction(10);
app.myFunction2('hello');

What about testing?

Easy peasy, just inject your mocked modules:

import { declare } from 'cakets';
import Example2 from './example2';

const mockQueue = ({
    send: jest.fn()
});

const TestQueueModule = declare({ queue: mockQueue });
const test = Example2(TestQueueModule())();

describe('Example2', () => {
    it('send stuff on the queue', () => {
        test.myFunction2('this is a test');
        expect(mockQueue.send).toHaveBeenCalledWith('this is a test');
    })
})