Skip to content

How did we get to fastn?

Mark Wylde edited this page Nov 7, 2019 · 8 revisions
/*
  How do we put something on the screen
*/
const container = document.createElement('div')
const el1 = document.createElement('span')
el1.textContent = 'This is a test'

const el2 = document.createElement('span')
el2.textContent = 'This is another test'

container.appendChild(el1)
container.appendChild(el2)

/*
  But, this get's annoying and verbose
  Let's make a helper
*/
const container = buildElement('div')
const el1 = buildElement('span', { textContent: 'This is a test'})
const el2 = buildElement('span', { textContent: 'This is another test'})

container.appendChild(el1)
container.appendChild(el2)

/*
  But what if we could nest our elements
*/
const ui = buildElement('div',
  buildElement('span', { textContent: 'This is a test' }),
  buildElement('span', { textContent: 'This is another test' })
)

/*
  Since textContent is acctually a child, let's put in text
*/
const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test')
)

/*
  But I want properties
*/
const colouredEl = buildElement('div', 'I am pretty')
colouredEl.style.backgroundColor = 'yellow'
const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test'),
  colouredEl
)

/*
  Why can't I do this inline?
*/
const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test'),
  buildElement('div', {
    style: {
      backgroundColor: 'yellow'
    }
  }, 'I am pretty')
)

/*
  And update the UI when events happen
*/

const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test'),
  buildElement('div', {
    style: {
      backgroundColor: 'yellow'
    }
  }, 'I am pretty')
  .on('click', function() {
    this.element.style.backgroundColor = 'blue'
  })
)

/*
  But Rather than updating directly, we should bind to state
*/
const state = {
  backgroundColor: 'yellow'
}

const syncBackgroundColor = new EventEmitter()

const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test'),
  buildElement('div', {
    style: {
      backgroundColor: syncBackgroundColor
    }
  }, 'I am pretty')
  .on('click', () => {
    state.backgroundColor = 'yellow'
    syncBackgroundColor.emit('change', state.backgroundColor)
  })
)

/*
  But I don't want to manually emit every time I change state
*/
const state = {
  backgroundColor: 'yellow'
}

const stateEvents = new EventEmitter()

function changeState(state, property, newValue) {
  state[property] = newValue || state[property]
  stateEvents.emit('change', state[property])
}

function observe (emitter, eventName) {
  const localEventEmitter = new EventEmitter()
  emitter.addEventListener(eventName, newValue => {
    localEventEmitter.emit('change', newValue)
  })
  return localEventEmitter
}

const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test'),
  buildElement('div', {
    style: {
      backgroundColor: observe(stateEvents, 'backgroundColor')
    }
  }, 'I am pretty')
  .on('click', () => {
    changeState(state, 'backgroundColor', 'yellow')
  })
)

/*
  But, I don't have my data yet
*/
const state = {
  backgroundColor: 'yellow'
}

const stateEvents = new EventEmitter()

function changeState(state, property, newValue) {
  state[property] = newValue || state[property]
  stateEvents.emit('change', state[property])
}

function observe (emitter, eventName) {
  const localEventEmitter = new EventEmitter()
  let currentEmitter
  const onChange = newValue => {
    localEventEmitter.emit('change', newValue)
  }
  localEventEmitter.attach = emitter => {
    if(currentEmitter){
      currentEmitter.removeListener('change', onChange)
    }
    emitter.addEventListener(eventName, onChange)
  }
  return localEventEmitter
}

const ui = buildElement('div',
  buildElement('span', 'This is a test'),
  buildElement('span', 'This is another test'),
  buildElement('div', {
    style: {
      backgroundColor: observe('backgroundColor').attach(stateEvents)
    }
  }, 'I am pretty')
  .on('click', () => {
    changeState(state, 'backgroundColor', 'yellow')
  })
)
Clone this wiki locally