<commit_before>import PropTypes from 'prop-types'
// @flow weak
// Connects the FormBuilder with various sanity roles
import React from 'react'
import FormBuilder from 'part:@sanity/form-builder'
import {throttle} from 'lodash'
import subscriptionManager from '../utils/subscriptionManager'
import schema from 'part:@sanity/base/schema'
import PatchEvent from '../PatchEvent'
import {checkout} from './formBuilderValueStore'

function getInitialState() {
  return {
    isLoading: true,
    isSaving: false,
    value: null
  }
}

export default class WithFormBuilderValue extends React.PureComponent {
  document: Object

  static propTypes = {
    documentId: PropTypes.string,
    typeName: PropTypes.string,
    children: PropTypes.func
  };

  static childContextTypes = {
    formBuilder: PropTypes.object
  };

  subscriptions = subscriptionManager('documentEvents', 'commit')

  state = getInitialState();

  getChildContext() {
    return {
      formBuilder: FormBuilder.context
    }
  }

  checkoutDocument(documentId) {
    this.document = checkout(documentId)

    this.subscriptions.replace('documentEvents', this.document.events
      .subscribe({
        next: this.handleDocumentEvent,
        // error: this.handleDocumentError
      })
    )
  }

  handleDocumentEvent = event => {
    switch (event.type) {
      case 'snapshot': {
        this.setState({
          isLoading: false,
          value: event.document ? event.document : null
        })
        break
      }
      case 'rebase': {
        this.setState({
          value: event.document
        })
        break
      }
      case 'mutation': {
        this.handleIncomingMutationEvent(event)
        break
      }
      case 'create': {
        this.setState({
          value: event.document
        })
        break
      }
      default: {
        // eslint-disable-next-line no-console
        console.log('Unhandled document event type "%s"', event.type, event)
      }
    }
  }

  componentWillUnmount() {
    this.subscriptions.unsubscribeAll()
  }

  componentWillMount() {
    this.checkoutDocument(this.props.documentId)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.documentId !== this.props.documentId) {
      this.setState(getInitialState())
      this.checkoutDocument(nextProps.documentId)
    }
  }

  handleIncomingMutationEvent(event) {
    // Broadcast incoming patches to input components that applies patches on their own
    // Note: This is *experimental* and likely to change in the near future
    FormBuilder.receivePatches({
      patches: event.patches,
      snapshot: event.document
    })

    this.setState({
      deletedSnapshot: event.deletedSnapshot,
      value: event.document
    })
  }

  commit = throttle(() => {
    this.setState({isSaving: true})
    this.subscriptions.replace('commit', this.document.commit().subscribe({
      next: () => {
        // todo
      },
      error: error => {
        // todo
      },
      complete: () => {
        this.setState({isSaving: false})
      }
    }))

  }, 1000, {leading: true, trailing: true})

  handleChange = (event : PatchEvent) => {
    this.document.patch(event.patches)
    this.commit()
  }

  handleDelete = () => {
    this.document.delete()
    this.commit()
  }

  handleCreate = document => {
    this.document.create(document)
    this.commit()
  }

  render() {
    const {typeName, documentId, children: Component} = this.props
    return (
      <Component
        {...this.state}
        documentId={documentId}
        type={schema.get(typeName)}
        onChange={this.handleChange}
        onDelete={this.handleDelete}
        onCreate={this.handleCreate}
      />
    )
  }
}
<commit_msg>[form-builder] Make sure WithFormBuilderValue emits createIfNotExists<commit_after>import PropTypes from 'prop-types'
// @flow weak
// Connects the FormBuilder with various sanity roles
import React from 'react'
import FormBuilder from 'part:@sanity/form-builder'
import {throttle} from 'lodash'
import subscriptionManager from '../utils/subscriptionManager'
import schema from 'part:@sanity/base/schema'
import PatchEvent from '../PatchEvent'
import {checkout} from './formBuilderValueStore'

function getInitialState() {
  return {
    isLoading: true,
    isSaving: false,
    value: null
  }
}

export default class WithFormBuilderValue extends React.PureComponent {
  document: Object

  static propTypes = {
    documentId: PropTypes.string,
    typeName: PropTypes.string,
    children: PropTypes.func
  };

  static childContextTypes = {
    formBuilder: PropTypes.object
  };

  subscriptions = subscriptionManager('documentEvents', 'commit')

  state = getInitialState();

  getChildContext() {
    return {
      formBuilder: FormBuilder.context
    }
  }

  checkoutDocument(documentId) {
    this.document = checkout(documentId)

    this.subscriptions.replace('documentEvents', this.document.events
      .subscribe({
        next: this.handleDocumentEvent,
        // error: this.handleDocumentError
      })
    )
  }

  handleDocumentEvent = event => {
    switch (event.type) {
      case 'snapshot': {
        this.setState({
          isLoading: false,
          value: event.document ? event.document : null
        })
        break
      }
      case 'rebase': {
        this.setState({
          value: event.document
        })
        break
      }
      case 'mutation': {
        this.handleIncomingMutationEvent(event)
        break
      }
      case 'create': {
        this.setState({
          value: event.document
        })
        break
      }
      default: {
        // eslint-disable-next-line no-console
        console.log('Unhandled document event type "%s"', event.type, event)
      }
    }
  }

  componentWillUnmount() {
    this.subscriptions.unsubscribeAll()
  }

  componentWillMount() {
    this.checkoutDocument(this.props.documentId)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.documentId !== this.props.documentId) {
      this.setState(getInitialState())
      this.checkoutDocument(nextProps.documentId)
    }
  }

  handleIncomingMutationEvent(event) {
    // Broadcast incoming patches to input components that applies patches on their own
    // Note: This is *experimental* and likely to change in the near future
    FormBuilder.receivePatches({
      patches: event.patches,
      snapshot: event.document
    })

    this.setState({
      deletedSnapshot: event.deletedSnapshot,
      value: event.document
    })
  }

  commit = throttle(() => {
    this.setState({isSaving: true})
    this.subscriptions.replace('commit', this.document.commit().subscribe({
      next: () => {
        // todo
      },
      error: error => {
        // todo
      },
      complete: () => {
        this.setState({isSaving: false})
      }
    }))

  }, 1000, {leading: true, trailing: true})

  handleChange = (event : PatchEvent) => {
    this.document.createIfNotExists({
      _id: this.props.documentId,
      _type: this.props.typeName
    })
    this.document.patch(event.patches)
    this.commit()
  }

  handleDelete = () => {
    this.document.delete()
    this.commit()
  }

  handleCreate = document => {
    this.document.create(document)
    this.commit()
  }

  render() {
    const {typeName, documentId, children: Component} = this.props
    return (
      <Component
        {...this.state}
        documentId={documentId}
        type={schema.get(typeName)}
        onChange={this.handleChange}
        onDelete={this.handleDelete}
        onCreate={this.handleCreate}
      />
    )
  }
}

{'fraction_non_alphanumeric': 0.11597258829731154, 'fraction_numerical': 0.0010542962572482868, 'mean_word_length': 2.5512400561534863, 'pattern_counts': {'":': 0, '<': 5, '<?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': '3315186', 'n_tokens_mistral': 2210, 'n_tokens_neox': 2178, 'n_words': 450}