Skip to content

JavaScript dependency container and contexte propagation

License

Notifications You must be signed in to change notification settings

squall-io/context

Repository files navigation

@squall.io/context

codecov

Welcome to @squall.io/context library! This library was created to help developers quickly and easily propagate context and handle synchronous and asynchronous operations in their applications.

It provides a set of tools to help manage application state and the associated context information. With this library, developers can easily create and manage context objects that are associated with requests, responses, transactions, and keep them consistently across the application.

Additionally, the library provides asynchronous capabilities to help make asynchronous operations easier to manage. With @squall.io/context, developers can manage their application context and asynchronous operations with ease.

Features:

  • Dependency container
  • Dependency Injection
  • Inheritable DI container (even multiple inheritance)
  • Context propagation
  • Asynchronous context propagation
  • Context-aware promise implementation
  • Async/Await API context propagation compatibility
  • Conditional beans
  • Bean and context lifecycle & hooks
  • Beans pre- and post-processors
  • Inversion of Control (considered as a separate library responsibility)

Context

import {Context} from "@squall.io/context";

const context = new Context() // Create a context 
    .provide('host', () => 'localhost') // Register a bean factory
    .provide('host', 'db', () => 'somewhere.cloud.google.com'); // Register a bean factory

// Inject the bean (the value is cached for later calls).
context.inject('host'); // "localhost" (default qualifier)
context.inject('host', 'db'); // "somewhere.cloud.google.com" ("db" qualifier)

Token can be a symbol. Refer to the JS documentation and TypeScript hints to see supported usage.

// Context can inherit from one or more parent contexts.
new Context(appContext, requestContext, transactionContext);

Please, refer to the JS doc. for more detail on the expected behaviours and the other APIs available.

Promise

import {Context, Promise as ContextPromise} from "@squall.io/context";

const firstContext = new Context();
ContextPromise.resolve(1, firstContext)
    .then((value, context) => {
        // 1 === value
        // firstContext === context
    });

const secondContext = new Context();
ContextPromise.reject(-1, secondContext)
    .catch((reason, context) => {
        // -1 === value
        // secondContext === context
    });

const thridContext = new Context();
ContextPromise.reject(-2, thridContext)
    .finally(context => {
        // thridContext === context
    });

The context propagated through the async chain always follow the most recency precedence.

const context = new Context();
ContextPromise.resolve(ContextPromise.resolve(1, context), new Context())
  .then((value, ctx) => {
    // 1 === value
    // context === ctx
  });

Please, refer to the JS doc. for more detail on the expected behaviours and the other APIs available.

Context Propagation

The sync. API:

import {Context, Promise as ContextPromise} from "@squall.io/context";

let value: number = context.invoke(doSomethingWithinContext);

function doSomethingWithinContext(ctx: Context): number {
    // Can access `Context.invoked` once to get the context, in the same event loop the invoke method was called into
    Context.invoked === ctx;
    
    // removed for brievity
}

Oh, you instead want to make a native promise into a context-aware one?

import {Context, Promise as ContextPromise} from "@squall.io/context";

ContextPromise.from((async () => 1)(), new Context());

The async. API (compatibility with async/await):

import {Context, Promise as ContextPromise} from "@squall.io/context";

try {
    const [value, context] = await contextAwarePromise.context;
} catch (error) {
    const [reason, ctx] = error as any;
}

Contribution

git clone https://github.com/squall-io/context.git
cd context
# Install dependencies
yarn install
# yarn test   nodemon
yarn test:dev

Contributors

Contribution Guidelines

We follow best practices for Open-Source Software contributions, including:

  • Be respectful of peers inputs
  • If you say something, add value
  • Lint, test, be consistent before submitting a pull request (PR)
  • Document your code, even with commits and PR description for the beginners