def on_message(self, message):
        """ When we get an event from js, lookup the node and invoke the
        action on the enaml node.

        """
        change = json.loads(message)
        log.debug(f'Update from js: {change}')

        # Lookup the node
        ref = change.get('ref')
        if not ref:
            return
        nodes = self.viewer.xpath('//*[@ref=$ref]', ref=ref)
        if not nodes:
            return  # Unknown node
        node = nodes[0]

        # Trigger the change on the enaml node
        if change.get('type') and change.get('name'):
            if change['type'] == 'event':
                trigger = getattr(node, change['name'])
                trigger()
            elif change['type'] == 'update':
                # Trigger the update
                setattr(node, change['name'], change['value'])
        else:
            log.warning(f"Unhandled event {self} {node}: {change}")
When we get an event from js, lookup the node and invoke the
        action on the enaml node.