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

inceptor

v1.0.1

Published

Ownership-driven dependency injection for Javascript

Downloads

5

Readme

Inceptor.js

Build Status Coverage Status

Sauce Test Status

Ownership-driven dependency injection for JavaScript

Usually, dependency injection frameworks rely on central container to retrieve dependencies.

In contrast, this ownership-driven approach spawn scopes when these dependencies are created.

Features:

  • Very small (5kb minified).
  • Does not depend on any other library.
  • Works everywhere! Both node.js and browser are supported.
  • Re-uses familiar loading mechanisms such as requirejs or node's require.
  • Does not need string names to map objects.
  • Code is well-tested.
  • Scopes can be tested in isolation without dependency map.
  • Once dependency map is used, it becomes immutable.
  • No global variables or containers!

How does it work?

This container turns the problem on its head: instead of creating a dependency when your code requests it, Inceptor.js does the reverse.

It runs your code when all dependencies are created.

Let's look at simple example.

Suppose we have a simple logger that logs our messages to multiple backends.

In traditional DI, we would inject the backends into the logger constructor.

Here, we do the reverse: we tell the backend to require the logger.

Let's see the code for logger:

var Logger = inceptor.scope({
    initialize: function() {
        this.backends = [];
    },

    log: function(message) {
        for (var i = 0; i < this.backends.length; i++) {
            this.backends[i].log(message);
        }
    }
});

Here, we achieved the abstraction: the logger knows nothing about the backends, the only thing it requires is that they implement the log() method.

Let's see the code for backend:

var Backend = inceptor.scope([Logger], {
    initialize: function(logger) {
        logger.backends.push(this);
    },

    log: function(message) {
        console.log(message);
    }
});

Here, the backend receives the logger over the first argument, and adds itself to the list.

Somewhere at the root of the project, we add both the Logger and the Backend to dependency map:

var deps = inceptor.load(
    Logger,
    Backend,
);

And later create the logger using this map:

var logger = deps.create(Logger);
logger.log('Hello!');

Receive the Hello! in console!

If we later need a different Backend implementation, or want to silence the logs, we don't need to touch the logger, just modify the backend.

So, we have achieved what is required from the dependency injection.

The big difference here is that lifetime of all objects spawned by logger depend directly on the lifetime of logger. If a new logger is created, the whole tree of dependent objects is created too.

Usage in frameworks

Intrigued? See how it can be used in your environment:

License

MIT