1.0.0 • Published 4 years ago
@borderlesslabs/context v1.0.0
Context
Tiny, type-safe, JavaScript-native
context
implementation.
Why? Working on utilities across browsers, serverless and node.js require different of implementations, e.g. fetch
vs require('http')
. Go's context
package provides a nice abstraction for my needs. By implementing a JavaScript first variation, we can achieve the same benefits.
Installation
npm install @borderlesslabs/context --save
Usage
Context events and values are unidirectional, child context automatically inherit the parents values.
import { Context } from "@borderlesslabs/context";
const context = new Context();
const childContext = new Context(context);
Values
The context
provides a way to attach and retrieve values.
context.set("test", true);
context.get("test"); //=> `true`
childContext.get("test"); //=> `true`
childContext.set("test", false);
context.get("test"); //=> `true`
childContext.get("test"); //=> `false`
Events
The standard for async notifications in JavaScript is the event emitter. Based on the browser AbortController
, the context
has an event emitter available on signal
.
context.signal.on("abort", () => {});
childContext.signal.on("abort", () => {});
context.abort(); // Triggers `abort` event.
context.signal.emit("test"); // Propagates to `childContext`.
childContext.signal.emit("test"); // Events are unidirectional, `context` is not triggered.
Example
Tracing is a natural example for context
:
// Use a unique symbol for tracing.
const spanKey = Symbol('span');
// Start a new span, and automatically use "parent" span.
export function startSpan(ctx: Context, name: string) {
const newCtx = new Context(ctx);
const span = tracer.startSpan(name, {
childOf: ctx.get(spanKey)
});
newCtx.set(spanKey, span);
return [span, newCtx];
}
// server.js
async function app(req, next) {
const [span, req.ctx] = startSpan(req.ctx, 'request');
try {
return await next();
} finally {
span.finish();
}
}
// middleware.js
async function middleware(req, next) {
const [span, req.ctx] = startSpan(req.ctx, 'middleware');
try {
return await next();
} finally {
span.finish();
}
}
License
MIT
1.0.0
4 years ago