function generate_field_changes(original_fields, updated_fields) {
  
  // Collect inserts and updates
  const inserts = []
  const updates = []
  const deletions = []
  
  // Handle deletions - keep as is since we want to delete children before parents
  original_fields.forEach(original => {
    if (!updated_fields.find(updated => updated.id === original.id)) {
      deletions.push({ 
        action: 'delete', 
        id: original.id 
      })
    }
  })

  updated_fields.forEach(updated => {
    const original = original_fields.find(o => o.id === updated.id)
    
    if (!original) {
      inserts.push({ 
        action: 'insert', 
        id: updated.id, 
        data: _.cloneDeep(updated)
      })
    } else {
      const comparable_original = _.omit(original, ['id'])
      const comparable_updated = _.omit(updated, ['id'])
      
      if (!_.isEqual(comparable_original, comparable_updated)) {
        updates.push({ 
          action: 'update', 
          id: updated.id,
          data: _.cloneDeep(_.omitBy(comparable_updated, (v, k) => _.isEqual(comparable_original[k], v)))
        })
      }
    }
  })

  // Sort inserts by hierarchy so parents come before children
  const sorted_inserts = sort_by_hierarchy(
    inserts.map(insert => insert.data)
  ).map(data => ({
    action: 'insert',
    id: data.id,
    data
  }))

  // Combine all changes in the correct order: deletions, updates, sorted inserts
  return [
    ...deletions, // deletions
    ...updates,
    ...sorted_inserts
  ]
}
Generates a list of entry changes by comparing original and updated entries

@param {import('$lib').Field[]} original_fields - The original array of entries
@param {import('$lib').Field[]} updated_fields - The updated array of entries  
@returns {{ action: string, id: string, data?: object }[]} Array of change objects