npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mupli-core

v1.0.4

Published

Mupli is a modular framework designed to enhance code reusability across different projects. It enforces a structure that promotes the creation of reusable components, enabling developers to maintain consistency and efficiency in their codebase. This docu

Downloads

9

Readme

Mupli Framework Documentation

Mupli is a modular framework designed to enhance code reusability across different projects. It enforces a structure that promotes the creation of reusable components, enabling developers to maintain consistency and efficiency in their codebase. This documentation will guide you through the core concepts, usage, and advanced features of Mupli.

Why Mupli?

Over a decade-long career, repetitive tasks like user registration and email management often lead to burnout. The Mupli framework addresses this by providing a way to modularize and reuse code across projects. This approach minimizes redundancy and maximizes the reuse of well-tested components.

Key Features

  • Modular Architecture: Break down applications into reusable modules.
  • Easy Configuration: Use JSON configurations to manage modules across different projects.
  • Monolith and Microservices Support: Start with a monolith and scale to microservices as needed.
  • Lifecycle Management: Clearly defined steps for initialization and invocation.

One node server but two websites

Configuration file: /root/config/apps.json

{
    "myProject1": {
        "host": ["app1.localhost"],
        "modules": ["custom-module", "users", "page", "my-layout", "mail"]
    },
    "app2": {
        "host": ["app2.localhost"],
        "modules": [
            "users",
            "page",
            "security",
            "cors",
            "mail",
            "my-layout",
            "cron"
        ],
        "tags": ["dev", "some-other"]
    }
}

Getting Started

Installation

npm install mupli-core

Note: you need to create minimal folder structure. Please check https://github.com/Mupli/mupli-examples/tree/main/example-api

  • /config/apps.json
  • /app/app.js
  • /app/myProject1/api/test.js

That is it!! Now you just need to run it.

Running the Project

To start a Mupli project, run:

node app/app.js

You can also run with specific tags:

node app/app.js tags=dev,sit,some-other

This will only run projects with the specified tags.

Project Structure

Directories

 /root
    /app
        - app.js
        /[projectName]
            /api
            - users.js  - user controller
            /page
            /cron       - cron job definitions (mupli-cron module)
        /[modularProject]
            /user
                /api
                /cron    - same as /cron
                /page    - directory with html templates (mupli-page or mupli-handlebar)
            /mail
                /mailer  - mailer (mupli-mail)
                /cron    - same as /cron
            /products
                /static  - some example
                /events  - event handlers (mupli-events module)
    /config
        - apps.json

Minimal dirctory structure

/root/app/app.js
/root/app/myProject/api/users.js
/root/config/apps.json

Simplified Api example

/root/app/myProject/api/users.js

import { executeOn, isAuthenticated, isMethod } from "mupli-lib-middlewares";


// Exported method (api/[fileName]/search)
export async function search({req, res, userService}) {
    const name = req.param("userName");
    const users = await userService.findAllByName(name);
    return ctx.res.json(users);
}

// Exported root method (takes file name)
export const init = [
    isAuthenticated(),
    executeOn(isMethod("post", "put"), _createOrUpdateUser),
    executeOn(isMethod("delete"), _deleteUser),
    (ctx) => ctx.res.status("405"),
];

async function _createOrUpdateUser({req, userService}) {
    const user = await ctx.req.json();
    // Do stuff
    await userService.save(user);
    return { status: "OK" };
}


  • url: GET localhost:3000/api/users/search
  • url: POST localhost:3000/api/users

Modules development

Initialization Steps

  1. Process Inheritance Modules: Handles module inheritance.
  2. Init: Initialize the application with appName and bootConfig.
  3. Services: Initialize services with bootConfig and ctx.
  4. Module Extensions: Apply module extensions using appName.
  5. Routes: Set up routes using appConfig and serviceCtx.

Invocation Steps

  1. Dispatch: (TODO)
  2. Context: Set up request context.
  3. Middlewares: Apply global middlewares.
  4. Action: Execute route action.
  5. OnError: Handle errors.

WebSocket Invocation Steps

  1. WS Context: Set up WebSocket context.
  2. WS Middlewares: Apply WebSocket middlewares.
  3. Action: Execute WebSocket action.
  4. OnError: Handle WebSocket errors.

App Configuration

Define your application configuration in config/apps.json:

{
    "test": {
        "hosts": ["localhost", "www.example.com"],
        "tags": ["dev", "prod"],
        "modules": ["page", "store", "api", "services"],
        "arch": "modular"
    }
}

Module Extensions

Modules can extend the functionality of other modules:

moduleExtensions(appName, ctx) {
    const me = this;
    return {
        securityExt: async function (obj) {
            // handle data from other modules
        },
        otherNameExt: async function (obj) {
            // handle ..
        },
    };
}

Creating a Minimal Module

export const myModule = {
    moduleName: "myModuleName",
    routes: (appName, serviceCtx) => {
        return {
            "/page": (ctx) => {
                return "OK";
            },
        };
    },
};

Add the module to your app configuration:

{
    "myapp": {
        "host": ["localhost"],
        "modules": ["myModuleName"]
    },
    "myapp-still-in-development": {
        "host": ["dev.localhost"],
        "arch": "modular",
        "tags": ["dev", "someother"],
        "modules": ["users", "page"]
    }
}

Example App Initialization

new Mupli() //
    .module(myModule)
    .listen(3000);

Run the app:

node app/app.js

Available Modules

  • page: HTML page renderer module
  • api: REST module
  • mail: Mail sender module
  • newsletter
  • user
  • register
  • product
  • cron
  • aws
  • files

Advanced Module Example

User Module

// file usersModule.js
export const usersModule = {
    moduleName: "usersModule",

    services(appName, ctx) {
        return {
            userServices: new UserServices(ctx.dbConnection);
        }
    }
};

Custom Module

//file : myModule.js
export const myModule = {
    moduleName: "myModuleName",

    init(appName) {
        // Initialization logic
    },

    services(appName, ctx) {
        return {
            myService: new MyService(dbConnection, ctx.userServices),
            myEmailService: //...
        }
    },

    middlewares: (appName) => [
        globalMiddleWare,
        (ctx) => {
            console.log("all request log");
        },
        isMethod("post", "patch"),
        (ctx) => {
            if (ctx.req.is("POST")) {
                return ctx.res.status(403);
            }
        }
    ],

    routes: (appName, serviceCtx) => {
        return {
            "/page": [
                localMiddleware,
                (ctx) => {
                    console.log("Invoked middlewares");
                },
                isMethod("get"),
                isOwner("dataCollection", "_id"),
                hasRoles("PRODUCT_CREATOR", "ADMIN"),
                validateGroupAccess(),
                isAuthenticated(),
                async (ctx) => {
                    const myData = await ctx.req.json();
                    const savedMyDate = await myService.save(myData);

                    await ctx.userService.saveRelation(ctx.auth.id, myData.id);
                    return ctx.res.ok();
                }
            ]
        };
    },
};

Module Inheritance

Mupli allows modules to inherit functionality from other modules:

Example

import path from "path";
import { fileURLToPath } from "url";

const currentFileDirectory = path.dirname(fileURLToPath(import.meta.url));

class MyAppModule {
    moduleName = "myapp";
    appPath = currentFileDirectory + "/src";
    modules = ["page", "api"];
}

Define your module structure in config/apps.json:

{
    "myCurrentApp": {
        "hosts": ["localhost"],
        "modules": ["myapp", "other"]
    }
}

Conclusion

Mupli is a powerful framework that facilitates code reusability and modularization, making it easier to manage and maintain projects. By following the structure and guidelines provided, developers can create scalable and maintainable applications efficiently.