All files / src/namespace resolve.ts

9.43% Statements 5/53
0% Branches 0/25
0% Functions 0/10
10% Lines 5/50
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92  15x 15x 15x                           15x                         15x                                                                                                                          
const resolvedMaps = [];
import { NamespaceObjClause } from "../clauses/namespace.types";
 
export default function resolve( clauseRef, registry ) {
  let map = _findFirst( resolvedMaps, ( [ registryRef, m ] ) => {
    if ( registryRef === registry ) {
      return m;
    }
  } );
 
  if ( !map ) {
    map = _createResolveMap( registry );
    resolvedMaps.push( [ registry, map ] );
  }
 
  return _resolveWithMap( map, clauseRef );
}
 
export function getDefList( registry ) {
  const map = _createResolveMap( registry );
  const groups = {};
  map.forEach( ( curr ) => {
    let [ p ] = curr;
    if ( !groups[ p ] ) {
      groups[ p ] = [];
    }
    groups[ p ].push( curr );
  } );
  return groups;
}
 
function _createResolveMap( registry ) {
  const r = [];
  var conformedReg = NamespaceObjClause.conform( registry );
  _walk( null, null, conformedReg, r );
  return r;
}

function _walk( prefix, currN, creg, r ) {
  let currNs = prefix ? `${prefix}.${currN}` : currN;
  let subnamespaces;

  for ( let key in creg ) {
    if ( creg.hasOwnProperty( key ) ) {
      switch ( key ) {
      case "subNamespaces":
        subnamespaces = creg[ key ];
        for ( let sns in subnamespaces ) {
          if ( subnamespaces.hasOwnProperty( sns ) ) {
            _walk( currNs, sns, subnamespaces[ sns ], r );
          }
        }
        break;
      case ".expr":
        r.push( [ `${prefix ? prefix : ''}`, `${currN}`, creg[ '.expr' ] ] );
        break;
      default:
        break;
      }
    }
  }
}

function _resolveWithMap( map, clauseRef ) {
  const path = _findFirst( map, ( [ p, n, r ] ) => {
    if (
      r === clauseRef ||
    _tryStripPredClause( r ) === _tryStripPredClause( clauseRef ) ) {
      return `${p}/${n}`;
    }
  } );
  return path;
}
 
function _tryStripPredClause( expr ) {
  if ( expr.type === 'PRED' ) {
    return expr.opts.predicate;
  } else {
    return expr;
  }
}

function _findFirst( array, fn ) {
  for ( let i = 0; i < array.length; i++ ) {
    let r = fn( array[ i ] );
    if ( r ) {
      return r;
    }
  }
  return null;
}