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

@mooncake/container

v1.0.13

Published

DI(dependency injection) container for JavaScript and TypeScript.

Readme

DI(dependency injection)container for JavaScript and TypeScript.

Only support node 9+ (suggest node 10), powered by async_hooks

Notes

// import Container class type
import { Container } from '@mooncake/container'

import container from '@mooncake/container'
// import the global instance of Container (lazy initialize when first import)

Example:

const container = new Container()
container.aliasScope('scope1')
const t1 = new Test1(1)
container.set('test', t1)
process.nextTick(() => {
    container.aliasScope('nt1')
    const t11 = container.get('test') as Test1
    assert.equal(t1, t11, 'should equal')
    const t2 = new Test1(2)
    container.set('test', t2)
    assert.equal(t2, container.get('test'), 'should equal')
    process.nextTick(() => {
        assert(container.hasScope('scope1'))
        assert(container.hasScope('nt1'))
        assert.equal(t2, container.get('test'), 'should equal')
        assert.equal(t1, container.get('test', 'scope1'), 'should equal')
    })
})

API

interface Container {
 
    /**
     * get instance from container
     *
     * @template T
     * @param {Constructor<T>} id
     * @param {string} [fromScope]
     * @returns {T}
     * @memberof ContainerResolver
     */
    get<T>(id: Constructor<T>, fromScope?: string): T
    get<T=any>(id: string | symbol, fromScope?: string): T | undefined

    /**
     * fill prop depencies of an exist instalce
     * it will ignore when target prop has value
     *
     * @param {*} target
     * @param {string} [fromScope]
     * @memberof ContainerResolver
     */
    fill (target: any, fromScope?: string): void

    /**
     * alias of bind Value
     *
     * @template T
     * @param {ID<T>} id
     * @param {T} value
     * @param {Pick<BindOption, 'scope'>} [opt]
     * @memberof ContainerBinder
     */
    set<T> (id: ID<T>, value: T, opt?: Pick<BindOption, 'scope'>): this

    /**
     * bind a exist instalce
     *
     * @template T
     * @param {ID<T>} id
     * @param {T} value
     * @param {Pick<BindOption, 'scope'>} [opt]
     * @memberof ContainerBinder
     */
    bindValue<T> (id: ID<T>, value: T, opt?: Pick<BindOption, 'scope'>): this
    /**
     * bind lazy initialize instance
     *
     * @template T
     * @param {ID<T>} id
     * @param {() => T} creater
     * @param {Partial<BindOption>} [opt]
     * @memberof ContainerBinder
     */
    bind<T> (id: ID<T>, creater: () => T, opt?: Partial<BindOption>): this

    /**
     * bind a class with factory
     *
     * @template T
     * @param {Constructor<T>} id
     * @param {(Factory<T> | Constructor<Factory<T>>)} factory
     * @param {Partial<BindOption>} [opt]
     * @returns {this}
     * @memberof ContainerBinder
     */
    bindFactory<T> (id: Constructor<T>, factory: Factory<T> | Constructor<Factory<T>>, opt?: Partial<BindOption>): this

    /**
     * bind a class
     * set scope or singleton
     *
     * @template T
     * @param {Constructor<T>} cls
     * @param {Partial<BindOption>} [opt]
     * @memberof ContainerBinder
     */
    bindClass<T> (cls: Constructor<T>, opt?: Partial<BindOption>): this
    /**
     * bind a class with an diffrent id
     *
     * @param {ID<any>} id
     * @param {Constructor<any>} cls
     * @param {Partial<BindOption>} [opt]
     * @memberof ContainerBinder
     */
    bindClassWithId (id: ID<any>, cls: Constructor<any>, opt?: Partial<BindOption>): this

    /**
     * alias a id
     *
     * @param {ID<any>} id
     * @param {ID<any>} toId
     * @param {Pick<BindOption, 'scope'>} [opt]
     * @memberof ContainerBinder
     */
    bindAlias (id: ID<any>, toId: ID<any>, opt?: Pick<BindOption, 'scope'>): this


    /**
     * alias current async scope
     *
     * @param {string} name
     * @memberof ContainerBinder
     */
    aliasScope (name: string): this

    /**
     * detect if exist a scope
     * 
     * @param {string} name
     * @memberof ContainerBinder
     */
    hasScope (name: string): boolean
    /**
     * scan the decoractors and auto bind class
     *
     * @param {Constructor<any>} target
     * @memberof ContainerBinder
     */
    autoBind (target: Constructor<any>): this
}

decorators

1.injection

class Test1 {
   
}
// prop inject
class Test2 {
    @Inject()
    prop1!: Test1
}
// constructor inject
class Test3 {
    prop1!: Test1
    constructor(@Inject() param1: Test1) {
        this.prop1 = param1
    }
}
// optional inject
class Test4 {
    @InjectOptional()
    prop1!: Test1   // prop1 will be undefined if resolve Test1 Fail
}

// custom inject action
class Test4 {
    @InjectRaw((c) => c.get('id'), { required: true })
    prop1!: Test1  
}

2. bind with decorators

@Singleton()  // Singleton's default scope is 'root'
// alias as @Service({ singleton: true,scope:'any scope' })

@Service({scope:'request' }) // service default bind opt { singleton: true,scope:'any scope' }
@Alias('a',{scope:'request'}) // alias 'a' to class A 
// Container.get(A) and Container.get('a') will return same result in 'request' scope

@Implement(() => A1)   // container.get(A) will return A1 class instead

@Factory(FactoryA)    // customize instance with factory 

@BindAction((cls,container)=>{
    // customize bind Action
    const instance = new cls()
    // instance.doSomeAction()
    container.set(cls,instance)
})
class A {}

class A1{}

class FactoryA{
    create(){
        const ins = new A1()
        // instance.doSomeAction()
        return ins
    }
}