whole_func_string: function updateSync (component, replaceNode=true) {
    if (!isValidVirtualNode(component.virtualNode)) {
      throw new Error(`${component.constructor ? component.constructor.name + ' instance' : component} is not associated with a valid virtualNode. Perhaps this component was never initialized?`)
    }
  
    if (component.element == null) {
      throw new Error(`${component.constructor ? component.constructor.name + ' instance' : component} is not associated with a DOM element. Perhaps this component was never initialized?`)
    }
  
    let newVirtualNode = component.render()
    if (!isValidVirtualNode(newVirtualNode)) {
      const namePart = component.constructor && component.constructor.name ? ' in ' + component.constructor.name : ''
      throw new Error('invalid falsy value ' + newVirtualNode + ' returned from render()' + namePart)
    }
  
    applyContext(component, newVirtualNode)
  
    syncUpdatesInProgressCounter++
    let oldVirtualNode = component.virtualNode
    let oldDomNode = component.element
    let newDomNode = patch(oldVirtualNode, newVirtualNode, {
      refs: component.refs,
      listenerContext: component
    })
    component.virtualNode = newVirtualNode
    if (newDomNode !== oldDomNode && !replaceNode) {
      throw new Error('The root node type changed on update, but the update was performed with the replaceNode option set to false')
    } else {
      component.element = newDomNode
    }
  
    // We can safely perform additional writes after a DOM update synchronously,
    // but any reads need to be deferred until all writes are completed to avoid
    // DOM thrashing. Requested reads occur at the end of the the current frame
    // if this method was invoked via the scheduler. Otherwise, if `updateSync`
    // was invoked outside of the scheduler, the default scheduler will defer
    // reads until the next animation frame.
    if (typeof component.writeAfterUpdate === 'function') {
      component.writeAfterUpdate()
    }
    if (typeof component.readAfterUpdate === 'function') {
      getScheduler().readDocument(function () {
        component.readAfterUpdate()
      })
    }
  
    syncUpdatesInProgressCounter--
  }
func_code_string: function updateSync (component, replaceNode=true) {
    if (!isValidVirtualNode(component.virtualNode)) {
      throw new Error(`${component.constructor ? component.constructor.name + ' instance' : component} is not associated with a valid virtualNode. Perhaps this component was never initialized?`)
    }
  
    if (component.element == null) {
      throw new Error(`${component.constructor ? component.constructor.name + ' instance' : component} is not associated with a DOM element. Perhaps this component was never initialized?`)
    }
  
    let newVirtualNode = component.render()
    if (!isValidVirtualNode(newVirtualNode)) {
      const namePart = component.constructor && component.constructor.name ? ' in ' + component.constructor.name : ''
      throw new Error('invalid falsy value ' + newVirtualNode + ' returned from render()' + namePart)
    }
  
    applyContext(component, newVirtualNode)
  
    syncUpdatesInProgressCounter++
    let oldVirtualNode = component.virtualNode
    let oldDomNode = component.element
    let newDomNode = patch(oldVirtualNode, newVirtualNode, {
      refs: component.refs,
      listenerContext: component
    })
    component.virtualNode = newVirtualNode
    if (newDomNode !== oldDomNode && !replaceNode) {
      throw new Error('The root node type changed on update, but the update was performed with the replaceNode option set to false')
    } else {
      component.element = newDomNode
    }
  
    // We can safely perform additional writes after a DOM update synchronously,
    // but any reads need to be deferred until all writes are completed to avoid
    // DOM thrashing. Requested reads occur at the end of the the current frame
    // if this method was invoked via the scheduler. Otherwise, if `updateSync`
    // was invoked outside of the scheduler, the default scheduler will defer
    // reads until the next animation frame.
    if (typeof component.writeAfterUpdate === 'function') {
      component.writeAfterUpdate()
    }
    if (typeof component.readAfterUpdate === 'function') {
      getScheduler().readDocument(function () {
        component.readAfterUpdate()
      })
    }
  
    syncUpdatesInProgressCounter--
  }
func_documentation_string: Synchronsly updates the DOM element associated with a component object. . This method assumes the presence of `.element` and `.virtualNode` properties on the component, which are assigned in the `initialize` function.  It calls `render` on the component to obtain the desired state of the DOM, then `diff`s it with the previous state and `patch`es the element based on the resulting diff. During the patch operation, it pushes the component's `refs` object to a shared stack so that references to DOM elements can be updated.  If `update` is called during the invocation of `updateSync`, the requests are processed synchronously as well. We track whether this is the case by incrementing and decrementing `syncUpdatesInProgressCounter` around the call.  For now, etch does not allow the root tag of the `render` method to change between invocations, because we want to preserve a one-to-one relationship between component objects and DOM elements for simplicity.