@composi/runtime:

Immutability

Program State is Mutable

By default a program's state is mutable when you have access to it inside both the update and view methods. Hopefully no one would ever modify state from the code for rendering the view. Update, on the other hand, is how you modify a program's state. For simple examples this is probably not going to be a problem. At the very least, you can use destruction to create a shallow copy of program state:

function actions(state, msg) {
  // Clone the state using destructuring:
  const prevState = {...state}
  return Msg.match(msg, {
    // Check for the message tag:
    'addItem': value => {
      prevState.fruits.push({ key: prevState.newKey++, value })
      // Render view and update program state by return the clone:
      return prevState
    },
    // Check for the message tag:
    'deleteItem': key => {
      prevState.fruits = prevState.fruits.filter(item => item.key != key)
      // Render view and update program stateby return the clone:
      return prevState
    }
  })
}

Deep Clone

If your app and data are complex, you will probably want to create a deep clone of your data. You can do that inside the the update function just like we did with destruction above. Just import the clone function from @composi namespace:

import { h, render, run, union } from '@composi/core'
import { clone } from '@composi/clone'

function actions(state, msg) {
  // Clone the state:
  const prevState = clone(state)
  return Msg.match(msg, {
    // Check for the message tag:
    'addItem': value => {
      prevState.fruits.push({ key: prevState.newKey++, value })
      // Render view and update program state by return the clone:
      return prevState
    },
    // Check for the message tag:
    'deleteItem': key => {
      prevState.fruits = prevState.fruits.filter(item => item.key != key)
      // Render view and update program stateby return the clone:
      return prevState
    }
  })
}

Using the above technique of cloning the state with clone means that the program state won't be updated until the action returns it.