
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
eventify-function
Advanced tools
A package that adds to any given function or method events of starting, ending and erroring
npm i eventify-function
Just call eventifyFunction informing the function you want to eventify
const eventified = eventifyFunction(myFunction);
A new version of the function is returned that does exactly what the former one does, but it also emits event when:
Look that, a string, an Array, a Map, a WeakMap, a Set and a WeakSet are all valid iterables, but if your function return or resolve for one of those types, end will be called instead of iterated. That's because all these types don't need iteration to be evaluated. A Generator, in the other hand, does. Notice that streams are also AsyncIterables, and a stream need iteration to be evaluated. In that case, if you eventify a function that returns a String, it'll not emit end, just iterated when the streams close.
To listen to some of the events, you attach a listener to it as with any other EventEmitter:
eventified.on('init', (uuid: string, a: Number, b: string) => console.log(`(${uuid}): myFunction was called with "${a}" and "${b}"`);
eventified.on('end', (uuid: string, result: boolean, a: Number, b: string) => console.log(`(${uuid}): myFunction returned "${result}" for the call with "${a}" and ${b}"`);
eventified.on('error', (uuid: string, err: Error, a: Number, b: string) => console.log(`(${uuid}): myFunction threw "${err.Message}" for the call with "${a}" and "${b}"`);
eventified.on('iterated', (uuid: string, a: Number, b: string) => console.log(`(${uuid}): Iteration ended for the call with "${a}" and "${b}"`);
eventified.on('yielded', (uuid: string, value: boolean; a: Number, b: string) => console.log(`(${uuid}): Iteration yielded: ${value} for the call with "${a}" and "${b}"`);
Notice that all the events are strongly typed and receives the parameters passed to the function, while end additionally receives the result, and error the threw Error. The event iterated does not receives the result as, for an iterable, there is multiples, but you can access each yielded value by the yielded event. Finally, there is an uuid generated for each call, so, you can identify each call flow.
You can also easily eventify methods decorating them! To take this approach, do as follow:
class MyClass {
@Eventify(MyEventApplier)
test(test: string, index: number): void {
...
}
}
In this example, MyEventApplier must implement EventifyApplier, using the decorated method as signature:
class MyEventApplier implements EventifyApplier<MyClass['test']s> {
applyListeners(eventified: EventifiedFunc<MyClass['test']>) {
eventified.on('end', (uuid: string, result: void, test: string, index: number) => {
console.log(`${uuid}: ("${test}", ${index}) call ended`);
});
}
}
Finally, to initialize the appliers, you must call applyEventify informing instance getter function:
applyEventify(() => new MyEventApplier());
The instance getter function is needed because eventify-function does not have control of the right way to instantiate your applier classes. The idea here is for you to use some dependency injection package for it. If you don't have such complexity and want to avoid using applyEventify, you can inform to the decorator directly an instance of your class:
class MyClass {
@Eventify(new MyEventApplier())
test(test: string, index: number): void {
...
}
}
Using it like this, the applier will be used immediately.
Let's suppose, in your method, you have an intermediate value that is useful in your error event, for some logging purpose. The error event only have access to the error parameters, but not any information limited to the function scope, so, how do you do it?
The first way to achieve this is to aggregate the information you want in the parameters the function received, before the error happens. This way, when the parameters are passed to the error event, it'll have the additional info. But what if you don't want to pollute your parameters?
in this, case, there is some special functions you may call just inside the eventified method that'll help you out:
class MyTest() {
constructor(private logger: Logger) {}
@Eventify(MyErrorHandler)
async myMethod(value: string, index: number) {
const id = await getIndexId(index);
// The callId function will return the call id passed to the events!
this.logger.info(`index id ${id} received for ${callId(this)}`);
// The eventMapSet will put any information you want in a temporary context available while your method is running
eventMapSet('index-id', id);
await doSomethingElse(id, value);
}
}
Then, to access your information from your event, you can do as follow:
class MyErrorHandler implements EventifyApplier<MyTest['myMethod']s> {
constructor(private logger: Logger) {}
applyListeners(eventified: EventifiedFunc<MyTest['myMethod']>) {
eventified.on('error', (uuid: string, error: Error, test: string, index: number) => {
this.logger.error(`${uuid}: an error occurred for index id ${eventMapGet(uuid, 'index-id')}: ${error.message}`);
});
}
}
That's it! But be aware! This information is highly temporary and, if you want to access if in the error, end or iterated event, you need to do it immediately in the event listener, before any promise awaiting or then operation, otherwise the information may already have been dropped.
Licensed under MIT.
0.5.5
FAQs
This project is just a template for creation of new projects
The npm package eventify-function receives a total of 0 weekly downloads. As such, eventify-function popularity was classified as not popular.
We found that eventify-function demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 6 open source maintainers 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
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.