Skip to content

drmats/mem-box

Repository files navigation

mem-box

Shared memory.

npm version GitHub code size GitHub tag npm license

$ npm i mem-box

shared memory pattern

Frontend and backend applications often use some globally-configured objects, like axios instance with custom headers and base url, authenticated cloud services provider instance, express.js instance, database connection object, configured redux store, etc...

One might stick these to window (or global) object, but it's considered an anti-pattern.

Another solution is to pass these objects as parameters to functions that needs to use them, but it's cumbersome and scales poorly.

Using mem-box solves these problems and resembles the usage of hooks in react.


example

  • main.js file of an express.js-based microservice application:

    import express from "express";
    import { share } from "mem-box";
    import configureRoutes from "./routes";
    
    // main express application
    const app = express();
    
    // share it with any other module interested
    share({ app });
    
    // complex configuration - e.g. enable CORS,
    // authentication, redirects, etc.
    // ...
    
    // routes configuration
    configureRoutes();
    
    app.listen(/* ... */);
  • example routes.js file:

    import { useMemory } from "mem-box";
    
    export default configureRoutes () {
    
        // get access to main express application
        const { app } = useMemory();
    
        // add "hello world" route
        app.get("/hello/", (req, res, next) => {
            res.status(200).send({ hello: "world" });
            return next();
        });
    
    }

usage with typescript

In order to provide type-safety (and nice IntelliSense hints) declaration merging typescript feature can be utilized.

  • main.ts file of an express.js-based microservice application:

    import express from "express";
    import { share } from "mem-box";
    import configureAuth from "./auth";
    
    // main express application
    const app = express();
    
    // private key (read from env or keystore in real-world)
    const secretKey = "-----BEGIN PRIVATE KEY-----\nMIIEvqhkiGwgEqh...";
    
    // share with other modules
    share({ app, secretKey });
    
    // authentication config (based on external service provider)
    configureAuth();
    
    // ...
    
    app.listen(/* ... */);
    
    // global declaration merging
    declare global {
    
        // shared memory type augmentation
        interface Mem {
            app: ReturnType<typeof express>;
            secretKey: string;
        }
    
    }
  • example auth.ts file:

    import type { RequestHandler } from "express";
    import { someservice } from "someserviceapis"; // imaginary service
    import { share, useMemory } from "mem-box";
    
    // ...
    export default configureAuth (): void {
    
        // get access to secret (explicit type hint)
        const { secretKey } = useMemory<Mem>();
    
        // obtain JSON Web Token from external provider
        const jwt = new someservice.auth.JWT({
            secretKey, /* scopes: [...], subject: ..., */
        });
    
        // build middleware for usage in other modules
        const authMw: RequestHandler = (req, res, next) => {
            // do something with `jwt` const
            // ...
            return next();
        };
    
        // share it
        share({ authMw });
    
    }
    
    // inform type system of a new member in `Mem` interface
    declare global {
    
        // shared memory type augmentation
        interface Mem {
            authMw: RequestHandler;
        }
    
    }

documentation

API Reference


namespace

shared memory

memory
{ useMemory: [Function: useMemory],
  share: [Function: share] }

notes

This library is suitable to use in server and browser environments and it is being used as such. Go ahead and file an issue if you found a bug 🐞.


support

You can support this project via stellar network:


license

mem-box is released under the Apache License, Version 2.0. See the LICENSE for more details.