Shared memory.
$ npm i mem-box
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
.
-
main.js
file of anexpress.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 anexpress.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; } }
memory
{ useMemory: [Function: useMemory], share: [Function: share] }
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 🐞.
You can support this project via stellar network:
- Payment address: xcmats*keybase.io
- Stellar account ID:
GBYUN4PMACWBJ2CXVX2KID3WQOONPKZX2UL4J6ODMIRFCYOB3Z3C44UZ
mem-box is released under the Apache License, Version 2.0. See the LICENSE for more details.