Skip to content

Latest commit

 

History

History
141 lines (105 loc) · 3.08 KB

README.md

File metadata and controls

141 lines (105 loc) · 3.08 KB

nctx

IoC (Inversion of Control)

NodeJS Contextual Dependency Injection using native async_hooks

see https://nodejs.org/api/async_hooks.html

installation

yarn add nctx

or

npm i nctx

usage example with express

ctx/app.js

const nctx = require("nctx")
module.exports = nctx.create(Symbol("app"))

ctx/req.js

const nctx = require("nctx")

const reqCtx = nctx.create(Symbol("req"))

reqCtx.createAppMiddleware = () => {
  return (req, res, next) => {
    reqCtx.provide(()=>{
      reqCtx.share(req)
      res.on("finish", () => {
        reqCtx.endShare(req)
      })
      reqCtx.set("req", req)
      next()
    })
  }
}
reqCtx.createRouterMiddleware = () => {
  return function (req, _res, next) {
    reqCtx.share(req)
    if (next) {
      next()
    }
  }
}

module.exports = reqCtx

app.js

const express = require("express")
const reqCtx = require("~/ctx/req")

const app = express()

app.use(reqCtx.createAppMiddleware())

// middlewares context
app.use(async (req, _res, next) => {
  const reqLogger = logger.child({ path: req.path })
  reqCtx.set("logger", reqLogger)
  next()
})

const router = express.Router()
router.use(reqCtx.createRouterMiddleware())

app.use(router)

// now you can get contextual logger from anywhere you call reqCtx under async tree
router.get("/", async ()=>{
  const reqLogger = reqCtx.get("logger")
  // the reqLogger is specific to the query
})

fork context

const nctx = require("nctx")

const funcCtx1 = nctx.create()
const func = async () => {
  const foo = funcCtx1.require("foo")
  return `foo=${foo}`
}

const main = async () => {
  funcCtx1.provide(()=>{

    funcCtx1.set("foo", "bar")
  
    const result = await Promise.all([
      
      nctx.fork([funcCtx1], () => {
        funcCtx1.set("foo", "jo")
        // here func is executed under the forked context 1
        return func()
      }),
  
      nctx.fork([funcCtx1], () => {
        funcCtx1.set("foo", "devthejo")
        // here func is executed under the forked context 2
        return func()
      }),
  
      // here func is executed under original context
      func(),
  
    ])

  })


  console.log(result)
}

main()

related libs

Contributing:

We welcome contributions! If you encounter a bug or have a feature suggestion, please open an issue. To contribute code, simply fork the repository and submit a pull request.

This repository is mirrored on both GitHub and Codeberg. Contributions can be made on either platform, as the repositories are synchronized bidirectionally.

For more information: