
Security News
/Research
Fake Corepack Site Distributes Infostealer and Proxyware to Developers
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.
Browser-compatible polyfill for Node.js's diagnostics_channel API. This package provides the core diagnostics channel functionality that works in browser environments, including integration with AsyncLocalStorage via als-browser.
diagnostics_channel API compatibilitybindStorenpm install dc-browser
# or
pnpm add dc-browser
# or
yarn add dc-browser
For AsyncLocalStorage integration:
npm install als-browser
import { channel } from 'dc-browser';
const requestChannel = channel('http.request');
// Subscribe to messages
requestChannel.subscribe((message, name) => {
console.log(`Received on ${name}:`, message);
});
// Publish a message
requestChannel.publish({ url: '/api/data', method: 'GET' });
TracingChannel provides structured tracing with start, end, asyncStart, asyncEnd, and error events:
import { tracingChannel } from 'dc-browser';
const httpChannel = tracingChannel('http.request');
// Subscribe to events
httpChannel.subscribe({
start: (context) => {
console.log('Request started:', context);
},
end: (context) => {
console.log('Request ended:', context);
},
error: (context) => {
console.error('Request error:', context.error);
}
});
// Trace a synchronous operation
const result = httpChannel.traceSync(() => {
// Your sync code here
return fetchData();
}, { requestId: 'req-123' });
// Trace a promise-based operation
const data = await httpChannel.tracePromise(async () => {
// Your async code here
return await fetch('/api/data');
}, { requestId: 'req-456' });
Channels can be bound to AsyncLocalStorage instances to transform events into stored context:
import { channel } from 'dc-browser';
import { AsyncLocalStorage } from 'als-browser';
const requestChannel = channel('http.request');
const requestContext = new AsyncLocalStorage();
// Bind the store to the channel
requestChannel.bindStore(requestContext);
// Now runStores will propagate context to the store
requestChannel.runStores({ requestId: 'req-789' }, () => {
console.log(requestContext.getStore()); // { requestId: 'req-789' }
// Context is available in the callback
doWork();
});
function doWork() {
const context = requestContext.getStore();
console.log('Current request:', context.requestId);
}
You can provide a transform function when binding a store to extract/transform the message:
import { channel } from 'dc-browser';
import { AsyncLocalStorage } from 'als-browser';
const requestChannel = channel('http.request');
const userIdStore = new AsyncLocalStorage<string>();
// Extract just the userId from messages
requestChannel.bindStore(
userIdStore,
(message) => message.userId
);
requestChannel.runStores({ userId: 'user-123', url: '/api/data' }, () => {
console.log(userIdStore.getStore()); // 'user-123'
});
You can bind multiple AsyncLocalStorage instances to a single channel:
const requestChannel = channel('http.request');
const requestIdStore = new AsyncLocalStorage<string>();
const userIdStore = new AsyncLocalStorage<string>();
requestChannel.bindStore(requestIdStore, (msg) => msg.requestId);
requestChannel.bindStore(userIdStore, (msg) => msg.userId);
requestChannel.runStores({ requestId: 'req-123', userId: 'user-456' }, () => {
console.log(requestIdStore.getStore()); // 'req-123'
console.log(userIdStore.getStore()); // 'user-456'
});
const store = new AsyncLocalStorage();
const ch = channel('test');
ch.bindStore(store);
// ... later
ch.unbindStore(store); // Returns true if successfully unbound
channel(name: string | symbol): ChannelGet or create a channel by name.
hasSubscribers(name: string | symbol): booleanCheck if a channel has any subscribers.
subscribe(name: string | symbol, callback: Function): voidSubscribe to a channel.
unsubscribe(name: string | symbol, callback: Function): booleanUnsubscribe from a channel.
tracingChannel(name: string): TracingChannelCreate a TracingChannel for structured tracing.
subscribe(callback: (message: any, name: string) => void): voidAdd a subscriber to this channel.
unsubscribe(callback: Function): booleanRemove a subscriber from this channel.
publish(message: any): voidPublish a message to all subscribers.
bindStore(store: AsyncLocalStorage, transform?: (message: any) => any): voidBind an AsyncLocalStorage instance to this channel. When runStores is called, the message (optionally transformed) will be set as the store value.
unbindStore(store: AsyncLocalStorage): booleanUnbind an AsyncLocalStorage instance from this channel.
runStores(context: any, fn: () => any): anyPublish the context and run the function within all bound AsyncLocalStorage contexts.
A TracingChannel manages 5 individual channels:
start: Published before operation beginsend: Published after operation completesasyncStart: Published when async operation starts resolvingasyncEnd: Published when async operation finishes resolvingerror: Published when operation throws/rejectssubscribe(handlers: ChannelHandlers): voidSubscribe to tracing events.
unsubscribe(handlers: ChannelHandlers): booleanUnsubscribe from tracing events.
traceSync<T>(fn: Function, context?: any, thisArg?: any, ...args: any[]): TTrace a synchronous operation.
tracePromise<T>(fn: Function, context?: any, thisArg?: any, ...args: any[]): Promise<T>Trace a promise-based operation.
traceCallback<T>(fn: Function, position?: number, context?: any, thisArg?: any, ...args: any[]): anyTrace a callback-based operation.
When using bindStore with als-browser, the context will be preserved through:
runStores callbackAsyncLocalStorage.bind() or snapshot() for other async operationsNote: Native Promise await boundaries will lose context unless you:
AsyncLocalStorage.bind()als-browserimport { tracingChannel } from 'dc-browser';
import { AsyncLocalStorage } from 'als-browser';
const httpChannel = tracingChannel('http.request');
const requestStore = new AsyncLocalStorage();
// Bind store to start channel for context propagation
httpChannel.start.bindStore(requestStore);
// Subscribe to events
httpChannel.subscribe({
start: (ctx) => console.log('Started:', ctx.requestId),
end: (ctx) => console.log('Ended:', ctx.requestId, 'result:', ctx.result),
error: (ctx) => console.error('Error:', ctx.requestId, ctx.error)
});
// Make a traced request
const response = httpChannel.traceSync(() => {
// Context is available throughout the operation
console.log('Current request:', requestStore.getStore()?.requestId);
return fetch('/api/data');
}, { requestId: 'req-123', url: '/api/data' });
# Run tests
pnpm test
# Build
pnpm build
MIT
This implementation is based on Node.js's diagnostics_channel API from Node.js core.
FAQs
Browser polyfill for Node.js diagnostics_channel
The npm package dc-browser receives a total of 450,904 weekly downloads. As such, dc-browser popularity was classified as popular.
We found that dc-browser demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.

Research
/Security News
A large-scale campaign abused GitHub Actions in compromised repositories to exploit CVE-2026-41940 in cPanel and WHM and steal server credentials.

Security News
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.