Giter Club home page Giter Club logo

pluto.js's People

Contributors

ecowden avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

pluto.js's Issues

Eager Loading

This is a toughy.

Lazy loading makes sense for fast startups, but it means that we can't guarantee that any given factory function ever gets called. So, if I'm relying on, for instance, Express routes getting registered, I can't.

Possible options:

  1. Eager-load all functions. Just iterate through the registry after the bind function. This has the added benefit of identifying missed bindings up front.
  2. Create a module.start() kinda function that does the above.
  3. Create an alternate to bind() (bindAndCreate()?) that will mark the binding for eager loading. Or extend the binding vocabulary to be something like (bind(...).toFactory(...).andEagerLoad()). I kinda like the previous option better because it would be easier to scan through and see what is simply bound and what is set to be initialized.

Add circular dependency detection

Pluto bootstrapping fails without evidence when two or more functions are dependent on each other. Perhaps an error could be thrown if this situation occurs.

serviceOne.js
module.exports = function(serviceTwo) {
...
}

serviceTwo.js
module.exports = function(serviceOne) {
...
}

Continuous Integration

As the project owner, I want a CI tool building my project so that I get test results and simplified deployment.

Node-ify

Let's make this a proper Node/NPM module

Bundle Bootstrapping

After we have asynchronous injection (#25), the old .eagerlyLoadAll(...) doesn't make as much sense. Instead, this is our opportunity to "bootstrap" the whole shebang (probably the whole application). It should try to load all injectables, resolve all promises as needed, and return an object holding the fully bootstrapped set of components.

  const anInstance = Promise.resolve({}) // Promises will be resolved
  const bind = pluto()
  bind('myInstance').toInstance(anInstance)

  // ... eagerly load everything. Maybe `.bootstrap()`?
  const app = yield bind.eagerlyLoadAll()

  // ...and then everything can be retrieved synchronously
  t.is(app.get('myInstance'), anInstance)

Eliminate Ugly Constructor Hack

Back when I originally made this, I was targeting browsers and Node.js v0.8.x. (Also, it's about the first thing I ever wrote in JavaScript.) Dynamically invoking constructor functions was black magic, so I relied on a big ol' switch statement.

Nowadays, this should be easier to work around.

Improve Syntax

The weird callback thing is just ugly. Instead, consider something cleaner:

const pluto = require('pluto')
const bind = pluto()

const myInstance = {}
pluto.bind('myInstance').toInstance(myInstance) // and other bindings

const promise = pluto.get('myInstance') // get(...) must return a promise to support async

promise.then( (result) => {
  t.is(result, myInstance)
})

Remove test duplication

As a developer, I want to clean up the module loading code duplicated in the tests so that there isn't ugly copy pasta in my codebase, and so that adding new tests is easier.

Modernize

  • Update code conventions to es2015
  • Update test framework to AVA
  • Incorporate eslint

Angular-ize the API?

I'm really not sure if this is a good idea or a terrible idea...

We've gotten very used to Angular-style dependency injection. Since Angular has gotten so much traction, it seems to make sense to adopt a similar API.

I could pretty easily adjust the API to look like:

pluto.module('myModule')
    .factory('myFactoryFunction', function(dependencyOne, dependencyTwo) {
        ...
    });

...but then there's artifacts (like a name for the module, or module dependencies) which don't seem to make sense for Node. There's no "multiple modules got loaded by the browser" thing - it's all just require(...) calls.

Guice-style bootstrapping seems to make more sense.

'Module' name needs to be changed

There's already plenty of modules out there. In particular, Node's module, which just happens to be a kinda-sorta huge concept and global variable in the Node world.

Let's get rid of the 'module' nomenclature in favor of something a bit less vague.

Installation documentation

As the project owner, I want documentation on how to integrate Pluto into a project so that people can get started easily.

Create example app

Create an example app.

Consider using an Express application, since it's such a popular framework.

I'd also love to have a kata example that I can use as a template.

Clean style

My understanding of JavaScript has grown a lot since I first created this:

  • Consider functional style instead of inheritence
  • Consider many vars
  • Naming! (eww...)

Integration test suite

As the project owner, I want an integration test suite so that I have greater confidence in the project from end to end.

Throw on non-string names

As a developer, I want an error if I try to use something other than a String for a name so that I don't screw things up.

Asynchronous Injection

Pluto should support asynchronous bootstrapping by automatically detecting and resolving promises, then injecting their resolved values when used as a dependency.

Sample usage:

  function Greeter(name) {
    this.name = name
  }

  Greeter.prototype.greet = function () {
    return `Hello, ${this.name}!`
  }

  const bind = pluto()
  bind('name').toInstance(Promise.resolve('World'))
  bind('greeter').toConstructor(Greeter)

  const theGreeter = yield bind.get('greeter')

  t.is(theGreeter.greet(), 'Hello, World!')

Add License

I should officially add a license file.

I'm thinking the MIT license makes the most sense.

Memoize

Calls to module.get(...) should be memoized. This effectively turns everything injectable into singletons.

It should be safe to create a factory function (or constructor function) and know that it will only be called once.

Are there times when we wouldn't want singletons? I can't think of any off the top of my head, and it should be simple enough to get the desired behavior by having a singleton factory that creates instances.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.