UNPKG

@plugjs/plug

Version:
159 lines (157 loc) 6.29 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // pipe.ts var pipe_exports = {}; __export(pipe_exports, { Context: () => Context, ContextPromises: () => ContextPromises, PipeImpl: () => PipeImpl, install: () => install }); module.exports = __toCommonJS(pipe_exports); var import_node_path = require("node:path"); var import_asserts = require("./asserts.cjs"); var import_logging = require("./logging.cjs"); var import_paths = require("./paths.cjs"); var Context = class { constructor(buildFile, taskName) { this.buildFile = buildFile; this.taskName = taskName; this.buildDir = (0, import_paths.getAbsoluteParent)(buildFile); this.log = (0, import_logging.getLogger)(taskName); } /** The directory of the file where the task was defined (convenience). */ buildDir; /** The {@link Logger} associated with this instance. */ log; /** * Resolve a (set of) path(s) in this {@link Context}. * * If the path (or first component thereof) starts with `@...`, then the * resolved path will be relative to the directory containing the build file * where the current task was defined, otherwise it will be relative to the * current working directory. */ resolve(path, ...paths) { if (path && path.startsWith("@")) { const components = path.substring(1).split(import_node_path.sep).filter((s) => !!s); return (0, import_paths.resolveAbsolutePath)(this.buildDir, ...components, ...paths); } if (!path) return (0, import_paths.getCurrentWorkingDirectory)(); return (0, import_paths.resolveAbsolutePath)((0, import_paths.getCurrentWorkingDirectory)(), path, ...paths); } }; var contextPromises = /* @__PURE__ */ new WeakMap(); var ContextPromises = class _ContextPromises { /* Private constructor */ constructor(context) { this.context = context; } _cold = /* @__PURE__ */ new Set(); _hot = /* @__PURE__ */ new Set(); /** Track a {@link Promise} _hot_ (failure will fail the task) */ hot(promise) { this._cold.delete(promise); this._hot.add(promise); } /** Track a {@link Promise} _cold_ (failure will be ignored) */ cold(promise) { this._hot.delete(promise); this._cold.add(promise); } /** * Await all tracked {@link Promise}s, triggering a build failure if any of * the _hot_ ones is rejected. */ static async wait(context) { const instance = contextPromises.get(context); if (!instance) return; await Promise.allSettled([...instance._cold]); await (0, import_asserts.assertPromises)([...instance._hot]); } /** Get a {@link ContextPromises} instance for the given {@link Context} */ static get(context) { let promises = contextPromises.get(context); if (!promises) { promises = new _ContextPromises(context); contextPromises.set(context, promises); } return promises; } }; var PipeImpl = class _PipeImpl { constructor(_context, _promise) { this._context = _context; this._promise = _promise; ContextPromises.get(_context).hot(_promise); } [Symbol.toStringTag] = "Pipe"; /* ------------------------------------------------------------------------ * * Promise implementation * * ------------------------------------------------------------------------ * * From a _types_ point of view, the `Pipe` implements a `Promise<Files>` * * (because only when plugging the correct `Plug` the correct value are * * returned). * * * * Whether to return (as a type) another `Pipe` or a `Promise<undefined>` * * is determined by the type of the `plug` parameter below. * * * * That said, in practice, a `Pipe` implements `Promise<Files | undefined>` * * because the result of the plug is _eventually_ computed asynchronously * * while `plug` returns immediately. * * * So, all those "as whatever" below are kind-of-legit... * * ------------------------------------------------------------------------ */ then(onfulfilled, onrejected) { ContextPromises.get(this._context).cold(this._promise); return this._promise.then(onfulfilled, onrejected); } catch(onrejected) { ContextPromises.get(this._context).cold(this._promise); return this._promise.catch(onrejected); } finally(onfinally) { ContextPromises.get(this._context).cold(this._promise); return this._promise.finally(onfinally); } plug(arg) { const plug = typeof arg === "function" ? { pipe: arg } : arg; ContextPromises.get(this._context).cold(this._promise); return new _PipeImpl(this._context, this._promise.then(async (result) => { (0, import_asserts.assert)(result, "Unable to extend pipe"); const result2 = await plug.pipe(result, this._context); return result2 || void 0; })); } }; function install(name, ctor) { function plug(...args) { return this.plug(new ctor(...args)); } Object.defineProperty(plug, "name", { value: name }); void Object.defineProperty(PipeImpl.prototype, name, { value: plug }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Context, ContextPromises, PipeImpl, install }); //# sourceMappingURL=pipe.cjs.map