mariocasciaro / scatter Goto Github PK
View Code? Open in Web Editor NEWIoC container and out-of-the-box extensibility for Node.js applications
License: MIT License
IoC container and out-of-the-box extensibility for Node.js applications
License: MIT License
There's a
this.setModule(name, mod);
missing at Container.js:107
.
Based on Node.js's require()
it should be possible for a module to be dependent not only of other modules but also of directories. The directory should be resolved to <directory>/index.js
.
If you agree I can send a PR.
Instead of returning Promise, is it possible to get the resolved module synchronously?
Given a module a/b/c/module1
.
Is it allowed for module1
to provide a service app/setUp
or must the provided service namespace be a substring of a/b/c/module1
?
Is it also allowed to have an empty service namespace?
Scatter can make the service become a dependency is so powerful,but if an injected service is an asynchronous method and need an callback argument,how deal with that?
At the moment a service invocation like svc!bar/foo
will execute the service foo
under the namespace bar
and all his descendants, this can cause troubles if somebody invokes svc!foo
since it will also execute svc!bar/foo
.
So it is proposed to introduce namespacing for services so instead of defining a service like
provides: {
foo: {}
}
each service must be declared with its full namespace:
provides: {
"bar/foo": {
handler: "fooMethod"
}
}
Autocreate and pass factories as dependencies, e.g 'factory!foo/bar'. Factories will instantiate (and wire) the module dynamically, when the user invokes the factory.
My app runs with Scatter 0.6.0. Updating Scatter to 0.7.0 leads to the following error:
Error: [web-server/index] Cannot find module: :/app/info
at Container.resolveModule (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\lib\Container.js:156:11)
at Container.getModule (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\lib\Container.js:181:15)
at Container.loadModule (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\lib\Container.js:193:18)
at Container._loadOne (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\lib\Container.js:252:17)
at D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\lib\Container.js:312:23
at Promise.FulfilledPromise._when (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\node_modules\when\when.js:439:48)
at deliver (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\node_modules\when\when.js:108:7)
at Array.28 (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\node_modules\when\when.js:105:63)
at runHandlers (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\node_modules\when\when.js:368:12)
at drainQueue (D:\dev\svn\working-copies\ips\ips-mac\mac-ui\test\test-server\node_modules\scatter\node_modules\when\when.js:811:3)
Module app/info is registered by
scatter.registerModuleInstance('app/info', appInfo, {})
and referenced in module web-server/index by
module.exports.__module = {
args: ['app/info', 'app/loggers', 'web-server/impl']
};
first off, awesome project!
ok, heres my issue. In a service, I load an entire namespace (using the scatter-plugin-all
plugin), iterate over the modules and register new modules in a new namespace depending on certain configuration. this part works as expected
// psuedo-code
scatter.load('config')
.then(config => {
scatter.load('all!workers')
.then(workers => {
return Object.keys(workers).map(name => [name, workers[name]]
})
.each(pair => {
const [name, worker] = pair
const data = { /* ... */ }
if (config.enabled[name]) {
const consumer = new Consumer(name, worker, data)
container.registerModuleInstance(`consumers/${name}`, consumer)
}
})
})
the issue is, when I then try to load all of the new namespace in another module, i receive an empty object, unless i load twice. my guess is this has something to do with the caching mechanism and the fact that the new namespace is registered after startup
container.load('all!consumers')
.then(console.log) // {}
.then(() => container.load('all!consumers'))
.then(console.log) // { 'consumers/a': Consumer, 'consumers/b': Consumer }
any ideas on what I'm doing wrong?
Executing 'npm test` under Windows 7 leads to the following console output:
D:\dev\GitHub\repositories\scatter>npm test
> [email protected] test D:\dev\GitHub\repositories\scatter
> ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha test/*.js --report html -- -R spec
Der Befehl "." ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
I don't know if there is a solution for that at all.
Do I understand it right that the name
property in particle.json
is only for distinguishing a particle container (= a particle with subparticles) from a particle with modules?
This works
scatter.registerParticle [ 'components.0', 'components.1' ], __dirname
(scatter.load 'svc|sequence!init').then (app_init) ->
app_init()
.then () ->
(scatter.load 'svc|sequence!start')
.then (app_start) ->
app_start()
but registering the second particle later
scatter.registerParticle [ 'components.0' ], __dirname
(scatter.load 'svc|sequence!init').then (app_init) ->
app_init()
.then () ->
scatter.registerParticle [ 'components.1' ], __dirname
(scatter.load 'svc|sequence!start')
.then (app_start) ->
app_start()
does not work (service init
is provioded by particle.0
, service start
is provioded by particle.1
).
Hi,
Do you think it would be reasonable to generate that __module
declaration implicitly based on args?
Ie. instead of this:
module.exports = function(hello) {
return {
saySomething: function() {
hello();
}
}
};
module.exports.__module = {
args: ["hello"]
};
You would use this:
module.exports = function(hello) {
return {
saySomething: function() {
hello();
}
}
};
It is entirely possible I'm missing something obvious here and that there is a valid reason for the current solution. It just feels like this would be a nice shortcut for small scale development.
Of course this wouldn't work in all cases (ie. relative paths) and there may be other gotchas I'm not aware of (introspecting those params can be a little tricky).
First of all thanks, without people like you I could not stand on the shoulders of giants. That being say a lot of the guide and docs are over my head. You make huge leaps and much of what you are doing looks like 'magic' that I don't understand. I took a look at your example and it was too simple and does not prove a real problem. At least for me, and maybe betting many others a full example with something like express and mongoose would be crazy helpful in understanding how to get started with scatter.
A simple case:
Given a couple routes access a couple models. Bonus would be a plugin that had access to the models.
Also what about node modules? Should they be injected? Or is require always the right answer for those?
This probably involves the creation of a transform to collect the dependencies and manually register them without using the resolver.
Dependencies starting with ./
or ../
should be resolved against the directory of the dependent module.
For me this feature would be very useful but I cannot figure out if this feature is in conflict with other features of Scatter.
Here is a mocha unit test (with failures):
https://gist.github.com/anonymous/2688b7dd54757c60eabf
Provide the way to dynamically build chain of streams using the same way you build services today.
It would be useful if Scatter
's load
method as well supports relative module "paths" as the module dependency specification already does.
It should be possible to write
scatter.load("./web-server/index").then (web_srv) ->
web_srv.setUp appConfig.webServer
instead of
mod_ns = ''
i = scatter.module.name.lastIndexOf '/'
if i >= 0
mod_ns = scatter.module.name[0..i]
... and later ...
scatter.load("#{mod_ns}web-server/index").then (web_srv) ->
web_srv.setUp appConfig.webServer
I am wondering why the particles system in scatter exists. Because you really do not need it:
For example if i have a particle with the name "core" inside the "project" dir :
Now if i want to load the "module" module. I will have the following code inside the "index.js"
// Load other modules
var Scatter = require("scatter");
var path = require("path");
// Create the scatter container
var scatter = new Scatter();
// Define the node modules
scatter.setNodeModulesDir(path.join(__dirname, "node_modules"));
// Register the particles
scatter.registerParticles([
path.join(__dirname, "core")
]);
// Load the module
scatter.load("module").then(function() { // I think here u should write core/module
console.log("Loaded the module");
});
It would be more logicaly if i have to specify the pratcile i am loading that module from while loading it. So rather than loading "module" it should be "core/module"
So why do i need the particles system then? It doesnt help me to organize my code, Or did i misunderstood something?
After running the test suite by manually typing
> node .\node_modules\istanbul\lib\cli.js cover .\node_modules\mocha\bin\_mocha test\*.js --report html -- -R spec
on the console I get the following errors:
1) Scatter basic loading scoped assemble should load only matching modules in advance:
AssertionError: expected { Object (namespace\Module1) } to have key 'namespace/Module1'
2) Scatter basic loading scoped assemble should load only matching modules in advance (with caching):
AssertionError: expected {} to have key 'namespace/Module1'
3) Scatter basic loading scoped assemble should load assemble all (with caching):
AssertionError: expected { Object (Module1, Module2, ...) } to have keys 'namespace/Module1', 'Module1', and 'Module2'
4) Scatter basic loading npm dir loading should discover roots under symlinked dirs:
Error: EPERM, operation not permitted 'D:\dev\GitHub\repositories\scatter\test\01-load\nodeModulesLink\base2'
at Object.fs.symlinkSync (fs.js:730:18)
at Context.<anonymous> (D:\dev\GitHub\repositories\scatter\test\01-load.js:351:10)
at Test.Runnable.run (D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runnable.js:194:15)
at Runner.runTest (D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runner.js:372:10)
at D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runner.js:448:12
at next (D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runner.js:297:14)
at D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runner.js:307:7
at next (D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runner.js:245:23)
at Object._onImmediate (D:\dev\GitHub\repositories\scatter\node_modules\mocha\lib\runner.js:274:5)
at processImmediate [as _immediateCallback] (timers.js:330:15)
Hi it's possible to extends functionality from a file in one folder to other?. For example:
We have this structure:
- components
- c1
- routes.js
- core
- c1
- routes.js
core/c1/routes.js:
module.exports = {
hello: function() {
return 'hello';
},
world: function() {
return 'world';
}
};
components/c1/routes.js:
module.exports = {
hello: function() {
return 'welcome';
}
};
At the end i want to get this module:
module.exports = {
hello: function() {
return 'welcome';
},
world: function() {
return 'world';
}
};
Should i write something in particles? Or Scatter control that?
Thanks and best regards
I changed all of the '.js' -> '.coffee' in Resolver.js and it seems to work fine, but a better solution is needed.
Using benchmark.js or other frameworks
Allow to specify optional/required dependencies. This is useful in case the user wants just to define an order between services/components.
'svc?foo/bar'
'?foo/bar'
Is it allowed to have a module a/b/c/d/module1
providing a service which is defined with name ./service1
?
If yes, what is the resulting service name?
Sometimes,I make mistakes,something like forget to install modules.So,When I start the app,it just hangs there.
If I don't use Scatter,I will see the error stacks in the console.
Why dosen't Scatter just throw the exceptions?or Can I see the errors in the console?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.