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

@dliv/minject

v0.1.2

Published

A Javascript Dependency Injection library built with an emphasis on constructor injection and ES6 classes.

Downloads

2

Readme

Minject

Minject is a Javascript Dependency Injection library built with an emphasis on constructor injection and ES6 classes. The 'M' is for 'map' and/or 'minimal'. Map because constructor arguments are injected as a single object for easy destructuring. Minimal because it has (a lot) fewer features than other libraries (Angular's module system, BottleJS, etc).

Minject is also tiny: 2.5KB before gzip.

Getting Started

The Minject module can be loaded as:

  • A CommonJS / Node module available as the npm package @dliv/minject
  • A script tag (creates the global variable Minject when dist/index.js is included on the page)

API and Examples

The most comprehensive documentation is the set of spec files in the src folder and the ESDocs associated with each public method.

Minject (constructor)

The constructor does not accept any options. That should probably change.

ES6 module

Install with npm i @dliv/minject. Then:

import Minject from '@dliv/minject';

const services = new Minject();

Minject is a scoped npm module; ostensibly because of the left-pad issue (but really because some Haxe thing already has the name).

script tag

Include dist/index.js on your page. Then:

var services = new window.Minject();

chaining

Methods for adding values / services are chainable.

services
    .value('debugMode', false)
    .eagerService('Water', Water)
    .lazyService('ColdBrew', ColdBrew, { water: 'Water', coffee: 'Coffee', brewTime: 'BrewTime' })
    .service('Coffee', Coffee)
    .service('BrewTime', BrewTime);

const coldBrew = services.get('ColdBrew'); // `services.get(name)` can't return `services` for obvious reasons

Minject#value(serviceName, serviceValue)

services.value('name', value);

Registers a value that is already constructed as an injectible dependency for services when requested by @param name. The @param value will not be created with new, invoked, or mutated - it is passed as is when asked for by a service.

Minject#service(serviceName, serviceConstructor[, dependencies])

Registers a service name and constructor pair, with optional dependencies for the constructor. The created service is a cached singleton (it can be retrieved multiple times but only one instance will be created).

class Water {
    constructor () {
        // ...
    }
}


class Coffee {
    constructor ({ water, coffee, time }) {
        // ...
    }

    brew () {
        const { water, coffee, time } = this._services;
        // ...
    }
}


class AngularCoffee {
    constructor ({ water, coffee, time }) {
        // ...
    }
}

AngularCoffee.$inject = { water: 'ColdWater', coffee: 'CoarseGroundCoffee', time: 'OverNight '};
// or `AngularCoffee.$inject = ['water', 'coffee', 'time'];`


class ImplicitCoffee {
    constructor ({ water, coffee, time }) {
        // ...
    }
}

ImplicitCoffee._inject =  { water: 'ColdWater', coffee: 'CoarseGroundCoffee', time: 'OverNight '};
// or `ImplicitCoffee._inject = ['water', 'coffee', 'time'];`

services
    .service('water', Water)
    .service('ColdBrew', Coffee, { water: 'ColdWater', coffee: 'CoarseGroundCoffee', time: 'OverNight '})
    .service('BasicCoffee', Coffee, ['water', 'coffee', 'time'])
    .service('AngularCoffee', AngularCoffee)
    .service('ImplicitCoffee', ImplicitCoffee);

The dependencies param can be an array of registered service names or an object mapping constructor param name to registered dependency name; when using the array syntax, the constructor param name will be inferred (as equal to) the dependency's name. If the dependency param is omitted, the constructor will also be checked for a (static) property named $inject or _inject.

As a side effect, after the constructor is invoked, a _services property is added to the constructed service; this convenience means the constructor does not have to save every service it is passed.

Dependencies are looked up when the service is created; lazy services can specify dependencies that have not been registered yet, while eager services can only use already registered services as dependencies. It is unspecified whether Minject#service is constructed lazily or eagerly. The current default is eager (to surface errors sooner, at the expense of potentially creating services that are never injected).

WARNING: may register a lazy service in a future version.

Minject#eagerService(serviceName, serviceConstructor[, dependencies])

Registers a dependency name and value; immediately creates the value. See Minject#service.

class Eager {
    constructor () {
        console.log('Eager service created.');
    }
}

services.eagerService('Eager', Eager);

// immediately logs 'Eager service created.'
// but service may never be injected or retrieved with `Minject#get`

Minject#lazyService(serviceName, serviceConstructor[, dependencies])

Registers a dependency name and value; delays creating the value until it is needed. See Minject#service.

class LazyPi {
    constructor () {
        console.log('LazyPi created.');
        this.value = this._calculatePi();
    }
}

class CircleAreaCalculator {
    constructor ({ pi }) {
        console.log('CircleAreaCalculator created.');
        // ...
    }
}

services.lazyService('pi', LazyPi);

// <nothing logged>

services.eagerService('Calculator', CircleAreaCalculator, ['pi']);

// logs 'LazyPi created.'
// then 'CircleAreaCalculator created.'

Minject#get(serviceName)

Returns the specified service; will create (with dependencies) and cache the service if needed. If you can organize your app as a single (eager) service, you don't need this method. Overuse of this method will lead to the Service Locator pattern and is discouraged.

WARNING: may be renamed, removed, or limited in a future version.

// detect-env.js
services.value('$window', typeof window === 'undefined' ? mockWindow : window);


// controller1.js
const $window = services.get('$window');

Status

Very beta. Besides the limited functionality, lots of error checking is missing (e.g. checking for circular dependencies).