function _fuzzyPrefixMatch(skipIdx, searchStr, targetStr, targetSkips) {
      let searchIdx = 0;
      const searchLen = searchStr.length;
      /** @type {number[]} */
      const ranges = [];

      for (let skipLen = targetSkips.length - 1; skipIdx < skipLen; ++skipIdx) {
        const startIdx = targetSkips[skipIdx];
        const endIdx = targetSkips[skipIdx + 1];
        let targetIdx = startIdx;
        let matchLen = 0;

        while (targetIdx < endIdx && searchIdx < searchLen) {
          const targetChar = targetStr[targetIdx];
          const searchChar = searchStr[searchIdx];

          if (targetChar === searchChar) {
            ++targetIdx;
            ++searchIdx;
            ++matchLen;
            continue;
          }

          // spaces shouldn't break matching
          if (targetChar === ` `) {
            ++targetIdx;
            continue;
          }
          if (searchChar === ` `) {
            ++searchIdx;
            continue;
          }

          break;
        }

        if (matchLen) {
          // make contiguous ranges if possible
          const rangesLen = ranges.length;
          if (rangesLen >= 2 && ranges[rangesLen - 2] + ranges[rangesLen - 1] === startIdx) {
            ranges[rangesLen - 1] += matchLen;
          } else {
            ranges.push(startIdx, matchLen);
          }
        }

        if (searchIdx === searchLen) {
          // search is fully matched, return ranges
          return ranges;
        }
      }

      return null;
    }
performs a prefix match e.g 'usam' matches '[u]nited [s]tates of [am]erica
@param {number} skipIdx - skip index where to start search from
@param {string} searchStr - lowercased search string
@param {string} targetStr - lowercased target string
@param {number[]} targetSkips - skip boundary indices
@returns {number[] | null}
 - the [idx, len, ...] ranges where the match occured
 - null if no match found