« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/aggregate.js728
-rw-r--r--src/util/cli.js521
2 files changed, 0 insertions, 1249 deletions
diff --git a/src/util/aggregate.js b/src/util/aggregate.js
deleted file mode 100644
index c7648c4c..00000000
--- a/src/util/aggregate.js
+++ /dev/null
@@ -1,728 +0,0 @@
-import {colors} from './cli.js';
-import {empty, typeAppearance} from './sugar.js';
-
-// Utility function for providing useful interfaces to the JS AggregateError
-// class.
-//
-// Generally, this works by returning a set of interfaces which operate on
-// functions: wrap() takes a function and returns a new function which passes
-// its arguments through and appends any resulting error to the internal error
-// list; call() simplifies this process by wrapping the provided function and
-// then calling it immediately. Once the process for which errors should be
-// aggregated is complete, close() constructs and throws an AggregateError
-// object containing all caught errors (or doesn't throw anything if there were
-// no errors).
-export function openAggregate({
-  // Constructor to use, defaulting to the builtin AggregateError class.
-  // Anything passed here should probably extend from that! May be used for
-  // letting callers programatically distinguish between multiple aggregate
-  // errors.
-  //
-  // This should be provided using the aggregateThrows utility function.
-  [openAggregate.errorClassSymbol]: errorClass = AggregateError,
-
-  // Optional human-readable message to describe the aggregate error, if
-  // constructed.
-  message = '',
-
-  // Optional flag to indicate that this layer of the aggregate error isn't
-  // generally useful outside of developer debugging purposes - it will be
-  // skipped by default when using showAggregate, showing contained errors
-  // inline with other children of this aggregate's parent.
-  //
-  // If set to 'single', it'll be hidden only if there's a single error in the
-  // aggregate (so it's not grouping multiple errors together).
-  translucent = false,
-
-  // Value to return when a provided function throws an error. If this is a
-  // function, it will be called with the arguments given to the function.
-  // (This is primarily useful when wrapping a function and then providing it
-  // to another utility, e.g. array.map().)
-  returnOnFail = null,
-} = {}) {
-  const errors = [];
-
-  const aggregate = {};
-
-  aggregate.wrap =
-    (fn) =>
-    (...args) => {
-      try {
-        return fn(...args);
-      } catch (error) {
-        errors.push(error);
-        return typeof returnOnFail === 'function'
-          ? returnOnFail(...args)
-          : returnOnFail;
-      }
-    };
-
-  aggregate.wrapAsync =
-    (fn) =>
-    (...args) => {
-      return fn(...args).then(
-        (value) => value,
-        (error) => {
-          errors.push(error);
-          return typeof returnOnFail === 'function'
-            ? returnOnFail(...args)
-            : returnOnFail;
-        }
-      );
-    };
-
-  aggregate.push = (error) => {
-    errors.push(error);
-  };
-
-  aggregate.call = (fn, ...args) => {
-    return aggregate.wrap(fn)(...args);
-  };
-
-  aggregate.callAsync = (fn, ...args) => {
-    return aggregate.wrapAsync(fn)(...args);
-  };
-
-  aggregate.nest = (...args) => {
-    return aggregate.call(() => withAggregate(...args));
-  };
-
-  aggregate.nestAsync = (...args) => {
-    return aggregate.callAsync(() => withAggregateAsync(...args));
-  };
-
-  aggregate.receive = (results) => {
-    if (!Array.isArray(results)) {
-      if (typeof results === 'object' && results.aggregate) {
-        const {aggregate, result} = results;
-
-        try {
-          aggregate.close();
-        } catch (error) {
-          errors.push(error);
-        }
-
-        return result;
-      }
-
-      throw new Error(`Expected an array or {aggregate, result} object`);
-    }
-
-    return results.map(({aggregate, result}) => {
-      if (!aggregate) {
-        throw new Error(`Expected an array of {aggregate, result} objects`);
-      }
-
-      try {
-        aggregate.close();
-      } catch (error) {
-        errors.push(error);
-      }
-
-      return result;
-    });
-  };
-
-  aggregate.contain = (results) => {
-    return {
-      aggregate,
-      result: aggregate.receive(results),
-    };
-  };
-
-  aggregate.map = (...args) => {
-    const parent = aggregate;
-    const {result, aggregate: child} = mapAggregate(...args);
-    parent.call(child.close);
-    return result;
-  };
-
-  aggregate.mapAsync = async (...args) => {
-    const parent = aggregate;
-    const {result, aggregate: child} = await mapAggregateAsync(...args);
-    parent.call(child.close);
-    return result;
-  };
-
-  aggregate.filter = (...args) => {
-    const parent = aggregate;
-    const {result, aggregate: child} = filterAggregate(...args);
-    parent.call(child.close);
-    return result;
-  };
-
-  aggregate.throws = aggregateThrows;
-
-  aggregate.close = () => {
-    if (errors.length) {
-      const error = Reflect.construct(errorClass, [errors, message]);
-
-      if (translucent) {
-        error[Symbol.for('hsmusic.aggregate.translucent')] = translucent;
-      }
-
-      throw error;
-    }
-  };
-
-  return aggregate;
-}
-
-openAggregate.errorClassSymbol = Symbol('error class');
-
-// Utility function for providing {errorClass} parameter to aggregate functions.
-export function aggregateThrows(errorClass) {
-  return {[openAggregate.errorClassSymbol]: errorClass};
-}
-
-// Helper function for allowing both (fn, opts) and (opts, fn) in aggregate
-// utilities (or other shapes besides functions).
-function _reorganizeAggregateArguments(arg1, arg2, desire = v => typeof v === 'function') {
-  if (desire(arg1)) {
-    return [arg1, arg2 ?? {}];
-  } else if (desire(arg2)) {
-    return [arg2, arg1];
-  } else {
-    return [undefined, undefined];
-  }
-}
-
-// Takes a list of {aggregate, result} objects, puts all the aggregates into
-// a new aggregate, and puts all the results into an array, returning both on
-// a new {aggregate, result} object. This is essentailly the generalized
-// composable version of functions like mapAggregate or filterAggregate.
-export function receiveAggregate(arg1, arg2) {
-  const [array, opts] = _reorganizeAggregateArguments(arg1, arg2, Array.isArray);
-  if (!array) {
-    throw new Error(`Expected an array`);
-  }
-
-  const aggregate = openAggregate(opts);
-  const result = aggregate.receive(array);
-  return {aggregate, result};
-}
-
-// Performs an ordinary array map with the given function, collating into a
-// results array (with errored inputs filtered out) and an error aggregate.
-//
-// Optionally, override returnOnFail to disable filtering and map errored inputs
-// to a particular output.
-//
-// Note the aggregate property is the result of openAggregate(), still unclosed;
-// use aggregate.close() to throw the error. (This aggregate may be passed to a
-// parent aggregate: `parent.call(aggregate.close)`!)
-export function mapAggregate(array, arg1, arg2) {
-  const [fn, opts] = _reorganizeAggregateArguments(arg1, arg2);
-  if (!fn) {
-    throw new Error(`Expected a function`);
-  }
-
-  return _mapAggregate('sync', null, array, fn, opts);
-}
-
-export function mapAggregateAsync(array, arg1, arg2) {
-  const [fn, opts] = _reorganizeAggregateArguments(arg1, arg2);
-  if (!fn) {
-    throw new Error(`Expected a function`);
-  }
-
-  const {promiseAll = Promise.all.bind(Promise), ...remainingOpts} = opts;
-  return _mapAggregate('async', promiseAll, array, fn, remainingOpts);
-}
-
-// Helper function for mapAggregate which holds code common between sync and
-// async versions.
-export function _mapAggregate(mode, promiseAll, array, fn, aggregateOpts) {
-  const failureSymbol = Symbol();
-
-  const aggregate = openAggregate({
-    returnOnFail: failureSymbol,
-    ...aggregateOpts,
-  });
-
-  if (mode === 'sync') {
-    const result = array
-      .map(aggregate.wrap(fn))
-      .filter((value) => value !== failureSymbol);
-    return {result, aggregate};
-  } else {
-    return promiseAll(array.map(aggregate.wrapAsync(fn)))
-      .then((values) => {
-        const result = values.filter((value) => value !== failureSymbol);
-        return {result, aggregate};
-      });
-  }
-}
-
-// Performs an ordinary array filter with the given function, collating into a
-// results array (with errored inputs filtered out) and an error aggregate.
-//
-// Optionally, override returnOnFail to disable filtering errors and map errored
-// inputs to a particular output.
-//
-// As with mapAggregate, the returned aggregate property is not yet closed.
-export function filterAggregate(array, arg1, arg2) {
-  const [fn, opts] = _reorganizeAggregateArguments(arg1, arg2);
-  if (!fn) {
-    throw new Error(`Expected a function`);
-  }
-
-  return _filterAggregate('sync', null, array, fn, opts);
-}
-
-export async function filterAggregateAsync(array, arg1, arg2) {
-  const [fn, opts] = _reorganizeAggregateArguments(arg1, arg2);
-  if (!fn) {
-    throw new Error(`Expected a function`);
-  }
-
-  const {promiseAll = Promise.all.bind(Promise), ...remainingOpts} = opts;
-  return _filterAggregate('async', promiseAll, array, fn, remainingOpts);
-}
-
-// Helper function for filterAggregate which holds code common between sync and
-// async versions.
-function _filterAggregate(mode, promiseAll, array, fn, aggregateOpts) {
-  const failureSymbol = Symbol();
-
-  const aggregate = openAggregate({
-    returnOnFail: failureSymbol,
-    ...aggregateOpts,
-  });
-
-  function filterFunction(value) {
-    // Filter out results which match the failureSymbol, i.e. errored
-    // inputs.
-    if (value === failureSymbol) return false;
-
-    // Always keep results which match the overridden returnOnFail
-    // value, if provided.
-    if (value === aggregateOpts.returnOnFail) return true;
-
-    // Otherwise, filter according to the returned value of the wrapped
-    // function.
-    return value.output;
-  }
-
-  function mapFunction(value) {
-    // Then turn the results back into their corresponding input, or, if
-    // provided, the overridden returnOnFail value.
-    return value === aggregateOpts.returnOnFail ? value : value.input;
-  }
-
-  if (mode === 'sync') {
-    const result = array
-      .map(aggregate.wrap((input, index, array) => {
-        const output = fn(input, index, array);
-        return {input, output};
-      }))
-      .filter(filterFunction)
-      .map(mapFunction);
-
-    return {result, aggregate};
-  } else {
-    return promiseAll(
-      array.map(aggregate.wrapAsync(async (input, index, array) => {
-        const output = await fn(input, index, array);
-        return {input, output};
-      }))
-    ).then((values) => {
-      const result = values.filter(filterFunction).map(mapFunction);
-
-      return {result, aggregate};
-    });
-  }
-}
-
-// Totally sugar function for opening an aggregate, running the provided
-// function with it, then closing the function and returning the result (if
-// there's no throw).
-export function withAggregate(arg1, arg2) {
-  const [fn, opts] = _reorganizeAggregateArguments(arg1, arg2);
-  if (!fn) {
-    throw new Error(`Expected a function`);
-  }
-
-  return _withAggregate('sync', opts, fn);
-}
-
-export function withAggregateAsync(arg1, arg2) {
-  const [fn, opts] = _reorganizeAggregateArguments(arg1, arg2);
-  if (!fn) {
-    throw new Error(`Expected a function`);
-  }
-
-  return _withAggregate('async', opts, fn);
-}
-
-export function _withAggregate(mode, aggregateOpts, fn) {
-  const aggregate = openAggregate(aggregateOpts);
-
-  if (mode === 'sync') {
-    const result = fn(aggregate);
-    aggregate.close();
-    return result;
-  } else {
-    return fn(aggregate).then((result) => {
-      aggregate.close();
-      return result;
-    });
-  }
-}
-
-export const unhelpfulTraceLines = [
-  /sugar/,
-  /sort/,
-  /aggregate/,
-  /composite/,
-  /cacheable-object/,
-  /node:/,
-  /<anonymous>/,
-];
-
-export function getUsefulTraceLine(trace, {helpful, unhelpful}) {
-  if (!trace) return '';
-
-  for (const traceLine of trace.split('\n')) {
-    if (!traceLine.trim().startsWith('at')) {
-      continue;
-    }
-
-    if (!empty(unhelpful)) {
-      if (unhelpful.some(regex => regex.test(traceLine))) {
-        continue;
-      }
-    }
-
-    if (!empty(helpful)) {
-      for (const regex of helpful) {
-        const match = traceLine.match(regex);
-
-        if (match) {
-          return match[1] ?? traceLine;
-        }
-      }
-
-      continue;
-    }
-
-    return traceLine;
-  }
-
-  return '';
-}
-
-export function showAggregate(topError, {
-  pathToFileURL = f => f,
-  showTraces = true,
-  showTranslucent = showTraces,
-  print = true,
-} = {}) {
-  const getTranslucency = error =>
-    error[Symbol.for('hsmusic.aggregate.translucent')] ?? false;
-
-  const determineCauseHelper = cause => {
-    if (!cause) {
-      return null;
-    }
-
-    const translucency = getTranslucency(cause);
-
-    if (!translucency) {
-      return cause;
-    }
-
-    if (translucency === 'single') {
-      if (cause.errors?.length === 1) {
-        return determineCauseHelper(cause.errors[0]);
-      } else {
-        return cause;
-      }
-    }
-
-    return determineCauseHelper(cause.cause);
-  };
-
-  const determineCause = error =>
-    (showTranslucent
-      ? error.cause ?? null
-      : determineCauseHelper(error.cause));
-
-  const determineErrorsHelper = error => {
-    const translucency = getTranslucency(error);
-
-    if (!translucency) {
-      return [error];
-    }
-
-    if (translucency === 'single' && error.errors?.length >= 2) {
-      return [error];
-    }
-
-    const errors = [];
-
-    if (error.cause) {
-      errors.push(...determineErrorsHelper(error.cause));
-    }
-
-    if (error.errors) {
-      errors.push(...error.errors.flatMap(determineErrorsHelper));
-    }
-
-    return errors;
-  };
-
-  const determineErrors = error =>
-    (showTranslucent
-      ? error.errors ?? null
-      : error.errors?.flatMap(determineErrorsHelper) ?? null);
-
-  const flattenErrorStructure = (error, level = 0) => {
-    const cause = determineCause(error);
-    const errors = determineErrors(error);
-
-    return {
-      level,
-
-      kind: error.constructor.name,
-      message: error.message,
-
-      trace:
-        (error[Symbol.for(`hsmusic.aggregate.traceFrom`)]
-          ? error[Symbol.for(`hsmusic.aggregate.traceFrom`)].stack
-          : error.stack),
-
-      cause:
-        (cause
-          ? flattenErrorStructure(cause, level + 1)
-          : null),
-
-      errors:
-        (errors
-          ? errors.map(error => flattenErrorStructure(error, level + 1))
-          : null),
-
-      options: {
-        alwaysTrace:
-          error[Symbol.for(`hsmusic.aggregate.alwaysTrace`)],
-
-        helpfulTraceLines:
-          error[Symbol.for(`hsmusic.aggregate.helpfulTraceLines`)],
-
-        unhelpfulTraceLines:
-          error[Symbol.for(`hsmusic.aggregate.unhelpfulTraceLines`)],
-      }
-    };
-  };
-
-  const recursive = ({
-    level,
-    kind,
-    message,
-    trace,
-    cause,
-    errors,
-    options: {
-      alwaysTrace,
-      helpfulTraceLines: ownHelpfulTraceLines,
-      unhelpfulTraceLines: ownUnhelpfulTraceLines,
-    },
-  }, index, apparentSiblings) => {
-    const subApparentSiblings =
-      (cause && errors
-        ? [cause, ...errors]
-     : cause
-        ? [cause]
-     : errors
-        ? errors
-        : []);
-
-    const anythingHasErrorsThisLayer =
-      apparentSiblings.some(({errors}) => !empty(errors));
-
-    const messagePart =
-      message || `(no message)`;
-
-    const kindPart =
-      kind || `unnamed kind`;
-
-    let headerPart =
-      (showTraces
-        ? `[${kindPart}] ${messagePart}`
-     : errors
-        ? `[${messagePart}]`
-     : anythingHasErrorsThisLayer
-        ? ` ${messagePart}`
-        : messagePart);
-
-    if (showTraces || alwaysTrace) {
-      const traceLine =
-        getUsefulTraceLine(trace, {
-          unhelpful:
-            (ownUnhelpfulTraceLines
-              ? unhelpfulTraceLines.concat(ownUnhelpfulTraceLines)
-              : unhelpfulTraceLines),
-
-          helpful:
-            (ownHelpfulTraceLines
-              ? ownHelpfulTraceLines
-              : null),
-        });
-
-      const tracePart =
-        (traceLine
-          ? '- ' +
-            traceLine
-              .trim()
-              .replace(/file:\/\/.*\.js/, (match) => pathToFileURL(match))
-          : '(no stack trace)');
-
-      headerPart += ` ${colors.dim(tracePart)}`;
-    }
-
-    const head1 = level % 2 === 0 ? '\u21aa' : colors.dim('\u21aa');
-    const bar1 = ' ';
-
-    const causePart =
-      (cause
-        ? recursive(cause, 0, subApparentSiblings)
-            .split('\n')
-            .map((line, i) => i === 0 ? ` ${head1} ${line}` : ` ${bar1} ${line}`)
-            .join('\n')
-        : '');
-
-    const head2 = level % 2 === 0 ? '\u257f' : colors.dim('\u257f');
-    const bar2 = level % 2 === 0 ? '\u2502' : colors.dim('\u254e');
-
-    const errorsPart =
-      (errors
-        ? errors
-            .map((error, index) => recursive(error, index + 1, subApparentSiblings))
-            .flatMap(str => str.split('\n'))
-            .map((line, i) => i === 0 ? ` ${head2} ${line}` : ` ${bar2} ${line}`)
-            .join('\n')
-        : '');
-
-    return [headerPart, errorsPart, causePart].filter(Boolean).join('\n');
-  };
-
-  const structure = flattenErrorStructure(topError);
-  const message = recursive(structure, 0, [structure]);
-
-  if (print) {
-    console.error(message);
-  } else {
-    return message;
-  }
-}
-
-export function annotateError(error, ...callbacks) {
-  for (const callback of callbacks) {
-    error = callback(error) ?? error;
-  }
-
-  return error;
-}
-
-export function annotateErrorWithIndex(error, index) {
-  return Object.assign(error, {
-    [Symbol.for('hsmusic.annotateError.indexInSourceArray')]:
-      index,
-
-    message:
-      `(${colors.yellow(`#${index + 1}`)}) ` +
-      error.message,
-  });
-}
-
-export function annotateErrorWithFile(error, file) {
-  return Object.assign(error, {
-    [Symbol.for('hsmusic.annotateError.file')]:
-      file,
-
-    message:
-      error.message +
-      (error.message.includes('\n') ? '\n' : ' ') +
-      `(file: ${colors.bright(colors.blue(file))})`,
-  });
-}
-
-export function asyncAdaptiveDecorateError(fn, callback) {
-  if (typeof callback !== 'function') {
-    throw new Error(`Expected callback to be a function, got ${typeAppearance(callback)}`);
-  }
-
-  const syncDecorated = function (...args) {
-    try {
-      return fn(...args);
-    } catch (caughtError) {
-      throw callback(caughtError, ...args);
-    }
-  };
-
-  const asyncDecorated = async function(...args) {
-    try {
-      return await fn(...args);
-    } catch (caughtError) {
-      throw callback(caughtError, ...args);
-    }
-  };
-
-  syncDecorated.async = asyncDecorated;
-
-  return syncDecorated;
-}
-
-export function decorateError(fn, callback) {
-  return asyncAdaptiveDecorateError(fn, callback);
-}
-
-export function asyncDecorateError(fn, callback) {
-  return asyncAdaptiveDecorateError(fn, callback).async;
-}
-
-export function decorateErrorWithAnnotation(fn, ...annotationCallbacks) {
-  return asyncAdaptiveDecorateError(fn,
-    (caughtError, ...args) =>
-      annotateError(caughtError,
-        ...annotationCallbacks
-          .map(callback => error => callback(error, ...args))));
-}
-
-export function decorateErrorWithIndex(fn) {
-  return decorateErrorWithAnnotation(fn,
-    (caughtError, _value, index) =>
-      annotateErrorWithIndex(caughtError, index));
-}
-
-export function decorateErrorWithCause(fn, cause) {
-  return asyncAdaptiveDecorateError(fn,
-    (caughtError) =>
-      Object.assign(caughtError, {cause}));
-}
-
-export function asyncDecorateErrorWithAnnotation(fn, ...annotationCallbacks) {
-  return decorateErrorWithAnnotation(fn, ...annotationCallbacks).async;
-}
-
-export function asyncDecorateErrorWithIndex(fn) {
-  return decorateErrorWithIndex(fn).async;
-}
-
-export function asyncDecorateErrorWithCause(fn, cause) {
-  return decorateErrorWithCause(fn, cause).async;
-}
-
-export function conditionallySuppressError(conditionFn, callbackFn) {
-  return (...args) => {
-    try {
-      return callbackFn(...args);
-    } catch (error) {
-      if (conditionFn(error, ...args) === true) {
-        return;
-      }
-
-      throw error;
-    }
-  };
-}
diff --git a/src/util/cli.js b/src/util/cli.js
deleted file mode 100644
index a40a911f..00000000
--- a/src/util/cli.js
+++ /dev/null
@@ -1,521 +0,0 @@
-// Utility functions for CLI- and de8ugging-rel8ted stuff.
-//
-// A 8unch of these depend on process.stdout 8eing availa8le, so they won't
-// work within the 8rowser.
-
-const {process} = globalThis;
-
-import {sortByName} from './sort.js';
-
-export const ENABLE_COLOR =
-  process &&
-  ((process.env.CLICOLOR_FORCE && process.env.CLICOLOR_FORCE === '1') ??
-    (process.env.CLICOLOR &&
-      process.env.CLICOLOR === '1' &&
-      process.stdout.hasColors &&
-      process.stdout.hasColors()) ??
-    (process.stdout.hasColors ? process.stdout.hasColors() : true));
-
-const C = (n) =>
-  ENABLE_COLOR ? (text) => `\x1b[${n}m${text}\x1b[0m` : (text) => text;
-
-export const colors = {
-  bright: C('1'),
-  dim: C('2'),
-  normal: C('22'),
-  black: C('30'),
-  red: C('31'),
-  green: C('32'),
-  yellow: C('33'),
-  blue: C('34'),
-  magenta: C('35'),
-  cyan: C('36'),
-  white: C('37'),
-};
-
-const logColor =
-  (color) =>
-  (literals, ...values) => {
-    const w = (s) => process.stdout.write(s);
-    const wc = (text) => {
-      if (ENABLE_COLOR) w(text);
-    };
-
-    wc(`\x1b[${color}m`);
-    for (let i = 0; i < literals.length; i++) {
-      w(literals[i]);
-      if (values[i] !== undefined) {
-        wc(`\x1b[1m`);
-        w(String(values[i]));
-        wc(`\x1b[0;${color}m`);
-      }
-    }
-    wc(`\x1b[0m`);
-    w('\n');
-  };
-
-export const logInfo = logColor(2);
-export const logWarn = logColor(33);
-export const logError = logColor(31);
-
-// Stolen as #@CK from mtui!
-export async function parseOptions(options, optionDescriptorMap) {
-  // This function is sorely lacking in comments, but the basic usage is
-  // as such:
-  //
-  // options is the array of options you want to process;
-  // optionDescriptorMap is a mapping of option names to objects that describe
-  // the expected value for their corresponding options.
-  //
-  // Returned is...
-  // - a mapping of any specified option names to their values
-  // - a process.exit(1) and error message if there were any issues
-  //
-  // Here are examples of optionDescriptorMap to cover all the things you can
-  // do with it:
-  //
-  // optionDescriptorMap: {
-  //   'telnet-server': {type: 'flag'},
-  //   't': {alias: 'telnet-server'}
-  // }
-  //
-  // options: ['t'] -> result: {'telnet-server': true}
-  //
-  // optionDescriptorMap: {
-  //   'directory': {
-  //     type: 'value',
-  //     validate(name) {
-  //       // const whitelistedDirectories = ['apple', 'banana']
-  //       if (whitelistedDirectories.includes(name)) {
-  //         return true
-  //       } else {
-  //         return 'a whitelisted directory'
-  //       }
-  //     }
-  //   },
-  //   'files': {type: 'series'}
-  // }
-  //
-  // ['--directory', 'apple'] -> {'directory': 'apple'}
-  // ['--directory=banana'] -> {'directory': 'banana'}
-  // ['--directory', 'artichoke'] -> (error)
-  //
-  // ['--files', 'a', 'b', 'c', ';'] -> {'files': ['a', 'b', 'c']}
-  // ['--files=a,b,c'] -> {'files': ['a', 'b', 'c']}
-  // ['--files', 'a,b,c'] -> {'files': ['a', 'b', 'c']}
-
-  const handleDashless = optionDescriptorMap[parseOptions.handleDashless];
-  const handleUnknown = optionDescriptorMap[parseOptions.handleUnknown];
-
-  const result = Object.create(null);
-  for (let i = 0; i < options.length; i++) {
-    const option = options[i];
-    if (option.startsWith('--')) {
-      // --x can be a flag or expect a value or series of values
-      let name = option.slice(2).split('=')[0]; // '--x'.split('=') = ['--x']
-      let descriptor = optionDescriptorMap[name];
-
-      if (!descriptor) {
-        if (handleUnknown) {
-          handleUnknown(option);
-        } else {
-          console.error(`Unknown option name: ${name}`);
-          process.exit(1);
-        }
-        continue;
-      }
-
-      if (descriptor.alias) {
-        name = descriptor.alias;
-        descriptor = optionDescriptorMap[name];
-      }
-
-      switch (descriptor.type) {
-        case 'flag': {
-          result[name] = true;
-          break;
-        }
-
-        case 'value': {
-          let value = option.slice(2).split('=')[1];
-          if (!value) {
-            value = options[++i];
-            if (!value || value.startsWith('-')) {
-              value = null;
-            }
-          }
-
-          if (!value) {
-            console.error(`Expected a value for --${name}`);
-            process.exit(1);
-          }
-
-          result[name] = value;
-          break;
-        }
-
-        case 'series': {
-          if (option.includes('=')) {
-            result[name] = option.split('=')[1].split(',');
-            break;
-          }
-
-          // without a semicolon to conclude the series,
-          // assume the next option expresses the whole series
-          if (!options.slice(i).includes(';')) {
-            let value = options[++i];
-
-            if (!value || value.startsWith('-')) {
-              value = null;
-            }
-
-            if (!value) {
-              console.error(`Expected values for --${name}`);
-              process.exit(1);
-            }
-
-            result[name] = value.split('=')[1].split(',');
-            break;
-          }
-
-          const endIndex = i + options.slice(i).indexOf(';');
-          result[name] = options.slice(i + 1, endIndex);
-          i = endIndex;
-          break;
-        }
-      }
-
-      if (descriptor.validate) {
-        const validation = await descriptor.validate(result[name]);
-        if (validation !== true) {
-          console.error(`Expected ${validation} for --${name}`);
-          process.exit(1);
-        }
-      }
-    } else if (option.startsWith('-')) {
-      // mtui doesn't use any -x=y or -x y format optionuments
-      // -x will always just be a flag
-      let name = option.slice(1);
-      let descriptor = optionDescriptorMap[name];
-      if (!descriptor) {
-        if (handleUnknown) {
-          handleUnknown(option);
-        } else {
-          console.error(`Unknown option name: ${name}`);
-          process.exit(1);
-        }
-        continue;
-      }
-
-      if (descriptor.alias) {
-        name = descriptor.alias;
-        descriptor = optionDescriptorMap[name];
-      }
-
-      if (descriptor.type === 'flag') {
-        result[name] = true;
-      } else {
-        console.error(`Use --${name} (value) to specify ${name}`);
-        process.exit(1);
-      }
-    } else if (handleDashless) {
-      handleDashless(option);
-    }
-  }
-  return result;
-}
-
-// Takes precisely the same sort of structure as `parseOptions` above,
-// and displays associated help messages. Radical!
-//
-// 'indentWrap' should be the function from '#sugar', with its wrap option
-//   already bound.
-//
-// 'sort' should take care of sorting a list of {name, descriptor} entries.
-export function showHelpForOptions({
-  heading,
-  options,
-  indentWrap,
-  sort = entries => entries,
-}) {
-  if (heading) {
-    console.log(colors.bright(heading));
-  }
-
-  const sortedOptions =
-    sort(
-      Object.entries(options)
-        .map(([name, descriptor]) => ({name, descriptor})));
-
-  if (!sortedOptions.length) {
-    console.log(`(No options available)`)
-  }
-
-  let justInsertedPaddingLine = false;
-
-  for (const {name, descriptor} of sortedOptions) {
-    if (descriptor.alias) {
-      continue;
-    }
-
-    const aliases =
-      Object.entries(options)
-        .filter(([_name, {alias}]) => alias === name)
-        .map(([name]) => name);
-
-    let wrappedHelp, wrappedHelpLines = 0;
-    if (descriptor.help) {
-      wrappedHelp = indentWrap(descriptor.help, {spaces: 4});
-      wrappedHelpLines = wrappedHelp.split('\n').length;
-    }
-
-    if (wrappedHelpLines > 0 && !justInsertedPaddingLine) {
-      console.log('');
-    }
-
-    console.log(colors.bright(` --` + name) +
-      (aliases.length
-        ? ` (or: ${aliases.map(alias => colors.bright(`--` + alias)).join(', ')})`
-        : '') +
-      (descriptor.help
-        ? ''
-        : colors.dim('  (no help provided)')));
-
-    if (wrappedHelp) {
-      console.log(wrappedHelp);
-    }
-
-    if (wrappedHelpLines > 1) {
-      console.log('');
-      justInsertedPaddingLine = true;
-    } else {
-      justInsertedPaddingLine = false;
-    }
-  }
-
-  if (!justInsertedPaddingLine) {
-    console.log(``);
-  }
-}
-
-export const handleDashless = Symbol();
-export const handleUnknown = Symbol();
-
-export function decorateTime(arg1, arg2) {
-  const [id, functionToBeWrapped] =
-    typeof arg1 === 'string' || typeof arg1 === 'symbol'
-      ? [arg1, arg2]
-      : [Symbol(arg1.name), arg1];
-
-  const meta = decorateTime.idMetaMap[id] ?? {
-    wrappedName: functionToBeWrapped.name,
-    timeSpent: 0,
-    timesCalled: 0,
-    displayTime() {
-      const align1 = 48;
-      const align2 = 22;
-
-      const averageTime = (meta.timeSpent / meta.timesCalled).toExponential(1);
-      const idPart = typeof id === 'symbol' ? id.description : id;
-      const timePart = `${meta.timeSpent} ms / ${meta.timesCalled} calls`;
-      const avgPart = `(avg: ${averageTime} ms)`;
-
-      const alignPart1 =
-        (idPart.length >= align1
-          ? ' '
-          : ' ' + '.'.repeat(Math.max(0, align1 - 2 - idPart.length)) + ' ');
-
-      const alignPart2 =
-        (timePart.length >= align2
-          ? ' '
-          : ' '.repeat(Math.max(0, align2 - timePart.length)));
-
-      console.log(
-        colors.bright(idPart) +
-        alignPart1 +
-        timePart +
-        alignPart2 +
-        colors.dim(avgPart));
-    },
-  };
-
-  decorateTime.idMetaMap[id] = meta;
-
-  const fn = function (...args) {
-    const start = Date.now();
-    const ret = functionToBeWrapped.apply(this, args);
-    const end = Date.now();
-    meta.timeSpent += end - start;
-    meta.timesCalled++;
-    return ret;
-  };
-
-  fn.displayTime = meta.displayTime;
-
-  return fn;
-}
-
-decorateTime.idMetaMap = Object.create(null);
-
-decorateTime.displayTime = function () {
-  const map = decorateTime.idMetaMap;
-
-  const keys = [
-    ...Object.getOwnPropertySymbols(map),
-    ...Object.getOwnPropertyNames(map),
-  ];
-
-  if (!keys.length) {
-    return;
-  }
-
-  console.log(`\x1b[1mdecorateTime results: ` + '-'.repeat(40) + '\x1b[0m');
-
-  const metas =
-    keys
-      .map(key => map[key])
-      .filter(meta => meta.timeSpent >= 1)  // Milliseconds!
-      .sort((a, b) => a.timeSpent - b.timeSpent);
-
-  for (const meta of metas) {
-    meta.displayTime();
-  }
-};
-
-export function progressPromiseAll(msgOrMsgFn, array) {
-  if (!array.length) {
-    return Promise.resolve([]);
-  }
-
-  const msgFn =
-    typeof msgOrMsgFn === 'function' ? msgOrMsgFn : () => msgOrMsgFn;
-
-  let done = 0,
-    total = array.length;
-  process.stdout.write(`\r${msgFn()} [0/${total}]`);
-  const start = Date.now();
-  return Promise.all(
-    array.map((promise) =>
-      Promise.resolve(promise).then((val) => {
-        done++;
-        // const pc = `${done}/${total}`;
-        const pc = (Math.round((done / total) * 1000) / 10 + '%').padEnd(
-          '99.9%'.length,
-          ' '
-        );
-        if (done === total) {
-          const time = Date.now() - start;
-          process.stdout.write(
-            `\r\x1b[2m${msgFn()} [${pc}] \x1b[0;32mDone! \x1b[0;2m(${time} ms) \x1b[0m\n`
-          );
-        } else {
-          process.stdout.write(`\r${msgFn()} [${pc}] `);
-        }
-        return val;
-      })
-    )
-  );
-}
-
-export function progressCallAll(msgOrMsgFn, array) {
-  if (!array.length) {
-    return [];
-  }
-
-  const msgFn =
-    typeof msgOrMsgFn === 'function' ? msgOrMsgFn : () => msgOrMsgFn;
-
-  const updateInterval = 1000 / 60;
-
-  let done = 0,
-    total = array.length;
-  process.stdout.write(`\r${msgFn()} [0/${total}]`);
-  const start = Date.now();
-  const vals = [];
-  let lastTime = 0;
-
-  for (const fn of array) {
-    const val = fn();
-    done++;
-
-    if (done === total) {
-      const pc = '100%'.padEnd('99.9%'.length, ' ');
-      const time = Date.now() - start;
-      process.stdout.write(
-        `\r\x1b[2m${msgFn()} [${pc}] \x1b[0;32mDone! \x1b[0;2m(${time} ms) \x1b[0m\n`
-      );
-    } else if (Date.now() - lastTime >= updateInterval) {
-      const pc = (Math.round((done / total) * 1000) / 10 + '%').padEnd('99.9%'.length, ' ');
-      process.stdout.write(`\r${msgFn()} [${pc}] `);
-      lastTime = Date.now();
-    }
-    vals.push(val);
-  }
-
-  return vals;
-}
-
-export function fileIssue({
-  topMessage = `This shouldn't happen.`,
-} = {}) {
-  if (topMessage) {
-    console.error(colors.red(`${topMessage} Please let the HSMusic developers know:`));
-  }
-  console.error(colors.red(`- https://hsmusic.wiki/feedback/`));
-  console.error(colors.red(`- https://github.com/hsmusic/hsmusic-wiki/issues/`));
-}
-
-export async function logicalCWD() {
-  if (process.env.PWD) {
-    return process.env.PWD;
-  }
-
-  const {exec} = await import('node:child_process');
-  const {stat} = await import('node:fs/promises');
-
-  try {
-    await stat('/bin/sh');
-  } catch (error) {
-    // Not logical, so sad.
-    return process.cwd();
-  }
-
-  const proc = exec('/bin/pwd -L');
-
-  let output = '';
-  proc.stdout.on('data', buf => { output += buf; });
-
-  await new Promise(resolve => proc.on('exit', resolve));
-
-  return output.trim();
-}
-
-export async function logicalPathTo(target) {
-  const {relative} = await import('node:path');
-  const cwd = await logicalCWD();
-  return relative(cwd, target);
-}
-
-export function stringifyCache(cache) {
-  cache ??= {};
-
-  if (Object.keys(cache).length === 0) {
-    return `{}`;
-  }
-
-  const entries = Object.entries(cache);
-  sortByName(entries, {getName: entry => entry[0]});
-
-  return [
-    `{`,
-    entries
-      .map(([key, value]) => [JSON.stringify(key), JSON.stringify(value)])
-      .map(([key, value]) => `${key}: ${value}`)
-      .map((line, index, array) =>
-        (index < array.length - 1
-          ? `${line},`
-          : line))
-      .map(line => `  ${line}`),
-    `}`,
-  ].flat().join('\n');
-}