npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

brandi-typed

v1.0.7

Published

Brandi with boosted type safety for DI modules

Downloads

10

Readme

Brandi-Typed: A Dependency Injection Library for Dependency Modules

Brandi-Typed is an extension of the Brandi dependency injection library, designed to provide fully typed dependency modules, making it impossible to get runtime dependency injection errors (like missing bindings).

Installation

To install Brandi-Typed, use npm:

npm install brandi-typed

Usage

First, declare your module by defining the brandi tokens that serve to identify each dependency :


// module.ts

import { token } from 'brandi'
import { makeInjectedModule } from 'brandi-typed'
import { Service } from './application'
import { Repository } from './repositories'
import { Factory } from './factories'

export const TOKENS = {
  factory: token<Factory>('Factory'),
  repository: token<Repository>('Repository'),
  service: token<Service>('Service'),
} as const

export const module = makeInjectedModule(TOKENS)

The type information of module retains the types for TOKENS keys and values.

Using this information, the module should only be used within a brandi Container if all its tokens are bound to the instance implementation (singleton or transient, etc.).

To define your implementations :


// bootstrap.ts

export const bootstraped = module
  .bind('factory', (bnd) => bnd.toInstance(FactoryImpl))
  .bind('repository', (bnd) => bnd.toInstance(RepositoryImpl))
  .bind('service', (bnd) => bnd.toInstance(ServiceImpl))

, then "compile" it to a brandi DependencyModule, that it usable from your container using the magic make method to do compile-time checking:


// bootstrap.ts

export const dependencyModule = module
  .bind('factory', (bnd) => bnd.toInstance(FactoryImpl))
  .bind('repository', (bnd) => bnd.toInstance(RepositoryImpl))
  .bind('service', (bnd) => bnd.toInstance(ServiceImpl))
  .make()

//make sure to register injections:
injected(ServiceImpl, TOKENS.factory)  // using the brandi's `injected`
module.injector(ServiceImpl, 'factory') // or using the module's `injector` method

It ensures that all bind calls were made with all the initial tokens.

When registering injectors, the module.injector is a boilerplate that is less painful to write, because the tokens are already encoded as type information within module, and the token key can already be inferred. Therefore, in the exemple the argument 'factory' is provided by keyboard autocompletion, no need to import the TOKENS objects.

Hence, the library helps getting a boilerplate-free, 100% usable brandi DependencyModule all with compile-time proofness !

Usage with Brandi's Container

A brandi Container can use tokens from a brandi DependencyModule. With Brandi-Typed, the module comes with an allTokens attributes which can be used to use all your module tokens in a container:

container.use(...dependencyModule.allTokens).from(dependencyModule)

Usage with multiple modules

Brandi-Typed provides operations to compose modules. Simply import the modules and use the combine method to merge them into a single module:

import { module as module1 } from './module1'
import { module as module2 } from './module2'

export const module = module1.combine(module2)

All tokens from the combined modules will be available in the new module. You can then use the new module as described above.

You can even bind tokens from one module and combine already bound tokens from another module, which will be useful for bootstraping each one of you modules separately:

import { bootstraped as bootstraped1 } from './bootstrap1'
import { module as module2 } from './module2'

export const bootstraped2With1 = bootstraped1
  .combine(module2)
  .bind('mod2token', /* */) 
  .make()  // call to make() if all tokens in combined modules are bound

Conclusion

Brandi-Typed simplifies the process of dependency injection and helps developers avoid common mistakes and runtime errors. With its strongly-typed tokens, it ensures that all dependencies are properly resolved at compile time and provides a more streamlined way to declare your modules in TypeScript projects.

License

APACHE 2.0

Contributing

Brandi-Typed is an open source project and we welcome contributions. Please create an issue or pull request if you find any bugs or have any suggestions.