knifecycle
Advanced tools
Comparing version 10.0.0 to 10.0.1
@@ -0,1 +1,10 @@ | ||
## [10.0.1](https://github.com/nfroidure/knifecycle/compare/v10.0.0...v10.0.1) (2020-09-14) | ||
### Bug Fixes | ||
* **utils:** reexport injections utils ([a94b734](https://github.com/nfroidure/knifecycle/commit/a94b734f62c3f0a8307d8e07627fcba8c928335c)) | ||
# [10.0.0](https://github.com/nfroidure/knifecycle/compare/v9.1.1...v10.0.0) (2020-09-14) | ||
@@ -2,0 +11,0 @@ |
@@ -42,2 +42,14 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "useInject", { | ||
enumerable: true, | ||
get: function () { | ||
return _util.useInject; | ||
} | ||
}); | ||
Object.defineProperty(exports, "mergeInject", { | ||
enumerable: true, | ||
get: function () { | ||
return _util.mergeInject; | ||
} | ||
}); | ||
Object.defineProperty(exports, "autoInject", { | ||
@@ -44,0 +56,0 @@ enumerable: true, |
{ | ||
"name": "knifecycle", | ||
"version": "10.0.0", | ||
"version": "10.0.1", | ||
"description": "Manage your NodeJS processes's lifecycle automatically with an unobtrusive dependency injection implementation.", | ||
@@ -83,28 +83,28 @@ "main": "dist/index", | ||
"devDependencies": { | ||
"@babel/cli": "^7.8.4", | ||
"@babel/core": "^7.9.0", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.9.0", | ||
"@babel/preset-env": "^7.9.0", | ||
"@babel/register": "^7.9.0", | ||
"@babel/cli": "^7.10.5", | ||
"@babel/core": "^7.11.1", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.11.0", | ||
"@babel/preset-env": "^7.11.0", | ||
"@babel/register": "^7.10.5", | ||
"babel-eslint": "^10.1.0", | ||
"browserify": "^16.5.1", | ||
"commitizen": "^4.0.3", | ||
"conventional-changelog-cli": "^2.0.31", | ||
"coveralls": "^3.0.11", | ||
"cz-conventional-changelog": "^3.1.0", | ||
"eslint": "^6.8.0", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"jsarch": "^2.0.3", | ||
"jsdoc-to-markdown": "^5.0.3", | ||
"karma": "^4.4.1", | ||
"commitizen": "^4.1.2", | ||
"conventional-changelog-cli": "^2.1.0", | ||
"coveralls": "^3.1.0", | ||
"cz-conventional-changelog": "^3.2.0", | ||
"eslint": "^7.7.0", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"jsarch": "^3.0.0", | ||
"jsdoc-to-markdown": "^6.0.1", | ||
"karma": "^5.1.0", | ||
"karma-browserify": "^7.0.0", | ||
"karma-chrome-launcher": "^3.1.0", | ||
"karma-firefox-launcher": "^1.3.0", | ||
"karma-mocha": "^1.3.0", | ||
"karma-mocha": "^2.0.1", | ||
"karma-sauce-launcher": "^4.1.2", | ||
"metapak": "^3.1.8", | ||
"metapak-nfroidure": "10.1.2", | ||
"mocha": "^7.1.1", | ||
"nyc": "^15.0.0", | ||
"prettier": "^2.0.2", | ||
"metapak": "^3.1.10", | ||
"metapak-nfroidure": "10.2.5", | ||
"mocha": "^8.1.1", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.0.5", | ||
"sinon": "^9.0.1" | ||
@@ -111,0 +111,0 @@ }, |
193
README.md
@@ -11,8 +11,8 @@ [//]: # ( ) | ||
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/knifecycle/blob/master/LICENSE) | ||
[![Build status](https://secure.travis-ci.org/nfroidure/knifecycle.svg)](https://travis-ci.org/nfroidure/knifecycle) | ||
[![Coverage Status](https://coveralls.io/repos/nfroidure/knifecycle/badge.svg?branch=master)](https://coveralls.io/r/nfroidure/knifecycle?branch=master) | ||
[![Build status](https://travis-ci.com/nfroidure/knifecycle.svg?branch=master)](https://travis-ci.com/github/nfroidure/knifecycle) | ||
[![Coverage Status](https://coveralls.io/repos/github/nfroidure/knifecycle/badge.svg?branch=master)](https://coveralls.io/github/nfroidure/knifecycle?branch=master) | ||
[![NPM version](https://badge.fury.io/js/knifecycle.svg)](https://npmjs.org/package/knifecycle) | ||
[![Dependency Status](https://david-dm.org/nfroidure/knifecycle.svg)](https://david-dm.org/nfroidure/knifecycle) | ||
[![devDependency Status](https://david-dm.org/nfroidure/knifecycle/dev-status.svg)](https://david-dm.org/nfroidure/knifecycle#info=devDependencies) | ||
[![Package Quality](http://npm.packagequality.com/shield/knifecycle.svg)](http://packagequality.com/#?package=knifecycle) | ||
[![Package Quality](https://npm.packagequality.com/shield/knifecycle.svg)](https://packagequality.com/#?package=knifecycle) | ||
[![Code Climate](https://codeclimate.com/github/nfroidure/knifecycle.svg)](https://codeclimate.com/github/nfroidure/knifecycle) | ||
@@ -27,62 +27,56 @@ | ||
**The code dependencies** are fully covered by JavaScript | ||
modules in a testable manner (with `mockery` or `System` | ||
directly). There is no need for another dependency management | ||
system if those libraries are pure functions (involve no | ||
global states at all). | ||
**The code dependencies** are fully covered by JavaScript modules in a testable | ||
manner (with `mockery` or `System` directly). There is no need for another | ||
dependency management system if those libraries are pure functions (involve no | ||
global states at all). | ||
Unfortunately, applications often rely on **global states** | ||
where the JavaScript module system shows its limits. This | ||
is where `knifecycle` enters the game. | ||
Unfortunately, applications often rely on **global states** where the JavaScript | ||
module system shows its limits. This is where `knifecycle` enters the game. | ||
It is largely inspired by the Angular service system except | ||
it should not provide code but access to global states | ||
(time, filesystem, db). It also have an important additional | ||
feature to shutdown processes which is really useful for | ||
back-end servers and doesn't exists in Angular. | ||
It is largely inspired by the Angular service system except it should not | ||
provide code but access to global states (time, filesystem, db). It also have an | ||
important additional feature to shutdown processes which is really useful for | ||
back-end servers and doesn't exists in Angular. | ||
You may want to look at the | ||
[architecture notes](./ARCHITECTURE.md) to better handle the | ||
reasonning behind `knifecycle` and its implementation. | ||
You may want to look at the [architecture notes](./ARCHITECTURE.md) to better | ||
handle the reasonning behind `knifecycle` and its implementation. | ||
At this point you may think that a DI system is useless. My | ||
advice is that it depends. But at least, you should not | ||
make a definitive choice and allow both approaches. See | ||
[this StackOverflow answer](http://stackoverflow.com/questions/9250851/do-i-need-dependency-injection-in-nodejs-or-how-to-deal-with/44084729#44084729) | ||
for more context about this statement. | ||
At this point you may think that a DI system is useless. My advice is that it | ||
depends. But at least, you should not make a definitive choice and allow both | ||
approaches. See | ||
[this StackOverflow answer](http://stackoverflow.com/questions/9250851/do-i-need-dependency-injection-in-nodejs-or-how-to-deal-with/44084729#44084729) | ||
for more context about this statement. | ||
## Features | ||
- services management: start services taking their dependencies | ||
in count and shut them down the same way for graceful exits | ||
(namely dependency injection with inverted control); | ||
- singleton: maintain singleton services across several running | ||
execution silos. | ||
- easy end to end testing: just replace your services per your | ||
own mocks and stubs while ensuring your application integrity | ||
between testing and production; | ||
- services management: start services taking their dependencies in count and | ||
shut them down the same way for graceful exits (namely dependency injection | ||
with inverted control); | ||
- singleton: maintain singleton services across several running execution silos. | ||
- easy end to end testing: just replace your services per your own mocks and | ||
stubs while ensuring your application integrity between testing and | ||
production; | ||
- isolation: isolate processing in a clean manner, per concerns; | ||
- functional programming ready: encapsulate global states | ||
allowing the rest of your application to be purely functional; | ||
- no circular dependencies for services: while circular | ||
dependencies are not a problem within purely functional | ||
libraries (require allows it), it may be harmful for your | ||
services, `knifecycle` impeach that while providing an | ||
`$injector` service à la Angular to allow accessing existing | ||
services references if you really need to; | ||
- functional programming ready: encapsulate global states allowing the rest of | ||
your application to be purely functional; | ||
- no circular dependencies for services: while circular dependencies are not a | ||
problem within purely functional libraries (require allows it), it may be | ||
harmful for your services, `knifecycle` impeach that while providing an | ||
`$injector` service à la Angular to allow accessing existing services | ||
references if you really need to; | ||
- generate Mermaid graphs of the dependency tree; | ||
- build raw initialization modules to avoid | ||
embedding Knifecycle in your builds; | ||
- optionally autoload services dependencies with custom | ||
logic. | ||
- build raw initialization modules to avoid embedding Knifecycle in your builds; | ||
- optionally autoload services dependencies with custom logic. | ||
## Usage | ||
Using `knifecycle` is all about declaring the services our | ||
application needs and running your application over it. | ||
Using `knifecycle` is all about declaring the services our application needs and | ||
running your application over it. | ||
Let's say we are building a CLI script. Here is how we would | ||
proceed with Knifecycle: | ||
First, we need to handle a configuration file so we are | ||
creating an initializer to instanciate our `CONFIG` service: | ||
Let's say we are building a CLI script. Here is how we would proceed with | ||
Knifecycle: | ||
First, we need to handle a configuration file so we are creating an initializer | ||
to instanciate our `CONFIG` service: | ||
```js | ||
@@ -180,6 +174,3 @@ // bin.js | ||
async ({ CONFIG, DB_URI, log }) => { | ||
const db = await MongoClient.connect( | ||
DB_URI, | ||
CONFIG.databaseOptions, | ||
); | ||
const db = await MongoClient.connect(DB_URI, CONFIG.databaseOptions); | ||
let fatalErrorPromise = new Promise((resolve, reject) => { | ||
@@ -240,5 +231,5 @@ db.once('error', reject); | ||
// Note that the auto loader must be a singleton | ||
options: { singleton: true } | ||
options: { singleton: true }, | ||
}, | ||
async ({ CONFIG, ARGS }) => async serviceName => { | ||
async ({ CONFIG, ARGS }) => async (serviceName) => { | ||
if ('command' !== serviceName) { | ||
@@ -285,3 +276,3 @@ // Allows to signal that the dependency is not found | ||
// (rarely done but good to know it exists) | ||
await $instance.destroy().catch(err => { | ||
await $instance.destroy().catch((err) => { | ||
console.error('Could not exit gracefully:', err); | ||
@@ -292,3 +283,3 @@ exit(1); | ||
}) | ||
.catch(err => { | ||
.catch((err) => { | ||
console.error('Could not launch the app:', err); | ||
@@ -298,3 +289,5 @@ process.exit(1); | ||
``` | ||
Running the following should make the magic happen: | ||
```sh | ||
@@ -306,3 +299,5 @@ cat "{ commands: './commands'}" > config.json | ||
``` | ||
Or at least, we still have to create commands, let's create the `mycommand` one: | ||
```js | ||
@@ -326,3 +321,5 @@ // commands/mycommand.js | ||
``` | ||
So now, it works: | ||
```sh | ||
@@ -334,10 +331,11 @@ DEBUG=knifecycle CONFIG_PATH=./config.json node -r @babel/register bin.js mycommand test | ||
This is a very simple example but you can find a complexer CLI usage | ||
with `(metapak)[https://github.com/nfroidure/metapak/blob/master/bin/metapak.js]`. | ||
This is a very simple example but you can find a complexer CLI usage with | ||
`(metapak)[https://github.com/nfroidure/metapak/blob/master/bin/metapak.js]`. | ||
## Auto detection | ||
Knifecycle also provide some utility function to automatically assign | ||
the initializer property declarations, the following 3 ways to declare | ||
the `getUser` service are equivalent: | ||
Knifecycle also provide some utility function to automatically assign the | ||
initializer property declarations, the following 3 ways to declare the `getUser` | ||
service are equivalent: | ||
```js | ||
@@ -360,11 +358,11 @@ import noop from 'noop'; | ||
That said, if you need to build your code with `webpack`/`babel` you may | ||
have to convert auto-detections to raw declarations with the | ||
[babel-plugin-knifecycle](https://github.com/nfroidure/babel-plugin-knifecycle) | ||
plugin. You can also do this only for the performance improvements it brings. | ||
That said, if you need to build your code with `webpack`/`babel` you may have to | ||
convert auto-detections to raw declarations with the | ||
[babel-plugin-knifecycle](https://github.com/nfroidure/babel-plugin-knifecycle) | ||
plugin. You can also do this only for the performance improvements it brings. | ||
Also, keep in mind that the auto-detection is based on a simple regular | ||
expression so you should care to keep initializer signatures simple to | ||
avoid having a `E_AUTO_INJECTION_FAILURE` error. As a rule of thumb, | ||
avoid setting complex default values. | ||
expression so you should care to keep initializer signatures simple to avoid | ||
having a `E_AUTO_INJECTION_FAILURE` error. As a rule of thumb, avoid setting | ||
complex default values. | ||
@@ -382,39 +380,40 @@ ```js | ||
Simply use the DEBUG environment variable by setting it to | ||
'knifecycle': | ||
Simply use the DEBUG environment variable by setting it to 'knifecycle': | ||
```sh | ||
DEBUG=knifecycle npm t | ||
``` | ||
The output is very verbose but lead to a deep understanding of | ||
mechanisms that take place under the hood. | ||
The output is very verbose but lead to a deep understanding of mechanisms that | ||
take place under the hood. | ||
## Plans | ||
The scope of this library won't change. However the plan is: | ||
- improve performances; | ||
- evolve with Node: I may not need to transpile this library at | ||
some point. | ||
- evolve with Node: I may not need to transpile this library at some point. | ||
- track bugs ;). | ||
I'll also share most of my own initializers and their | ||
stubs/mocks in order to let you reuse it through | ||
your projects easily. Here are the current projects | ||
that use this DI lib: | ||
- [common-services](https://github.com/nfroidure/common-services): | ||
contains the services I use the most in my apps. | ||
- [swagger-http-router](https://github.com/nfroidure/swagger-http-router): | ||
a complete HTTP router based on OpenAPI definitions with a few useful | ||
services compatible with Knifecycle. | ||
- [memory-kv-store](https://github.com/nfroidure/memory-kv-store): | ||
a simple in memory key-value store. | ||
- [whook](https://github.com/nfroidure/whook): | ||
a framework to build REST web services. | ||
- [postgresql-service](https://github.com/nfroidure/postgresql-service): | ||
a simple wrapper around the `pg` module. | ||
- [jwt-service](https://github.com/nfroidure/jwt-service): | ||
a simple wrapper around the `jwt` module to simplify its use. | ||
Notice that those modules remains usable without using Knifecycle at | ||
all which is maybe the best feature of this library ;). | ||
I'll also share most of my own initializers and their stubs/mocks in order to | ||
let you reuse it through your projects easily. Here are the current projects | ||
that use this DI lib: | ||
- [common-services](https://github.com/nfroidure/common-services): contains the | ||
services I use the most in my apps. | ||
- [swagger-http-router](https://github.com/nfroidure/swagger-http-router): a | ||
complete HTTP router based on OpenAPI definitions with a few useful services | ||
compatible with Knifecycle. | ||
- [memory-kv-store](https://github.com/nfroidure/memory-kv-store): a simple in | ||
memory key-value store. | ||
- [whook](https://github.com/nfroidure/whook): a framework to build REST web | ||
services. | ||
- [postgresql-service](https://github.com/nfroidure/postgresql-service): a | ||
simple wrapper around the `pg` module. | ||
- [jwt-service](https://github.com/nfroidure/jwt-service): a simple wrapper | ||
around the `jwt` module to simplify its use. | ||
Notice that those modules remains usable without using Knifecycle at all which | ||
is maybe the best feature of this library ;). | ||
[//]: # (::contents:end) | ||
@@ -421,0 +420,0 @@ |
@@ -10,2 +10,4 @@ /* eslint max-len: ["warn", { "ignoreComments": true }] */ | ||
inject, | ||
useInject, | ||
mergeInject, | ||
autoInject, | ||
@@ -980,2 +982,4 @@ alsoInject, | ||
inject, | ||
useInject, | ||
mergeInject, | ||
autoInject, | ||
@@ -982,0 +986,0 @@ alsoInject, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1051690
11530
1238