lib/component-helpers.js
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--
}
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--
}
function updateSync ( component , replaceNode = true ) { if ( ! isValidVirtualNode ( component . virtualNode ) ) { throw new Error ( ` ${ component . constructor ? component . constructor . name + ' instance' : component } ` ) } if ( component . element == null ) { throw new Error ( ` ${ component . constructor ? component . constructor . name + ' instance' : component } ` ) } 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 -- }
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.
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 .