function generate_entry_changes(original_entries, updated_entries) {
  
  const inserts = []
  const updates = []
  const deletions = []
  
  // Handle deletions
  original_entries.forEach(original => {
    if (!updated_entries.find(updated => updated.id === original.id)) {
      deletions.push({ action: 'delete', id: original.id })
    }
  })

  // Handle inserts and updates
  updated_entries.forEach(updated => {
    const original = original_entries.find(o => o.id === updated.id)
    if (!original) {
      inserts.push({ action: 'insert', id: updated.id, data: _.cloneDeep(updated) })
    } else if (!_.isEqual(original, updated)) {
      updates.push({ 
        action: 'update', 
        id: updated.id,
        data: _.cloneDeep(_.omitBy(updated, (v, k) => _.isEqual(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').Entry[]} original_entries - The original array of entries
@param {import('$lib').Entry[]} updated_entries - The updated array of entries  
@returns {{ action: string, id: string, data?: object }[]} Array of change objects