« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/composite.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/things/composite.js')
-rw-r--r--src/data/things/composite.js727
1 files changed, 1 insertions, 726 deletions
diff --git a/src/data/things/composite.js b/src/data/things/composite.js
index c03f883..7e068dc 100644
--- a/src/data/things/composite.js
+++ b/src/data/things/composite.js
@@ -2,14 +2,7 @@ import {inspect} from 'node:util';
 
 import {colors} from '#cli';
 import {TupleMap} from '#wiki-data';
-
-import {
-  a,
-  is,
-  isString,
-  isWholeNumber,
-  validateArrayItems,
-} from '#validators';
+import {a} from '#validators';
 
 import {
   decorateErrorWithIndex,
@@ -1639,721 +1632,3 @@ export function debugComposite(fn) {
   compositeFrom.debug = false;
   return value;
 }
-
-// Exposes a dependency exactly as it is; this is typically the base of a
-// composition which was created to serve as one property's descriptor.
-//
-// Please note that this *doesn't* verify that the dependency exists, so
-// if you provide the wrong name or it hasn't been set by a previous
-// compositional step, the property will be exposed as undefined instead
-// of null.
-//
-export const exposeDependency = templateCompositeFrom({
-  annotation: `exposeDependency`,
-
-  compose: false,
-
-  inputs: {
-    dependency: input.staticDependency({acceptsNull: true}),
-  },
-
-  steps: () => [
-    {
-      dependencies: [input('dependency')],
-      compute: ({
-        [input('dependency')]: dependency
-      }) => dependency,
-    },
-  ],
-});
-
-// Exposes a constant value exactly as it is; like exposeDependency, this
-// is typically the base of a composition serving as a particular property
-// descriptor. It generally follows steps which will conditionally early
-// exit with some other value, with the exposeConstant base serving as the
-// fallback default value.
-export const exposeConstant = templateCompositeFrom({
-  annotation: `exposeConstant`,
-
-  compose: false,
-
-  inputs: {
-    value: input.staticValue(),
-  },
-
-  steps: () => [
-    {
-      dependencies: [input('value')],
-      compute: ({
-        [input('value')]: value,
-      }) => value,
-    },
-  ],
-});
-
-// Checks the availability of a dependency and provides the result to later
-// steps under '#availability' (by default). This is mainly intended for use
-// by the more specific utilities, which you should consider using instead.
-// Customize {mode} to select one of these modes, or default to 'null':
-//
-// * 'null':  Check that the value isn't null (and not undefined either).
-// * 'empty': Check that the value is neither null, undefined, nor an empty
-//            array.
-// * 'falsy': Check that the value isn't false when treated as a boolean
-//            (nor an empty array). Keep in mind this will also be false
-//            for values like zero and the empty string!
-//
-
-const inputAvailabilityCheckMode = () => input({
-  validate: is('null', 'empty', 'falsy'),
-  defaultValue: 'null',
-});
-
-export const withResultOfAvailabilityCheck = templateCompositeFrom({
-  annotation: `withResultOfAvailabilityCheck`,
-
-  inputs: {
-    from: input({acceptsNull: true}),
-    mode: inputAvailabilityCheckMode(),
-  },
-
-  outputs: ['#availability'],
-
-  steps: () => [
-    {
-      dependencies: [input('from'), input('mode')],
-
-      compute: (continuation, {
-        [input('from')]: value,
-        [input('mode')]: mode,
-      }) => {
-        let availability;
-
-        switch (mode) {
-          case 'null':
-            availability = value !== undefined && value !== null;
-            break;
-
-          case 'empty':
-            availability = value !== undefined && !empty(value);
-            break;
-
-          case 'falsy':
-            availability = !!value && (!Array.isArray(value) || !empty(value));
-            break;
-        }
-
-        return continuation({'#availability': availability});
-      },
-    },
-  ],
-});
-
-// Exposes a dependency as it is, or continues if it's unavailable.
-// See withResultOfAvailabilityCheck for {mode} options!
-export const exposeDependencyOrContinue = templateCompositeFrom({
-  annotation: `exposeDependencyOrContinue`,
-
-  inputs: {
-    dependency: input({acceptsNull: true}),
-    mode: inputAvailabilityCheckMode(),
-  },
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: input('dependency'),
-      mode: input('mode'),
-    }),
-
-    {
-      dependencies: ['#availability', input('dependency')],
-      compute: (continuation, {
-        ['#availability']: availability,
-        [input('dependency')]: dependency,
-      }) =>
-        (availability
-          ? continuation.exit(dependency)
-          : continuation()),
-    },
-  ],
-});
-
-// Exposes the update value of an {update: true} property as it is,
-// or continues if it's unavailable. See withResultOfAvailabilityCheck
-// for {mode} options! Also provide {validate} here to conveniently
-// set a custom validation check for this property's update value.
-export const exposeUpdateValueOrContinue = templateCompositeFrom({
-  annotation: `exposeUpdateValueOrContinue`,
-
-  inputs: {
-    mode: inputAvailabilityCheckMode(),
-
-    validate: input({
-      type: 'function',
-      defaultValue: null,
-    }),
-  },
-
-  update: ({
-    [input.staticValue('validate')]: validate,
-  }) =>
-    (validate
-      ? {validate}
-      : {}),
-
-  steps: () => [
-    exposeDependencyOrContinue({
-      dependency: input.updateValue(),
-      mode: input('mode'),
-    }),
-  ],
-});
-
-// Early exits if a dependency isn't available.
-// See withResultOfAvailabilityCheck for {mode} options!
-export const exitWithoutDependency = templateCompositeFrom({
-  annotation: `exitWithoutDependency`,
-
-  inputs: {
-    dependency: input({acceptsNull: true}),
-    mode: inputAvailabilityCheckMode(),
-    value: input({defaultValue: null}),
-  },
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: input('dependency'),
-      mode: input('mode'),
-    }),
-
-    {
-      dependencies: ['#availability', input('value')],
-      compute: (continuation, {
-        ['#availability']: availability,
-        [input('value')]: value,
-      }) =>
-        (availability
-          ? continuation()
-          : continuation.exit(value)),
-    },
-  ],
-});
-
-// Early exits if this property's update value isn't available.
-// See withResultOfAvailabilityCheck for {mode} options!
-export const exitWithoutUpdateValue = templateCompositeFrom({
-  annotation: `exitWithoutUpdateValue`,
-
-  inputs: {
-    mode: inputAvailabilityCheckMode(),
-    value: input({defaultValue: null}),
-  },
-
-  steps: () => [
-    exitWithoutDependency({
-      dependency: input.updateValue(),
-      mode: input('mode'),
-      value: input('value'),
-    }),
-  ],
-});
-
-// Raises if a dependency isn't available.
-// See withResultOfAvailabilityCheck for {mode} options!
-export const raiseOutputWithoutDependency = templateCompositeFrom({
-  annotation: `raiseOutputWithoutDependency`,
-
-  inputs: {
-    dependency: input({acceptsNull: true}),
-    mode: inputAvailabilityCheckMode(),
-    output: input.staticValue({defaultValue: {}}),
-  },
-
-  outputs: ({
-    [input.staticValue('output')]: output,
-  }) => Object.keys(output),
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: input('dependency'),
-      mode: input('mode'),
-    }),
-
-    {
-      dependencies: ['#availability', input('output')],
-      compute: (continuation, {
-        ['#availability']: availability,
-        [input('output')]: output,
-      }) =>
-        (availability
-          ? continuation()
-          : continuation.raiseOutputAbove(output)),
-    },
-  ],
-});
-
-// Raises if this property's update value isn't available.
-// See withResultOfAvailabilityCheck for {mode} options!
-export const raiseOutputWithoutUpdateValue = templateCompositeFrom({
-  annotation: `raiseOutputWithoutUpdateValue`,
-
-  inputs: {
-    mode: inputAvailabilityCheckMode(),
-    output: input.staticValue({defaultValue: {}}),
-  },
-
-  outputs: ({
-    [input.staticValue('output')]: output,
-  }) => Object.keys(output),
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: input.updateValue(),
-      mode: input('mode'),
-    }),
-
-    {
-      dependencies: ['#availability', input('output')],
-      compute: (continuation, {
-        ['#availability']: availability,
-        [input('output')]: output,
-      }) =>
-        (availability
-          ? continuation()
-          : continuation.raiseOutputAbove(output)),
-    },
-  ],
-});
-
-// Gets a property of some object (in a dependency) and provides that value.
-// If the object itself is null, or the object doesn't have the listed property,
-// the provided dependency will also be null.
-export const withPropertyFromObject = templateCompositeFrom({
-  annotation: `withPropertyFromObject`,
-
-  inputs: {
-    object: input({type: 'object', acceptsNull: true}),
-    property: input({type: 'string'}),
-  },
-
-  outputs: ({
-    [input.staticDependency('object')]: object,
-    [input.staticValue('property')]: property,
-  }) =>
-    (object && property
-      ? (object.startsWith('#')
-          ? [`${object}.${property}`]
-          : [`#${object}.${property}`])
-      : ['#value']),
-
-  steps: () => [
-    {
-      dependencies: [
-        input.staticDependency('object'),
-        input.staticValue('property'),
-      ],
-
-      compute: (continuation, {
-        [input.staticDependency('object')]: object,
-        [input.staticValue('property')]: property,
-      }) => continuation({
-        '#output':
-          (object && property
-            ? (object.startsWith('#')
-                ? `${object}.${property}`
-                : `#${object}.${property}`)
-            : '#value'),
-      }),
-    },
-
-    {
-      dependencies: [
-        '#output',
-        input('object'),
-        input('property'),
-      ],
-
-      compute: (continuation, {
-        ['#output']: output,
-        [input('object')]: object,
-        [input('property')]: property,
-      }) => continuation({
-        [output]:
-          (object === null
-            ? null
-            : object[property] ?? null),
-      }),
-    },
-  ],
-});
-
-// Gets the listed properties from some object, providing each property's value
-// as a dependency prefixed with the same name as the object (by default).
-// If the object itself is null, all provided dependencies will be null;
-// if it's missing only select properties, those will be provided as null.
-export const withPropertiesFromObject = templateCompositeFrom({
-  annotation: `withPropertiesFromObject`,
-
-  inputs: {
-    object: input({type: 'object', acceptsNull: true}),
-
-    properties: input({
-      type: 'array',
-      validate: validateArrayItems(isString),
-    }),
-
-    prefix: input.staticValue({type: 'string', defaultValue: null}),
-  },
-
-  outputs: ({
-    [input.staticDependency('object')]: object,
-    [input.staticValue('properties')]: properties,
-    [input.staticValue('prefix')]: prefix,
-  }) =>
-    (properties
-      ? properties.map(property =>
-          (prefix
-            ? `${prefix}.${property}`
-         : object
-            ? `${object}.${property}`
-            : `#object.${property}`))
-      : ['#object']),
-
-  steps: () => [
-    {
-      dependencies: [input('object'), input('properties')],
-      compute: (continuation, {
-        [input('object')]: object,
-        [input('properties')]: properties,
-      }) => continuation({
-        ['#entries']:
-          (object === null
-            ? properties.map(property => [property, null])
-            : properties.map(property => [property, object[property]])),
-      }),
-    },
-
-    {
-      dependencies: [
-        input.staticDependency('object'),
-        input.staticValue('properties'),
-        input.staticValue('prefix'),
-        '#entries',
-      ],
-
-      compute: (continuation, {
-        [input.staticDependency('object')]: object,
-        [input.staticValue('properties')]: properties,
-        [input.staticValue('prefix')]: prefix,
-        ['#entries']: entries,
-      }) =>
-        (properties
-          ? continuation(
-              Object.fromEntries(
-                entries.map(([property, value]) => [
-                  (prefix
-                    ? `${prefix}.${property}`
-                 : object
-                    ? `${object}.${property}`
-                    : `#object.${property}`),
-                  value ?? null,
-                ])))
-          : continuation({
-              ['#object']:
-                Object.fromEntries(entries),
-            })),
-    },
-  ],
-});
-
-// Gets a property from each of a list of objects (in a dependency) and
-// provides the results. This doesn't alter any list indices, so positions
-// which were null in the original list are kept null here. Objects which don't
-// have the specified property are retained in-place as null.
-export function withPropertyFromList({
-  list,
-  property,
-  into = null,
-}) {
-  into ??=
-    (list.startsWith('#')
-      ? `${list}.${property}`
-      : `#${list}.${property}`);
-
-  return {
-    annotation: `withPropertyFromList`,
-    flags: {expose: true, compose: true},
-
-    expose: {
-      mapDependencies: {list},
-      mapContinuation: {into},
-      options: {property},
-
-      compute(continuation, {list, '#options': {property}}) {
-        if (list === undefined || empty(list)) {
-          return continuation({into: []});
-        }
-
-        return continuation({
-          into:
-            list.map(item =>
-              (item === null || item === undefined
-                ? null
-                : item[property] ?? null)),
-        });
-      },
-    },
-  };
-}
-
-// Gets the listed properties from each of a list of objects, providing lists
-// of property values each into a dependency prefixed with the same name as the
-// list (by default). Like withPropertyFromList, this doesn't alter indices.
-export const withPropertiesFromList = templateCompositeFrom({
-  annotation: `withPropertiesFromList`,
-
-  inputs: {
-    list: input({type: 'array'}),
-
-    properties: input({
-      validate: validateArrayItems(isString),
-    }),
-
-    prefix: input.staticValue({type: 'string', defaultValue: null}),
-  },
-
-  outputs: ({
-    [input.staticDependency('list')]: list,
-    [input.staticValue('properties')]: properties,
-    [input.staticValue('prefix')]: prefix,
-  }) =>
-    (properties
-      ? properties.map(property =>
-          (prefix
-            ? `${prefix}.${property}`
-         : list
-            ? `${list}.${property}`
-            : `#list.${property}`))
-      : ['#lists']),
-
-  steps: () => [
-    {
-      dependencies: [input('list'), input('properties')],
-      compute: (continuation, {
-        [input('list')]: list,
-        [input('properties')]: properties,
-      }) => continuation({
-        ['#lists']:
-          Object.fromEntries(
-            properties.map(property => [
-              property,
-              list.map(item => item[property] ?? null),
-            ])),
-      }),
-    },
-
-    {
-      dependencies: [
-        input.staticDependency('list'),
-        input.staticValue('properties'),
-        input.staticValue('prefix'),
-        '#lists',
-      ],
-
-      compute: (continuation, {
-        [input.staticDependency('list')]: list,
-        [input.staticValue('properties')]: properties,
-        [input.staticValue('prefix')]: prefix,
-        ['#lists']: lists,
-      }) =>
-        (properties
-          ? continuation(
-              Object.fromEntries(
-                properties.map(property => [
-                  (prefix
-                    ? `${prefix}.${property}`
-                 : list
-                    ? `${list}.${property}`
-                    : `#list.${property}`),
-                  lists[property],
-                ])))
-          : continuation({'#lists': lists})),
-    },
-  ],
-});
-
-// Replaces items of a list, which are null or undefined, with some fallback
-// value. By default, this replaces the passed dependency.
-export const fillMissingListItems = templateCompositeFrom({
-  annotation: `fillMissingListItems`,
-
-  inputs: {
-    list: input({type: 'array'}),
-    fill: input({acceptsNull: true}),
-  },
-
-  outputs: ({
-    [input.staticDependency('list')]: list,
-  }) => [list ?? '#list'],
-
-  steps: () => [
-    {
-      dependencies: [input('list'), input('fill')],
-      compute: (continuation, {
-        [input('list')]: list,
-        [input('fill')]: fill,
-      }) => continuation({
-        ['#filled']:
-          list.map(item => item ?? fill),
-      }),
-    },
-
-    {
-      dependencies: [input.staticDependency('list'), '#filled'],
-      compute: (continuation, {
-        [input.staticDependency('list')]: list,
-        ['#filled']: filled,
-      }) => continuation({
-        [list ?? '#list']:
-          filled,
-      }),
-    },
-  ],
-});
-
-// Filters particular values out of a list. Note that this will always
-// completely skip over null, but can be used to filter out any other
-// primitive or object value.
-export const excludeFromList = templateCompositeFrom({
-  annotation: `excludeFromList`,
-
-  inputs: {
-    list: input(),
-
-    item: input({defaultValue: null}),
-    items: input({type: 'array', defaultValue: null}),
-  },
-
-  outputs: ({
-    [input.staticDependency('list')]: list,
-  }) => [list ?? '#list'],
-
-  steps: () => [
-    {
-      dependencies: [
-        input.staticDependency('list'),
-        input('list'),
-        input('item'),
-        input('items'),
-      ],
-
-      compute: (continuation, {
-        [input.staticDependency('list')]: listName,
-        [input('list')]: listContents,
-        [input('item')]: excludeItem,
-        [input('items')]: excludeItems,
-      }) => continuation({
-        [listName ?? '#list']:
-          listContents.filter(item => {
-            if (excludeItem !== null && item === excludeItem) return false;
-            if (!empty(excludeItems) && excludeItems.includes(item)) return false;
-            return true;
-          }),
-      }),
-    },
-  ],
-});
-
-// Flattens an array with one level of nested arrays, providing as dependencies
-// both the flattened array as well as the original starting indices of each
-// successive source array.
-export const withFlattenedList = templateCompositeFrom({
-  annotation: `withFlattenedList`,
-
-  inputs: {
-    list: input({type: 'array'}),
-  },
-
-  outputs: ['#flattenedList', '#flattenedIndices'],
-
-  steps: () => [
-    {
-      dependencies: [input('list')],
-      compute(continuation, {
-        [input('list')]: sourceList,
-      }) {
-        const flattenedList = sourceList.flat();
-        const indices = [];
-        let lastEndIndex = 0;
-        for (const {length} of sourceList) {
-          indices.push(lastEndIndex);
-          lastEndIndex += length;
-        }
-
-        return continuation({
-          ['#flattenedList']: flattenedList,
-          ['#flattenedIndices']: indices,
-        });
-      },
-    },
-  ],
-});
-
-// After mapping the contents of a flattened array in-place (being careful to
-// retain the original indices by replacing unmatched results with null instead
-// of filtering them out), this function allows for recombining them. It will
-// filter out null and undefined items by default (pass {filter: false} to
-// disable this).
-export const withUnflattenedList = templateCompositeFrom({
-  annotation: `withUnflattenedList`,
-
-  inputs: {
-    list: input({
-      type: 'array',
-      defaultDependency: '#flattenedList',
-    }),
-
-    indices: input({
-      validate: validateArrayItems(isWholeNumber),
-      defaultDependency: '#flattenedIndices',
-    }),
-
-    filter: input({
-      type: 'boolean',
-      defaultValue: true,
-    }),
-  },
-
-  outputs: ['#unflattenedList'],
-
-  steps: () => [
-    {
-      dependencies: [input('list'), input('indices'), input('filter')],
-      compute(continuation, {
-        [input('list')]: list,
-        [input('indices')]: indices,
-        [input('filter')]: filter,
-      }) {
-        const unflattenedList = [];
-
-        for (let i = 0; i < indices.length; i++) {
-          const startIndex = indices[i];
-          const endIndex =
-            (i === indices.length - 1
-              ? list.length
-              : indices[i + 1]);
-
-          const values = list.slice(startIndex, endIndex);
-          unflattenedList.push(
-            (filter
-              ? values.filter(value => value !== null && value !== undefined)
-              : values));
-        }
-
-        return continuation({
-          ['#unflattenedList']: unflattenedList,
-        });
-      },
-    },
-  ],
-});