Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
blissful-hooks
Advanced tools
Deep extensibility for all!
A spinoff from ye olde BlissfulJS project. A precursor of this code powers the plugin system of PrismJS.
First, create a new Hooks
instance, and expose it to third-party code.
E.g. if your library is a class, it can be a static property:
// In a browser? Just import src/index.js instead
import Hooks from "blissful-hooks";
class MyAwesomeClass {
static hooks = new Hooks();
}
If your library is a set of modules, it can just be an export:
import Hooks from "blissful-hooks";
export const hooks = new Hooks();
Or, if you don’t care about potential name clashes across other libraries using this module, you can just use/export the hooks
singleton:
import { hooks } from "blissful-hooks";
export { hooks };
Now, at the places in your code where you want to allow extensions, call hooks.run(hookName, env)
.
hooks.run("hook-name", this);
Plugin code will now be executed with the same context as your code.
Instead of the current context, you can pass variables that plugins can read and manipulate!
Ideally, it would be exposing local variables, and you'd be reading and writing directly from it.
Then, you pass can still pass the current context to the plugin as a special this
or context
property (if both are present, this
wins).
For example, here’s how a syntax highlighter might use it:
let env = {
callback,
container,
selector: 'code[class*="language-"], [class*="language-"] code',
this: this,
};
hooks.run('before-highlightall', env);
env.elements = env.container.querySelectorAll(env.selector);
hooks.run('before-all-elements-highlight', env);
for (let element of env.elements) {
highlightElement(element, env.callback);
}
hooks.run('after-all-elements-highlight', env);
Plugin authors use hooks.add()
to schedule code to run at a given hook.
For example, suppose we wanted to change the selector above to also accept lang-*
classes.
It would be as simple as:
hooks.add("before-highlightall", function(env) {
env.selector += ', code[class*="lang-"], [class*="lang-"] code';
});
You can also add multiple hooks at one:
hooks.add({
"before-highlightall": function(env) {
env.selector += ', code[class*="lang-"], [class*="lang-"] code';
},
"before-all-elements-highlight": function(env) {
env.elements = Array.from(env.elements).filter(e => !e.classList.contains("no-highlight"));
}
});
Or the same callback to multiple hooks:
hooks.add(["before-highlightall", "some-other-hook"], function(env) {
env.selector += ', code[class*="lang-"], [class*="lang-"] code';
});
Yes, but only with the consent of the library author. Simply returning a value from your hook callback will do nothing (duh). However, the library author can designate that a certain property holds a return value, and if that property is non-empty, they can choose to honor it:
let env = {this: this}
hooks.run("hook-name", env);
if (env.returnValue) {
return env.returnValue;
}
Nothing happens. The code simply never gets executed. Libraries don't need to declare their hooks upfront (by design), so there is no way for Blissful Hooks to know the difference between a hook that hasn't run yet and a hook that never will.
It took 12 years of usage before I released this as a separate package, but precursors of it are used in several libraries:
FAQs
Deep extensibility for all!
We found that blissful-hooks demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 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
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.