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 🙏

© 2025 – Pkg Stats / Ryan Hefner

perfect-di

v1.0.2

Published

Simple alternative to many angular like DI tools

Downloads

8

Readme

perfect-di

DI made simple.

Definitions

Service - a piece of code or data that is useful for the application that other services can use (depend on). Provider - definition of a service dependencies and the exact way it should be created (provided). Module - a group of interdependent services (providers).

Philosophy

This package was created with the following ideas and requirements in mind:

  • simple and transparent
    • module described in one place - ideally a single JSON
    • can be used without typescript - no decorators metadata tricks
    • no (web server) domain specific features
  • reusable modules that can be isolated and published on npm
    • no DI engine specific code in services
    • no binding to specific classes outside of the module - module doesn't import anything outside its directory
  • hierarchical modules
    • modules don't have to be complete - they can depend on services provided by the parent module
    • parent module can use services provided by child modules (submodules)
    • imports/exports between modules should be stated explicitly
  • desired features
    • lazy initialization of services
    • cyclic dependencies detection
    • one service with same dependencies used in multiple modules should be initialized once
    • (not implemented) module deinitialization

Usage

Example 1 - Four Services in One Module

All you need to get started is to define a Module object and call initModule on it.

import { initModule, Module } from 'perfect-di'
import { UserService } from './services/user.service'
import { MongodbService } from './services/mongodb.service'
import { ApiService } from './services/api.service'

const MainModule: Module = {
  providers: {
    'configSvc': { // data as a service
      init: () => {
        apiPort: 8080,
        dbUrl: 'mongodb://url',
      },
    },
    'apiSvc': {
      dependencies: ['configSvc', 'userSvc'],
      init: async (configSvc, userSvc) => {
        const api = new ApiService(userSvc)
        await api.lister(configSvc.apiPort)
        return api
      },
    },
    'userSvc': {
      dependencies: ['dbSvc'],
      init: (dbSvc) => new UserService(dbSvc)
    },
    'dbSvc': {
      dependencies: ['configSvc'],
      init: async (configSvc) => {
        const db = new MongodbService()
        await db.connect(configSvc.dbUrl)
        return db
      },
    },
  },
}

async main() {
  await initModule(MainModule)
}

main()

Example 2 - Submodules

There are multiple ways a provider can be defined in a module:

  • local provider - defined locally through the init function,
  • internal import - imported from submodule via importFrom: 'SubmoduleName',
  • external import - imported from parent module via importFrom: null.

In the last case parent module can rename external imports of its submodule through imports: { 'svcNameInSubmodule': 'svcNameInParent' } syntax.

# config.module.ts
const ConfigModule: Module = {
  providers: {
    'configSvc': {
      doExport: true, // make this provider usable by parent
      init: () => ConfigService,
    },
  },
}


# api.module.ts
const ApiModule: Module = {
  providers: {
    'configSvc': { importFrom: null }, // import this provider from parent
    'apiSvc': {
      doExport: true,
      dependencies: ['configSvc'],
      init: (configSvc) => new ApiService(configSvc),
    },
  },
}


# main.module.ts
const MainModule: Module = {
  providers: {
    'configSvc': { importFrom: 'Config' },
    'apiSvc': { importFrom: 'Api' },
  },
  submodules: {
    'Config': { module: ConfigModule },
    'Api': {
      module: ApiModule
      // imports: {
      //   'configSvc': 'configSvc',
      // },
    },
  }
}

Example 3 - Real Life Example

https://github.com/grabantot/data-net-backend/blob/master/src/modules/main.module.ts