GithubHelp home page GithubHelp logo

shafeen / chaz Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 19.55 MB

A lightweight and gently opinionated framework to use for your applications.

JavaScript 100.00%
javascript nodejs starter-project dependency-injection ioc framework

chaz's Introduction

chaz ๐Ÿ˜ผ

Simple and powerful

Build Status

A lightweight and gently opinionated framework to use for your applications.

Installation and Directory structure

Create an empty project directory, init a package.json file and install the framework:

npm i chaz-js

In your project root directory, create the entrypoint app.js (you can call it whatever you like), and the folders src/ and resources/ (the folder names must be exactly "src" and "resources").

<project>
   |
   +--src/
   |
   +--resources/
   |
   +--app.js

Paste the following into your app.js file, it only serves to kick off an application.

// app.js

const chaz = require('chaz-js');
chaz.initialize();

Getting started and initializing an application

Kicking off the application by running your app.js (or equivalent file in your project root) will trigger the framework to search for an ApplicationRunner class (or TaskScheduler class, but more on those later) to run. You may have multiple ApplicationRunner classes, but most applications will probably stick with just 1.

An ApplicationRunner is a simple subclass that extends the ApplicationRunner class provided by the framework. Let's create a simple one in the src/ folder:

module.exports = {
    name: "Main", service: __, dependencies: ['ApplicationRunner']
};

function __(ApplicationRunner) {
    
    // Application runners should implement 2 methods
    // - order(): return an int to decide run order for multiple ApplicationRunners (if you have more than 1)
    // - run(): contains whatever code you want to run when your application starts
    class Main extends ApplicationRunner {
        order() {return 0;}

        run() {
            console.log(`Starting sample ApplicationRunner class '${this.constructor.name}'`);
        }
    }
    
    return Main;
}

Dependency Injection Container

All files placed in the src/ directory is eligible to be autoscanned for the DI container provided that an object in the following format is exported by each file:

module.exports = {
    // Name you want your module to be known for DI
    name: "ComponentName", 
    
    // Constructor function for your Component, whatever this function
    // returns will registered in the DI registry and will be injected when
    // another component requests this component in its dependency list
    service: serviceConstructorFunction,  
    
    // The DI container will look through its registry and inject these
    // dependencies (with the exact names specified) into the serviceConstructorFunction
    // for this component. They will be injected in the order in this list.
    dependencies: ['dependency1', 'dependency2']
};

To inject require-ed modules, simply type in the command "require(<module_name>)" in the exported dependencies property list (you still need to have them installed using npm install <module_name>). Notice the lack of quotes around the <module_name> in the dependency list, this is on purpose.

Example:

module.exports = {
    name: "MyFancyServiceClass", 
    service: __,  
    dependencies: ['require(mongoose)', 'MyService']
};

function __(mongoose, MyService) {
    // mongoose and MyService will be injected and usable in this scope
    
    class MyFancyServiceClass {
        constructor() {
            // constructor stuff
        }
        foo() {
            // foo stuff
        }
        bar() {
            // bar stuff
        }
    }
    
    return MyFancyServiceClass;
}

Special Dependencies

In addition to registered components, the following dependency formats have special meaning when specified in a component's dependency list:

  • require(<module_name>): inject installed module (core or node_modules)
  • resource(<resources_relative_name>): get and inject resource from resources/ directory
  • env(<ENV_VARIABLE_NAME>): inject environment variable (from process.env)

Special Framework "Runner" classes

ApplicationRunner

ApplicationRunner subclasses must implement a run function that will be kicked off in order by the framework after initialization. This is typically the main entry point to an application. You can think of them like a public static void main() in Java; however you can have more than 1 ApplicationRunner in an application if the need arises.

See example shown above in the Getting started and initializing an application section.

TaskScheduler

TaskScheduler subclasses must implement a run function for the framework to periodically run and a config function that lets the framework know the what schedule the framework should follow.

Example TaskScheduler class:

module.exports = {
    name: "MessageScheduler", service: __,
    dependencies: ['TaskScheduler']
};

function __(TaskScheduler) {

    class MessageScheduler extends TaskScheduler {
        config() {
            return { 
                delay: 1000, 
                runOnceFirst: false, 
                runOnlyOnce: false 
            };
        }
        
        run() {
            console.log(`Running sample TaskScheduler class '${this.constructor.name}'`);
        }

    }
    return MessageScheduler;
}

chaz's People

Contributors

shafeen avatar

Watchers

James Cloos avatar  avatar

chaz's Issues

TaskSchedulers seem to take double the "delay" set when "runOnceFirst" is set to true


delay: 1000, runOnceFirst: false, runOnlyOnce: false

TaskSchedulers seem to take double the delay set when runOnceFirst is set to true.

For example: if the delay is set to 30s with runOnceFirst=true, it is observed to run once, then will not run again next until 2x30s=60s has passed, after which it runs every 30s as expected. The expected behavior is to run again after 30s every time.

Need to do a root cause analysis, add a test for it and fix this issue.

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.