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 🙏

© 2026 – Pkg Stats / Ryan Hefner

iocello

v1.0.0

Published

Inversion of Control

Readme

Welcome to iocello!

This Library empowers you with the concept of Dependency Injection. and allows Inversion of control.

Note: This is a STAGE 2 decorator. also it depends on corello to exist in your package json.

Note: If you are using this in a FE framework like react or vue, make sure to add your services before you bootstrap your application, you can automate this by using blob or webpack context. for webpack there is a built-in method loadServices, while for vite you can utilize the ioc.add to add the loaded service files..

Sample Vite project

Check out source code for the sample application (Vue+vite)

The Concept

Imagine having a library of book shelves (domains), the lowset shelf has number 0 (domain) you can store your books (classes/services) in any shelf, and you can cross-reference those books at runtime, by passing the preferred domain

By default the books will be fetched from the current domain ( passed to IoC at construction time). When tagging a book to be used by the shelf you assign a tag, and a domain i.e shelf to be stored in.

when you try to get a book you tell the ioc to construct and instance of any book, IoC will try to fetch it from currently activeDomain, or by specifying the domain you wish to fetch it explicitly.

you can Invert to Control of your Application and change the constructed class shelf/container by setting ioc.setContainerDomain!

Setup

To make a class Injectable. use @Service To inject a property inside your class use @inject

Services should be added to the IoC by calling IoC.add(ServiceClass) Instances can be instantiated dynamically from the IoC by calling ioc.construct<Type>(TagNameString ,domainNumber?)

import { Service, Inject } from './decorators/service';

import {type IInjectable } from 'corello';
import { ioc } from './decorators/di';

// Pet class will be added to IoC, we use @Service here..
// note the tag param; this is used when dealing with the class in the IoC, a unique name (alias)
@Service({tag:'Pet'})
class Pet {
  // the Person class is also injected here, please note that this instance will be fetched from domain/scope 1
  // also note that we had to pass the tag as a param because we decided to customise the property name to person (all lower case in this example..)
  @inject({tag:'Person',domain:1} ) person!: Person
  walk() {
    console.log('PET IS WALKING')
  }
  // all services need to provide an implementation of the dispose method, this is used for any clean up..
  dispose() {}
}

// here we add the Pet Service to the IoC.. will be registered and tagged as `Pet`
ioc.add(Pet)


interface IPerson extends IInjectable {
  hello?:string
  semsem:Pet
}

interface IPerson2 extends IPerson {
 Pet:Pet
}

// another service named Person, and will have a tag `Person`, note that we can pass configuration for service, check the TS Type to learn more..
@Service({tag:'Person'})
class Person implements IPerson {
  hello:string= "Hello!"
  // this property is injected as well, in normal situations this will cause a circular dependency error, but the IoC will solve this for you..
  // note that the Pet property has a custom name `semsem`, also we need it to be specifically fetched from domain 1
  @inject({domain:1,tag:'Pet'}) semsem!: Pet
  dispose() {}
}

//This class will be enforced in level 0 meaning that it will replace any matching services in the same domain
@Service({tag:'Person', enforce:{domain:0}})
class Person2 extends Person implements Person2{

  // this property will by default create an instance from the service with tag `Pet`
  @inject() Pet!: Pet
  dispose() {}

}

ioc.add(Person)
ioc.add(Person2)

//Person2 will replace Person because of the enforce
// also check the console as IoC will warn you about services that were not found where their supposed to be,
// you will be warned also about service overrites, in case it was un-intentional

const person =  ioc.construct<Person>('Person',100)
person.Pet.walk()
console.log(person)

Note: In your ts-config make sure to enable the experimental decorators.

Note: This Library relies on the amazing '@abraham/reflection' as a replacement for the ts reflection, (a great size drop).