# All files / src/plugin index.js

100% Statements 22/22
80% Branches 4/5
90% Functions 9/10
100% Lines 22/22

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    24x

    2004x
    6357x

    7284x

    2x

    2004x
    3440x

    3440x

    24x
    89x

    89x
    1396x

    4442x
    88x
    88x

    4354x

    2004x

    4354x

    1396x

    89x
    2004x

    2004x

     // Return a single method which will chain all of the middleware provided
    const combineMiddleware = transforms => {
      let transform;

      const chain = transforms.reduce((stack, go) => {
        return go(args => {
          // Each middleware get's a node and context object. The context allows for
          // nested node to have knowledge of the outer/parent context. All of this is
          // part of args array
          return stack(args, transform);
        });
        // unroll last result
      }, ([id]) => id);

      return (args, topLevelTranfrom) => {
        transform = topLevelTranfrom;
        // kick off the chain of middleware, starting from right to left
        return chain(args, transform);
      };
    };

    export const combineParsers = (sortedParsers = []) => {
      const wildcards = [];

      // Normalize parsers by type
      const parsersByType = sortedParsers.reduce((acc, parser) => {
        Object.entries(parser).forEach(([type, cb]) => {
          // Wildcards may only handle types which have other callbacks attached to
          // them.
          if (type === '*') {
            wildcards.push(cb);
            return;
          }

          if (acc[type] == null) {
            // Prepend any previously defined wildcard to maintain precedence
            acc[type] = [...wildcards];
          }

          acc[type].push(cb);
        });

        return acc;
      }, {});

      return Object.entries(parsersByType).reduce((acc, [key, transforms]) => {
        acc[key] = combineMiddleware(transforms);

        return acc;
      }, {});
    };

    export default function plugin() {}