Callforth Promise Utilities
Callforth is a lightweight utility library designed to streamline common asynchronous JavaScript patterns by converting them into Promise-based operations. Currently at version 0.4.0, it offers a small collection of functions to replace traditional callback APIs, enabling developers to leverage `async/await` syntax for cleaner, more readable code. Its primary utilities include `eventOn` for awaiting specific events on any `EventTarget`, `timeout` for promise-based delays, and `polling` for repeatedly checking a predicate until it returns true or a maximum number of tries is reached. The library differentiates itself by focusing on simplifying frequently re-implemented patterns into a tiny, focused package, aiming to provide a 'don't callback, callforth' experience. There isn't a specified strict release cadence, but as a pre-1.0.0 project, updates are likely as needed.
Common errors
-
ReferenceError: require is not defined in ES module scope
cause Attempting to use CommonJS `require()` syntax in a JavaScript file that is treated as an ES module (e.g., due to `"type": "module"` in `package.json` or a `.mjs` extension).fixChange `const { symbol } = require('callforth')` to `import { symbol } from 'callforth'`. -
TypeError: eventTarget.addEventListener is not a function
cause The first argument passed to `eventOn` is not a valid `EventTarget` (e.g., a DOM element, `window`, `document`, or a custom object implementing `addEventListener` and `removeEventListener`).fixEnsure the `target` parameter for `eventOn` is an object that correctly implements the `EventTarget` interface, such as `document.body`, `window`, or a `new EventTarget()` instance.
Warnings
- breaking As a pre-1.0.0 package (current version 0.4.0), `callforth` does not strictly adhere to SemVer. Minor version updates (e.g., 0.x.0 to 0.y.0) may introduce breaking changes without prior deprecation warnings.
- gotcha The `eventOn` utility automatically removes the event listener after the first successful event or error event, ensuring the promise resolves or rejects once. This is by design but can be a 'gotcha' if you expect the listener to persist for multiple events.
Install
-
npm install callforth -
yarn add callforth -
pnpm add callforth
Imports
- eventOn
const eventOn = require('callforth').eventOnimport { eventOn } from 'callforth' - timeout
import timeout from 'callforth'
import { timeout } from 'callforth' - polling
const { polling } = window.callforthimport { polling } from 'callforth'
Quickstart
import { eventOn, timeout } from "callforth";
async function loadAndTrackScript(url: string) {
console.log(`Attempting to load script from: ${url}`);
const script = document.createElement("script");
script.src = url;
script.async = true;
// Append to document to start loading
document.head.appendChild(script);
try {
// Await either 'load' for success or 'error' for failure
const result = await eventOn(script, "load", "error");
if (result.type === "load") {
console.log(`Script loaded successfully from ${url} at ${new Date().toLocaleTimeString()}.`);
await timeout(500); // Simulate a small delay after loading
console.log("Further processing after a short pause.");
} else if (result.type === "error") {
console.error(`Failed to load script from ${url}.`);
}
} catch (err) {
console.error(`An unexpected error occurred during script loading for ${url}:`, err);
} finally {
// Clean up the script element after it's done
if (script.parentNode) {
script.parentNode.removeChild(script);
}
console.log(`Cleanup for ${url} complete.`);
}
}
// Example usage: Try loading a valid and an invalid script
loadAndTrackScript('https://unpkg.com/react@18/umd/react.production.min.js');
// In a real scenario, you'd replace 'nonexistent.js' with a URL that genuinely fails
// loadAndTrackScript('https://example.com/nonexistent.js');