function search(items, pattern, options) {

  const {
    keys
  } = options;

  pattern = pattern.trim().toLowerCase();

  if (!pattern) {
    throw new Error('<pattern> must not be empty');
  }

  const words = pattern.trim().toLowerCase().split(/\s+/);

  return items.flatMap((item) => {
    const tokens = matchItem(item, words, keys);

    if (!tokens) {
      return [];
    }

    return {
      item,
      tokens
    };
  }).sort(createResultSorter(keys));
}
Search items by query.

@template {SearchItem} T

@param {T[]} items elements to search in
@param {string} pattern pattern to search for
@param { {
  keys: string[];
} } options

@returns {SearchResult<T>[]}