UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

83 lines (82 loc) 2.95 kB
import { isAsync } from "../../util/async.js"; import { getMessage } from "../../util/error.js"; // Constants. const NOTICE_EVENT = "notice"; /** MessageEvent */ class NoticeEvent extends CustomEvent { } /** * Notify the user with a message by dispatching a notice event. * - This is how e.g. `<Button>` and `<FormNotify>` components send notices to the `<Notices>` list of global notices. */ export function notify(message, status, el = window) { el.dispatchEvent(new NoticeEvent(NOTICE_EVENT, { detail: { message, status }, bubbles: true, })); } /** Notify the user with a success message by dispatching a notice event. */ export function notifySuccess(message, el) { notify(message, "success", el); } /** Notify the user with a success message by dispatching a notice event. */ export function notifyError(message, el) { notify(message, "error", el); } /** Look at a thrown value, extract a viable message from it, and dispatch a notice event.. */ export function notifyThrown(thrown, el) { const message = getMessage(thrown); if (message) { notifyError(message, el); } else { notifyError("Unknown error", el); console.error(thrown); } } /** Subscribe to notice events on the window and call a callback when they happen. */ export function subscribeNotices(callback, el = window) { const listener = (e) => { e.stopPropagation(); // Prevent bubbling to a higher notice subscriber. if (e instanceof NoticeEvent) callback(e.detail.message, e.detail.status); }; el.addEventListener(NOTICE_EVENT, listener); return () => el.removeEventListener(NOTICE_EVENT, listener); } /** Callback that publishes notices to the window if it returns or throws "string" */ export function callNotified(callback, ...args) { return callNotifiedElement(window, callback, ...args); } /** Await a value that publishes "success" or "error" notices to the window if it returns */ export function awaitNotified(pending) { return awaitNotifiedElement(window, pending); } /** Callback that publishes notices to an element (defaults to the window) if it returns or throws "string" */ export function callNotifiedElement(el, callback, ...args) { try { const result = callback(...args); if (isAsync(result)) return awaitNotifiedElement(el, result); if (result) notifySuccess(result, el); return true; } catch (thrown) { notifyThrown(thrown, el); return false; } } /** Await a value that publishes "success" or "error" notices to an element (defaults to the window) if it returns */ export async function awaitNotifiedElement(el, pending) { try { const result = await pending; if (result) notifySuccess(result, el); return true; } catch (thrown) { notifyThrown(thrown, el); return false; } }