UNPKG

honkit

Version:

HonKit is building beautiful books using Markdown.

211 lines (210 loc) 6.16 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.forEach = forEach; exports.reduce = reduce; exports.map = map; exports.serie = serie; exports.some = some; exports.wrap = wrap; const immutable_1 = __importDefault(require("immutable")); const HONKIT = Symbol("honkitPromise"); function extendPromise(p) { const ep = p; if (ep[HONKIT]) { return ep; } ep[HONKIT] = true; const origThen = p.then.bind(p); const origCatch = p.catch.bind(p); ep.then = function (onFulfilled, onRejected) { return extendPromise(origThen(onFulfilled, onRejected)); }; ep.catch = function (onRejected) { return extendPromise(origCatch(onRejected)); }; ep.thenResolve = function (value) { return extendPromise(this.then(() => value)); }; ep.spread = function (fn) { return extendPromise(this.then((arr) => { if (Array.isArray(arr)) { return fn(...arr); } return fn(arr); })); }; ep.fail = function (onRejected) { return extendPromise(this.catch(onRejected)); }; ep.tap = function (onFulfilled) { return extendPromise(this.then((value) => Promise.resolve(onFulfilled(value)).then(() => value))); }; ep.progress = function (_onProgress) { return ep; }; ep.nodeify = function (callback) { if (!callback) { return ep; } this.then((result) => { callback(null, result); }, (err) => { callback(err); }); return undefined; }; ep.fin = function (onFinally) { return extendPromise(this.finally(() => { return onFinally(); })); }; return ep; } function defer() { const progressHandlers = new Set(); let resolve; let reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); const ext = extendPromise(promise); ext.progress = function (_onProgress) { progressHandlers.add(_onProgress); return ext; }; return { promise: ext, resolve, reject, notify(data) { progressHandlers.forEach((f) => f(data)); }, makeNodeResolver() { return (err, ...args) => { if (err) { reject(err); } else { resolve(args.length <= 1 ? args[0] : args); } }; } }; } function nfcall(fn, ...args) { const inner = new Promise((resolve, reject) => { const callback = (err, ...cbArgs) => { if (err) { reject(err); } else { resolve(cbArgs.length <= 1 ? cbArgs[0] : cbArgs); } }; fn(...args, callback); }); const ext = extendPromise(inner); ext.get = (index) => extendPromise(inner.then((val) => { if (Array.isArray(val)) { return val[index]; } return index === 0 ? val : undefined; })); return ext; } function nfbind(fn) { return function (...args) { return nfcall(fn.bind(this), ...args); }; } function reduce(arr, iter, base) { const list = immutable_1.default.Iterable.isIterable(arr) ? arr : immutable_1.default.List(arr); return list.reduce((prev, elem, key) => { return prev.then((val) => iter(val, elem, key)); }, extendPromise(Promise.resolve(base))); } function forEach(arr, iter) { return reduce(arr, (_val, el, key) => { return iter(el, key); }, undefined); } function serie(arr, iter) { return reduce(arr, (before, item, key) => { return extendPromise(Promise.resolve(iter(item, key))).then((r) => { before.push(r); return before; }); }, []); } function some(arr, iter) { const list = immutable_1.default.List.isList(arr) ? arr : immutable_1.default.List(arr); return list.reduce((prev, elem, i) => { return prev.then((val) => { if (val) { return val; } return iter(elem, i); }); }, extendPromise(Promise.resolve(undefined))); } function mapAsList(arr, iter) { return reduce(arr, (prev, entry, i) => { return extendPromise(Promise.resolve(iter(entry, i))).then((out) => { prev.push(out); return prev; }); }, []); } function map(arr, iter) { if (immutable_1.default.Map.isMap(arr)) { let type = "Map"; if (immutable_1.default.OrderedMap.isOrderedMap(arr)) { type = "OrderedMap"; } // eslint-disable-next-line @typescript-eslint/no-explicit-any return mapAsList(arr, ((value, key) => { return extendPromise(Promise.resolve(iter(value, key))).then((result) => { return [key, result]; }); })).then((result) => { return immutable_1.default[type](result); }); } else { return mapAsList(arr, iter).then((result) => { return immutable_1.default.List(result); }); } } function wrap(func) { return function (...args) { return extendPromise(Promise.resolve()).then(() => { return func.apply(this, args); }); }; } function isPromiseAlike(x) { return x != null && typeof x.then === "function"; } /* eslint-disable @typescript-eslint/no-explicit-any -- Q-compatible surface is intentionally loose for chaining */ const HonkitPromiseRoot = Object.assign(function HonkitPromise(value) { return extendPromise(Promise.resolve(value)); }, { defer, nfcall, nfbind, reject: (reason) => extendPromise(Promise.reject(reason)), all: (values) => extendPromise(Promise.all(Array.from(values))), reduce, forEach, map, serie, some, wrap, isPromiseAlike }); exports.default = HonkitPromiseRoot;