1
0
Fork 0
Thin dependency injection for JavaScript (Guice for JS)
Go to file
renovate[bot] cb94fada9a update: update dependency @microsoft/api-documenter to v7.21.4 2023-02-08 16:31:46 -06:00
.github update: from rollup-template 2019-09-24 06:52:11 -05:00
.gitlab update: update node.js to v16.14 2022-03-25 07:32:16 -05:00
config fix(build): correct GPG socket in dev container 2022-01-29 19:41:04 -06:00
docs fix(docs): describe how to use field decorator, add example 2022-10-20 08:34:08 -05:00
scripts feat(build): add alpine image from template 2019-11-09 23:13:49 -06:00
src fix(module): consistently use contract name type 2022-10-20 08:34:08 -05:00
test fix(test): cover missing fields better 2022-10-20 08:34:08 -05:00
vendor/rollup-resources feat(build): rollup json/yaml (update from rollup-template) 2019-09-28 10:45:20 -05:00
.codeclimate.yml feat(build): replace tslint with eslint 2019-11-09 14:46:39 -06:00
.dockerignore feat(build): adopt rollup-template 2019-09-24 06:52:11 -05:00
.eslintrc.json remove: tslint from eslint config 2022-10-16 09:13:33 -05:00
.gitignore feat: only bind module prototype if it exists 2021-03-27 17:56:19 -05:00
.gitlab-ci.yml feat(build): switch to c8 for coverage 2022-01-29 17:20:45 -06:00
.mdlrc fix(build): disable line lengths in markdownlint 2019-09-27 18:03:58 -05:00
.npmignore feat(build): adopt rollup-template 2019-09-24 06:52:11 -05:00
.npmrc feat(build): adopt rollup-template 2019-09-24 06:52:11 -05:00
CHANGELOG.md chore(release): 5.0.0-3 2022-10-20 08:51:00 -05:00
Dockerfile.alpine update: update node.js to v17 (#882) 2022-01-30 10:22:32 -06:00
Dockerfile.stretch update: update node.js to v17 (#882) 2022-01-30 10:22:32 -06:00
LICENSE.md clean up readme, ignores 2018-04-20 18:16:17 -05:00
Makefile fix(build): update API extractor report for ES modules 2022-01-29 18:52:57 -06:00
README.md feat: document supported Node versions 2021-07-10 16:08:31 -05:00
examples feat(test): add readme example as test 2020-04-04 09:53:51 -05:00
package.json update: update dependency @microsoft/api-documenter to v7.21.4 2023-02-08 16:31:46 -06:00
renovate.json feat(build): upgrade to rollup from webpack 2019-08-25 11:39:22 -05:00
run.mk fix(build): update with additional makefile 2019-09-28 15:26:09 -05:00
tsconfig.json update with changes from apex-world 2018-04-20 18:06:58 -05:00
yarn.lock update: update dependency @microsoft/api-documenter to v7.21.4 2023-02-08 16:31:46 -06:00

README.md

noicejs

Extremely thin, async dependency injection, now with a getting started guide.

Inspired by Google's Guice library and written in Typescript.

Features

  • async dependency resolution
  • constructor and property injection
  • modular containers with inheritance
  • named dependencies using strings or unique symbols
  • typed errors
  • typescript typedefs
  • zero runtime dependencies, bundled or otherwise
  • extensive test coverage

Contents

Status

Pipeline status Lines of Code Test coverage MIT license FOSSA Status

Open bug count Open issue count Closed issue count

Renovate badge Dependency status Dev dependency status Known vulnerabilities

Maintainability score Technical debt ratio Quality issues Language grade: JavaScript Total alerts

Releases

  • 3.x versions are compatible with Node 12+
  • 4.x versions are compatible with Node 16+

github release link github release version github commits since release

npm package link npm release version Typescript definitions

Usage

Consider a Server class that needs to fetch data from the Cache and Filesystem, but doesn't know (or need to know) how those are implemented. The following example is also part of the unit tests.

import { LocalModule } from './local';
import { NetworkModule } from './network';

class Cache {
  public get(path: string, ttl: number, fallback: () => Promise<string>): Promise<string> {
    /* ... */
  }
}

class Filesystem {
  public get(path: string): Promise<string> {
    /* ... */
  }
}

/**
 * Constructors, strings, and symbols are supported. Symbols are
 * preferred, as the most unique, but names can be convenient.
 */
@Inject(Cache.name.toLowerCase(), Filesystem.name.toLowerCase())
class Server {
  protected readonly cache: Cache;
  protected readonly filesystem: Filesystem;
  protected readonly ttl: number;

  constructor(options) {
    this.cache = options.cache;
    this.filesystem = options.filesystem;
    this.ttl = defaultTo(options.ttl, 0);
  }

  get(path: string) {
    return options.cache.get(path, this.ttl, () => options.filesystem.get(path));
  }
}

const TEST_TTL = 60;

function module() {
  if (process.env['DEBUG'] === 'TRUE') {
    return new LocalModule();
  } else {
    return new NetworkModule();
  }
}

async function main() {
  const container = Container.from(module());
  await container.configure();

  const server = await container.create(Server, {
    /* cache and filesystem are found and injected by container */
    ttl: TEST_TTL,
  });

  /* server.cache.get and server.filesystem.get will be called in order */
  const result = await server.get('some/file');
}

noicejs will collect dependencies from the decorated constructor and any superclasses, find a provider for each injected dependency, and asynchronously resolve them before calling the constructor. Any extra parameters are passed on to the original constructor, along with the container and resolved dependencies.

Build

To build a bundle and run tests:

> make

yarn
yarn install v1.17.3
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.20s.
/home/ssube/code/ssube/noicejs//node_modules/.bin/rollup --config /home/ssube/code/ssube/noicejs//config/rollup.js

src/index.ts, test/harness.ts, test/**/Test*.ts → out/...
...
created out/ in 3.3s
/home/ssube/code/ssube/noicejs//node_modules/.bin/api-extractor run --config /home/ssube/code/ssube/noicejs//config/api-extractor.json --local -v

api-extractor 7.3.8  - https://api-extractor.com/
...

API Extractor completed successfully
Success!

License

FOSSA Status