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

smart-factory

v1.0.12

Published

functional programming-ready dependancy injector/ioc container library

Downloads

126

Readme

smart-factory

npm version

Simple but powerful, functional-programming ready Dependency Injector/Container library for node.js.

dependency injection library for not only classes but also functions, strings, numbers, ... and all objects in the world.

features

  • simple syntax, easy to use
  • functional-programming ready
  • lightweight
  • built-in typescript supports
  • supports lazy-instantiation

installation

npm i smart-factory

simple usage

javascript + es6

const { init, injectable, resolve } = require('smart-factory');

// module names
const ModuleNames = {
  MSG_PROVIDER: 'MSG_PROVIDER',
  MSG_PRINTER: 'MSG_PRINTER',
  GREETER: 'GREETER'
};

// regiser message provider function to container
injectable(ModuleNames.MSG_PROVIDER,
  [], 
  () =>
    new Promise((resolve) => {
      const toBeRegistered = (lang) => { // msgProvider function.
        if (lang === 'en') return 'HELLO!';
        else if (lang === 'ko') return '안녕하세요!';
        else if (lang === 'es') return 'HOLA!';
        return 'UNKNOWN';
      };
      resolve(toBeRegistered);
    }));

// register message printer function to container
injectable(ModuleNames.MSG_PRINTER,
  [], 
  () => 
    new Promise((resolve) => {
      const toBeRegistered = (msg) => console.log(msg); // msgPrinter function
      resolve(toBeRegistered);
    }));

// register greeter function to container.
injectable(ModuleNames.GREETER,
  [ModuleNames.MSG_PROVIDER, ModuleNames.MSG_PRINTER], // required dependencies
  (provider, printer) => // dependencies which injected from container
    new Promise((resolve) => {
      const toBeRegistered = (lang) => { // greeter function.
        printer(provider(lang));
      };
      resolve(toBeRegistered);
    }));

(() => {
  init() // awaiting container ready
    .then(() => {
      const greet = resolve(ModuleNames.GREETER); // injects greeter function from container.
      greet('en'); // HELLO!
    });
})();

typescript + es2015

import { init, injectable, resolve } from 'smart-factory';

export enum Modules {
  HELLO_FUNC = 'HELLO_FUNC',
  MSG_PROVIDER = 'MSG_PROVIDER',
  MSG_PRINTER = 'MSG_PRINTER'
}

export type MsgProvider = (lang: string) => string;
export type MsgPrinter = (msg: string) => void;
export type HelloFunction = (lang: string) => void;

injectable(
  Modules.MSG_PROVIDER, // module name
  [], // dependencies
  async (): Promise<MsgProvider> =>
    (lang: string): string => {
      if (lang === 'en') return 'HELLO!';
      else if (lang === 'ko') return '안녕하세요!';
      else if (lang === 'es') return 'HOLA!';
      return 'UNKNOWN';
    });

injectable(
  Modules.MSG_PRINTER,
  [],
  async () : Promise<MsgPrinter> =>
    (msg: string) => console.log(msg);

injectable(
   Modules.HELLO_FUNC,
   [ Modules.MSG_PROVIDER, Modules.MSG_PRINTER ], // has dependencies to MsgProvider, MsgPrinter
   async (provider: MsgProvider, printer: MsgPrinter): HelloFunction =>
     (lang: string) => {
       printer(provider(lang));
     });

(async () => {
  await init();

  const helloFunc = resolve<HelloFunction>(Modules.HELLO_FUNC);
  helloFunc('es'); // HOLA!
})();

API reference

async init(opts?: ContainerOptions): Promise<void>

initialize container. after init() executed, you can retreive a modules from container.

type ContainerOptions

| key | mandantory | default | description | | --- | --- | -- | -- | | debug?: boolean | no | false | show container logs. for debug purpose. | | includes?: string[] | no | null | specify path for modules which calls injectable(). | | excludes?: string[] | no | null | specify path for exceptional modules. |

example

(async () => {
  await init({
    debug: true,
    includes: [`${__dirname}/**/*.ts`]
  });
})();

injectable(key: string, deps: string[], instantiator: Instantiator): void

register modules to container. the dependencies deps[] will be injeted before the module instantiated.

after all dependencies meets requirements, the modules will be instantiated and registered to container with name key.

the instantiator is your async function that preparing instance from given dependencies deps[].

example

type Coffee = {
  bean: CoffeeBean;
  water: Water;
  sugar: Sugar;
};
type CoffeeMaker = () => Coffee;

injectable(
  'COFFEE_MAKER', // module name
  [ 'COFFEE_BEAN', 'WATER', 'SUGAR' ], // required dependencies
  async (bean, water, sugar): Promise<CoffeeMaker> => // the "Instantiator": returns coffeeMaker function. 
    () => { // coffeeMaker function
      return {
        bean, water, sugar
      }
    }
);

resolve<T>(key: string): <T>

resolves module from container. with typescript, you can specify type.

example

(async () => {
  const makeCoffee = await <CoffeeMaker>resolve('COFFEE_MAKER');
  const coffee = makeCoffee();
  console.log(coffee); // { bean, water, sugar }!
})();

set<T>(key: string, instance: T): void

replace an instance in container with given key and instance. you can use this feature in the test codes.

(async () => {
  injectable('A', [], async () => 10);
  await init(); // container initialized.

  const value = <number>resolve('A');
  console.log(value); // "10"

  set('A', 20);
  const valueAfterSet = <number>resolve('A');
  console.log(valueAfterSet); // "20"
})();

clear(): void

clear all instances in container

(async () => {
  injectable('A', [], async () => 10);
  await init(); // container initialized.

  const value = <number>resolve('A');
  console.log(value); // "10"

  clear(); // nothing in container.
})();

More complicated examples

There are a more complicated examples that using smart-factory. you can learn how to manage complicated dependencies (ex: configuration, database, models..) for complicated application with the smart-factory.

  • Chatpot-Room-Server
    • chatting-room server written with Typescript, smart-factory
    • configurations, mysql, models, api endpoints
    • shows handling modules names and types with typescript way.