pdi
Advanced tools
Comparing version 1.2.0 to 2.0.0
{ | ||
"name": "pdi", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"description": "Minimal Promise based dependency injection framework", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -16,3 +16,3 @@ # PDI - Minimal Promise based Dependency Injection framework | ||
const pdi = require("pdi") | ||
pdi.add("dao", ["db"], (db) => createDao(db)) | ||
pdi.add("dao", ["db"], ({ db }) => createDao(db)) | ||
@@ -25,13 +25,12 @@ // File 3 | ||
const pdi = require("pdi") | ||
pdi.add(["dao", "config"], (dao, config) => { | ||
pdi.add(["dao", "config"], ({ dao, config }) => { | ||
createServer(dao, config) | ||
}) | ||
pdi.start() | ||
.then(logSuccess) | ||
.catch(logError) | ||
pdi | ||
.start() | ||
.then(logSuccess) | ||
.catch(logError) | ||
``` | ||
The api consists of: | ||
@@ -43,5 +42,5 @@ | ||
- `add(name, dependencies, factory)` - Registers a named factory function with dependencies. The factory will only be called when the dependencies are available. They will be passed in as arguments to the factory function. | ||
- `add(name, factory)` - A simpler form of the above where there are no dependencies. | ||
- `add(dependencies, factory)` - Registers a factory without a name. This is for side-effect functions. | ||
* `add(name, dependencies, factory)` - Registers a named factory function with dependencies. The factory will only be called when the dependencies are available. They will be passed in as arguments to the factory function. | ||
* `add(name, factory)` - A simpler form of the above where there are no dependencies. | ||
* `add(dependencies, factory)` - Registers a factory without a name. This is for side-effect functions. | ||
@@ -54,6 +53,9 @@ `name` must be a string | ||
NB This function will be called with a single argument which is an object containing | ||
the required dependencies. | ||
This function will throw on the following conditions: | ||
- if the DI container has already started | ||
- if a factory has already been registered with the same name | ||
* if the DI container has already started | ||
* if a factory has already been registered with the same name | ||
@@ -66,5 +68,5 @@ ### `start` | ||
- if `start` has already been called | ||
- if there is a missing dependency | ||
- if there is a circular dependency | ||
* if `start` has already been called | ||
* if there is a missing dependency | ||
* if there is a circular dependency | ||
@@ -87,16 +89,15 @@ The function sorts all previously registered factory functions according to the dependency graph. It then calls as many factory functions in parallel as possible. If any of the functions throw then the promise will reject. | ||
flow.add("body", req.body) | ||
flow.add("userId", ["body"], prop("userId")) | ||
flow.add("userId", ["body"], path(["body", "userId"])) | ||
flow.add("user", ["userId"], getUser) | ||
flow.add("friends", ["user"], getFriends) | ||
flow.add("result", ["friends", "user"], assoc("friends")) | ||
flow.start(["result"]) | ||
.then((result) => res.send(result)) | ||
.catch((err) => res.sendStatus(500)) | ||
flow.add("result", ["friends", "user"], mergeFriendsAndUser) | ||
flow | ||
.start(["result"]) | ||
.then(result => res.send(result)) | ||
.catch(err => res.sendStatus(500)) | ||
``` | ||
Extra utils for testing: | ||
Extra utils for testing: | ||
- `pdi._test.clear()` | ||
- `pdi._test.` | ||
* `pdi._test.clear()` | ||
* `pdi._test.` |
@@ -13,2 +13,3 @@ const Promise = require("bluebird") | ||
map, | ||
pick, | ||
flip, | ||
@@ -73,4 +74,4 @@ apply, | ||
return Promise.map(items, item => { | ||
const args = map(flip(prop)(memo), item.deps) | ||
return Promise.resolve(apply(item.fn, args)) | ||
const opts = pick(item.deps, memo) | ||
return Promise.resolve(item.fn(opts)) | ||
}).then(compose(merge(memo), zipObj(names))) | ||
@@ -83,4 +84,14 @@ } | ||
const addToRegistry = (registry, name, deps, fn) => | ||
(registry[name] = {fn, deps, name}) | ||
const addToRegistry = (registry, name, deps, fn) => { | ||
if (fn.length > 1) { | ||
throw new Error( | ||
`Attempted to register ${name} with a length of ${fn.length} | ||
pdi v2 passes all dependencies as a single object to allow developers to simulate | ||
named arugments using destructing. It therefore doesn't accept functions with | ||
a length of more than 1` | ||
) | ||
} | ||
registry[name] = {fn, deps, name} | ||
} | ||
@@ -87,0 +98,0 @@ function createInstance() { |
@@ -0,1 +1,2 @@ | ||
/* eslint max-nested-callbacks: 0 */ | ||
const {ok, equal, deepEqual, throws} = require("assert") | ||
@@ -95,2 +96,7 @@ const pdi = require("../src/index") | ||
it("doesn't accept functions who require multiple arguments", () => { | ||
throws(() => { | ||
pdi.add("1", [], (a, b) => [a, b]) | ||
}, /single object/i) | ||
}) | ||
}) | ||
@@ -105,3 +111,2 @@ | ||
}) | ||
}) | ||
@@ -127,3 +132,3 @@ | ||
return pdi.start().then(() => { | ||
ok(fn1.calledWith(foo)) | ||
ok(fn1.calledWith({"2": foo})) | ||
}) | ||
@@ -142,7 +147,6 @@ }) | ||
return pdi.start().then(() => { | ||
ok(fn1.calledWith(foo, foo2)) | ||
ok(fn1.calledWith({"2": foo, "3": foo2})) | ||
}) | ||
}) | ||
}) | ||
}) |
49083
287
98