<commit_before>// import {isKeyHotkey} from 'is-hotkey'
import PropTypes from 'prop-types'
import React from 'react'
import schema from 'part:@sanity/base/schema?'
import client from 'part:@sanity/base/client?'
import Preview from 'part:@sanity/base/preview?'
import {joinPath} from 'part:@sanity/base/util/search-utils'
import {getPublishedId, isDraftId, getDraftId} from 'part:@sanity/base/util/draft-utils'
import {Subject} from 'rxjs'
import {IntentLink} from 'part:@sanity/base/router'
import {flow, compact, flatten, union} from 'lodash'
import Ink from 'react-ink'
import SearchField from './SearchField'
import SearchResults from './SearchResults'
import {filter, takeUntil, tap, debounceTime, map, switchMap} from 'rxjs/operators'

import resultsStyles from './styles/SearchResults.css'

// NOTE: Remove until we know what hotkey to use
// const hotKeys = {
//   openSearch: isKeyHotkey('ctrl+t')
// }

// Removes published documents that also has a draft
function removeDupes(documents) {
  const drafts = documents.map(doc => doc._id).filter(isDraftId)

  return documents.filter(doc => {
    const draftId = getDraftId(doc._id)
    const publishedId = getPublishedId(doc._id)
    const hasDraft = drafts.includes(draftId)
    const isPublished = doc._id === publishedId
    return isPublished ? !hasDraft : true
  })
}

const combineFields = flow([flatten, union, compact])

function search(query) {
  if (!client) {
    throw new Error('Sanity client is missing')
  }

  const candidateTypes = schema
    .getTypeNames()
    .filter(typeName => !typeName.startsWith('sanity.'))
    .map(typeName => schema.get(typeName))

  const terms = query.split(/\s+/).filter(Boolean)

  const params = terms.reduce((acc, term, i) => {
    acc[`t${i}`] = `${term}*`
    return acc
  }, {})

  const uniqueFields = combineFields(
    candidateTypes.map(type => (type.__unstable_searchFields || []).map(joinPath))
  )
  const constraints = terms.map((term, i) =>
    uniqueFields.map(joinedPath => `${joinedPath} match $t${i}`)
  )
  const constraintString = constraints.map(constraint => `(${constraint.join('||')})`).join('&&')
  return client.observable.fetch(`*[${constraintString}][0...100]`, params)
}

class SearchContainer extends React.PureComponent {
  static propTypes = {
    onOpen: PropTypes.func.isRequired,
    onClose: PropTypes.func.isRequired,
    shouldBeFocused: PropTypes.bool.isRequired
  }

  input$ = new Subject()
  componentWillUnmount$ = new Subject()
  fieldInstance = null
  resultsInstance = null

  state = {
    activeIndex: -1,
    isBleeding: true, // mobile first
    isFocused: false,<commit_msg>[default-layout] Only select _id and _type when searching (#1057)<commit_after>// import {isKeyHotkey} from 'is-hotkey'
import PropTypes from 'prop-types'
import React from 'react'
import schema from 'part:@sanity/base/schema?'
import client from 'part:@sanity/base/client?'
import Preview from 'part:@sanity/base/preview?'
import {joinPath} from 'part:@sanity/base/util/search-utils'
import {getPublishedId, isDraftId, getDraftId} from 'part:@sanity/base/util/draft-utils'
import {Subject} from 'rxjs'
import {IntentLink} from 'part:@sanity/base/router'
import {flow, compact, flatten, union} from 'lodash'
import Ink from 'react-ink'
import SearchField from './SearchField'
import SearchResults from './SearchResults'
import {filter, takeUntil, tap, debounceTime, map, switchMap} from 'rxjs/operators'

import resultsStyles from './styles/SearchResults.css'

// NOTE: Remove until we know what hotkey to use
// const hotKeys = {
//   openSearch: isKeyHotkey('ctrl+t')
// }

// Removes published documents that also has a draft
function removeDupes(documents) {
  const drafts = documents.map(doc => doc._id).filter(isDraftId)

  return documents.filter(doc => {
    const draftId = getDraftId(doc._id)
    const publishedId = getPublishedId(doc._id)
    const hasDraft = drafts.includes(draftId)
    const isPublished = doc._id === publishedId
    return isPublished ? !hasDraft : true
  })
}

const combineFields = flow([flatten, union, compact])

function search(query) {
  if (!client) {
    throw new Error('Sanity client is missing')
  }

  const candidateTypes = schema
    .getTypeNames()
    .filter(typeName => !typeName.startsWith('sanity.'))
    .map(typeName => schema.get(typeName))

  const terms = query.split(/\s+/).filter(Boolean)

  const params = terms.reduce((acc, term, i) => {
    acc[`t${i}`] = `${term}*`
    return acc
  }, {})

  const uniqueFields = combineFields(
    candidateTypes.map(type => (type.__unstable_searchFields || []).map(joinPath))
  )
  const constraints = terms.map((term, i) =>
    uniqueFields.map(joinedPath => `${joinedPath} match $t${i}`)
  )
  const constraintString = constraints.map(constraint => `(${constraint.join('||')})`).join('&&')
  return client.observable.fetch(`*[${constraintString}][0...100] {_id, _type}`, params)
}

class SearchContainer extends React.PureComponent {
  static propTypes = {
    onOpen: PropTypes.func.isRequired,
    onClose: PropTypes.func.isRequired,
    shouldBeFocused: PropTypes.bool.isRequired
  }

  input$ = new Subject()
  componentWillUnmount$ = new Subject()
  fieldInstance = null
  resultsInstance = null

  state = {
    activeIndex: -1,
    isBleeding: true, // mobile first
    isFocused: false,
{'fraction_non_alphanumeric': 0.14130230812535186, 'fraction_numerical': 0.0026271345468192905, 'mean_word_length': 4.449897750511248, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7320898', 'n_tokens_mistral': 1710, 'n_tokens_neox': 1690, 'n_words': 425}