FastLookup = (hubs = createNullObj()) => {
  /** @namespace FastLookup */
  return {
    clone() {
      const clone = createNullObj();
      if (process.env.DEBUG) throwIfProtoPresent(clone);
      for (const group in hubs) { /* proto is null */// eslint-disable-line guard-for-in
        clone[group] = nullObjFrom(hubs[group]);
      }
      return FastLookup(clone);
    },
    delete: key => delete getHub(key)?.[key],
    get: key => getHub(key)?.[key],
    set: (key, val) => (getHub(key, true)[key] = val),
    toArray: () => {
      const values = objectValues(hubs);
      values::forEach((val, i) => { values[i] = objectKeys(val); });
      return safeApply(safeConcat, null, values);
    },
  };
  function getHub(key, autoCreate) {
    const group = key.length ? key[0] : ''; // length is unforgeable, index getters aren't
    const hub = hubs[group] || (
      autoCreate ? (hubs[group] = createNullObj())
        : null
    );
    return hub;
  }
}
2x faster than `Set`, 5x faster than flat object
@param {Object} [hubs]