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

speedball

v0.2.1

Published

A dependency injection library.

Downloads

4

Readme

Build Status Project Status: WIP - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public. David Join the chat at https://gitter.im/cameron-martin/speedball

Speedball

Speedball is a combinator-based dependency injection library. It consists of:

  • Factories, which are functions that produce dependencies.
  • A Speedball class, which is used to register factories with and resolve dependencies using those factories.
  • Factory creators, which are functions that produce factories, given something which is not a factory.
  • Factory combinators, which are functions that take factories as arguments and produce factories. These are used for modifying factories.

Installation

npm install --save speedball

Example

class House {
  constructor(streetNumber) {
    this._streetNumber = streetNumber;
  }

  toString() {
    return 'House at street number ' + this._streetNumber +
      'with neighbour at street number ' + this.neighboursStreetNumber;
  }

  increaseTemperature() {
    this.heater(1);
  }

  decreaseTemperature() {
    this.heater(-1);
  }
}

const heater = log => heatingAmount => {
  log('heating by ' + heatingAmount);
};
import Speedball, { construct, props, func, value, singleton } from 'speedball';

var speedball = new Speedball()
  .register('house', props(
    construct(House, ['streetNumber']),
    { neighboursStreetNumber: 'neighboursStreetNumber' }
  ))
  .register('heater', singleton(func(heater, ['log'])));
  .register('log', value(console.log.bind(console)));
  .register('streetNumber', value(1));
  .register('neighboursStreetNumber', function(speedball) {
    return speedball.resolve('streetNumber') - 1;
  });

Design Goals

  • To not be tied to a particular module system.
  • To allow injecting dependencies into functions, e.g.  const f = (dep1, dep2) => (arg1, arg2) => {}
  • To be extensible. The indicator I used for this is the ability to implement AOP without modifying existing code.

API

The types in the API documentation use the syntax of flow.

Speedball class

This is what you will use to configure your dependency graph and resolve your dependencies with. Unless you are creating custom factory combinators/creators, the Factory<T> type can be considered abstract.

register<T>(name: string, factory: Factory<T>): Speedball

Registers a dependency under the name name.

resolve<T>(name: string): T

Resolves a dependency that has been registered under the name name.

Factory creators

Factory creators are functions that construct factories, given something that is not a factory

value<T>(value: T): Factory<T>

Create a constant factory that always returns value. This is useful for configuration constants, e.g. database connection strings, but also for injecting values such as window and localStorage.

construct<T>(constructor: Class<T>, entities: Array<string> = []): Factory<T>

Creates a factory that resolves the entities entities, constructs the class constructor with them, then returns the instance. Similar to func.

func<T>(func: (...args: any) => T, entities: Array<string> = []): Factory<T>

Creates a factory that resolves the entities entities, calls the function func with them, then returns the result. Similar to construct.

fromContainer<T>(container: Speedball, entity: string): Factory<T>

Creates a factory that resolves the entity entity from another speedball container.

Factory combinators

Factory combinators modify behaviour of exsting factories. All factory combinators return new factories, rather than mutating existing ones.

singleton<T>(factory: Factory<T>): Factory<T>

Converts a factory into a singleton factory, i.e. a factory that memoises the result.

props<T>(factory: Factory<T>, props: { [key: string]: string }): Factory<T>

Converts a factory into a factory that behaves the same as originally, but also has the behaviour of injecting entities as properties of the subject. The keys of props are the property names, and the values are entity names.

Factory type

A factory is a function that is used to instantiate your dependencies.

type Factory<T> = (x: IResolver) => T;

AfterHook type

type AfterHook = (resolver: IResolver) => void;

IResolver interface

An IResolver is something that can be used to resolve other dependencies during resolution of a dependency and enquire about and modify various aspects of the resolution procedure.

This will probably only be of interest if you are developing custom factory combinators/constructors.

resolve<T>(name: string): T

Resolves a dependency that has been registered under the name name. Behaves the same as Speedball#resolve.

after(f: AfterHook): void

Registers an after hook, a function that is executed after the root dependency is resolved, but before it is returned to the user. This can be used to "join the circle" when resolving cyclic dependencies.

willCauseCycle(name: string): bool

Determines whether resolving the dependency registered under the name name would result in the dependency graph being cyclic. This can be used in combination with after to resolve cyclic dependencies.

Custom factory examples

Stateful counter factory creator

This could be used for injecting unique ids into classes and functions.

function counter() {
    let count = 1;
    
    return function() {
        return count++;
    }
}

TODO

  • Implement AOP features. Maybe as a seperate npm module?
  • Make better testing.
    • Have a separation between unit and integration tests?
    • Do some property-based testing where arbitrary dependency graphs are generated and assertions are calculated based on whether they are cyclic or acyclic.
    • Find out why travis is failing on all nodes < 5.0
  • Add code climate etc.
  • Submit PR to micro js.

Contributing

Pull requests are very much welcome. Also, if there is something you want added or something is broken then please open an issue.