@pulzar/core
Version:
Next-generation Node.js framework for ultra-fast web applications with zero-reflection DI, GraphQL, WebSockets, events, and edge runtime support
146 lines • 3.57 kB
JavaScript
import { AsyncLocalStorage } from "async_hooks";
export class RequestContextManager {
storage = new AsyncLocalStorage();
/**
* Create a new request context
*/
create(requestId) {
return {
requestId,
startTime: Date.now(),
metadata: {},
};
}
/**
* Run callback within request context
*/
run(context, callback) {
return this.storage.run(context, callback);
}
/**
* Get current request context
*/
get() {
return this.storage.getStore();
}
/**
* Set user in current context
*/
setUser(user) {
const context = this.get();
if (context) {
context.user = user;
}
}
/**
* Get user from current context
*/
getUser() {
const context = this.get();
return context?.user;
}
/**
* Set span in current context
*/
setSpan(span) {
const context = this.get();
if (context) {
context.span = span;
}
}
/**
* Set metadata in current context
*/
setMetadata(key, value) {
const context = this.get();
if (context) {
context.metadata[key] = value;
}
}
/**
* Get metadata from current context
*/
getMetadata(key) {
const context = this.get();
return context?.metadata[key];
}
/**
* Get request ID from current context
*/
getRequestId() {
const context = this.get();
return context?.requestId;
}
getDuration() {
const context = this.get();
if (!context)
return 0;
return Date.now() - context.startTime;
}
}
export const requestContext = new RequestContextManager();
/**
* Fastify middleware to create request context
*/
export function requestContextMiddleware(request, reply) {
const requestId = request.headers["x-request-id"] || generateRequestId();
const context = requestContext.create(requestId);
// Add request ID to response headers
reply.header("x-request-id", requestId);
// Attach context to request for debugging
request.context = context;
// Run in context - return a promise that resolves when context is set
return new Promise((resolve) => {
requestContext.run(context, () => {
resolve();
});
});
}
/**
* Register request context plugin for Fastify
*/
export function registerRequestContextPlugin(fastify) {
fastify.addHook("preHandler", async (request, reply) => {
await requestContextMiddleware(request, reply);
});
}
/**
* Get current request context
*/
export function getCurrentContext() {
return requestContext.get();
}
/**
* Get current user from context
*/
export function getCurrentUser() {
return requestContext.getUser();
}
/**
* Get current request ID
*/
export function getCurrentRequestId() {
return requestContext.getRequestId();
}
/**
* Get current span from context
*/
export function getCurrentSpan() {
const context = requestContext.get();
return context?.span;
}
/**
* Generate a unique request ID
*/
function generateRequestId() {
return `req_${Date.now()}_${Math.random().toString(36).substring(2)}`;
}
// Utility functions
export function getCurrentLocale() {
const context = requestContext.get();
return context?.metadata["locale"];
}
export function getRequestDuration() {
return requestContext.getDuration();
}
//# sourceMappingURL=requestContext.js.map