async function update_block({ block, updated_data }) {

	const original_code = block.code
	let original_fields = _.cloneDeep(block.fields)
	let original_entries = _.cloneDeep(block.entries)

	const updated_code = updated_data.code
	let updated_fields = _.cloneDeep(updated_data.fields)
	let updated_entries = _.cloneDeep(updated_data.entries.filter(e => !e.site && !e.page && !e.page_type))

	let content_changes = db_utils.generate_entry_changes(original_entries, updated_entries)
	let field_changes = db_utils.generate_field_changes(original_fields, updated_fields)

	const local_sections = helpers.generate_sibling_section_changes({ symbol_id: block.id, field_changes, original_fields, updated_fields })
	let foreign_sections = [] // fetch and assign below to avoid delay

	await update_timeline({
		doing: async () => {

			// remap IDs for new items (necessary to refresh IDs when doing() after undoing())
			db_utils.remap_entries_and_fields({
				changes: {
					fields: field_changes,
					entries: [...content_changes, ...local_sections.flatMap(s => s.changes)]
				},
				items: {
					fields: updated_fields,
					entries: [...updated_entries, ...local_sections.flatMap(s => s.entries)]
				}
			})

			// STORE: update code, symbol fields & entries locally w/ DB IDs
			store_actions.update_symbol(block.id, {
				fields: updated_fields,
				entries: updated_entries,
				code: updated_code
			})

			// STORE: update on-page sections' entries
			for (const { id, entries } of local_sections) {
				store_actions.update_section(id, { entries })
			}

			// DB: save block code if changed
			if (!_.isEqual(original_code, updated_code)) {
				await db_actions.update_block(block.id, { code: updated_code })
			}

			// DB: save Symbol fields
			await helpers.handle_field_changes_new(field_changes, {
				symbol: block.id
			})

			// DB: save Symbol entries
			await helpers.handle_content_changes_new(content_changes, {
				symbol: block.id
			})

			// DB: update Symbol Sections
			if (content_changes.length > 0) {
				await Promise.all(
					local_sections.map(({ id, changes }) => 
						helpers.handle_content_changes_new(changes, {
							section: id
						})
					)
				)

				const fetched_foreign_sections = await db_helpers.get_symbol_sections(block.id)
				foreign_sections = helpers.generate_sibling_section_changes({
					symbol_id: block.id,
					field_changes: field_changes,
					original_fields,
					updated_fields
				}, fetched_foreign_sections)

				await Promise.all(
					foreign_sections.map(({ id, changes }) => 
						helpers.handle_content_changes_new(changes, {
							section: id
						})
					)
				)
			}

			update_symbol_file(get(stores.symbols).find(s => s.id === block.id))
		},
		undoing: async () => {

			// DOING: this is too complicated, just replace it with what I was doing before: 
			// use generate_inverse_changes, return the id_map for the fields, and pass it to subsequent generate_inverse_changes/content


			const { changes:inverted_field_changes, fields:restored_fields, map } = db_utils.generate_inverted_field_changes(field_changes, original_fields)

			const { changes:inverted_entry_changes, entries:restored_entries } = db_utils.generate_inverted_entry_changes(content_changes, original_entries, map)
			const all_inverted_local_section_entries = local_sections.map(({ changes, entries }) => db_utils.generate_inverted_entry_changes(changes, entries, map))
			const all_inverted_foreign_section_entries = foreign_sections.map(({ changes, entries }) => db_utils.generate_inverted_entry_changes(changes, entries, map))

			// STORE: update the local sections w/ the original and recreated items
			all_inverted_local_section_entries.forEach((entries, i) => {
				const section_id = local_sections[i].id
				store_actions.update_section(section_id, { entries })
			})


			// STORE: update symbol code, fields, and entries
			store_actions.update_symbol(block.id, {
				fields: restored_fields,
				entries: restored_entries,
				code: original_code
			})


			// DB: restore symbol code
			if (!_.isEqual(original_code, updated_code)) {
				db_actions.update_block(block.id, { code: original_code })
			}

			// DB: restore symbol fields
			await helpers.handle_field_changes_new(inverted_field_changes, { symbol: block.id })


			// DB: revert Symbol and Sections entry changes
			await Promise.all([
				helpers.handle_content_changes_new(inverted_entry_changes, { symbol: block.id }),
				...all_inverted_local_section_entries.map((section, i) => {
					const section_id = local_sections[i].id
					return helpers.handle_content_changes_new(section.changes, { section: section_id })
				}),
			])


			// DB: Reverse foreign sibling section changes
			if (inverted_entry_changes.length > 0) {
				await Promise.all(
					all_inverted_foreign_section_entries.map(async ({ changes, entries }, i) => {
						const section_id = foreign_sections[i].id
						const [ inverted_sibling_entry_changes ] = db_utils.generate_inverted_changes(changes, entries)
						await helpers.handle_content_changes_new(inverted_sibling_entry_changes, {
							section: section_id
						})
					})
				)
			}

			original_fields = restored_fields
			original_entries = restored_entries

			update_symbol_file(get(stores.symbols).find(s => s.id === block.id))
		}
	})
}
Updates a block with new data and handles changes to its fields and entries.
This function also synchronizes entries changes across all instances of the block (section siblings),
and updates the data with database IDs in both the doing() and undoing() methods.

@async
@param {Object} params - The parameters for updating the block.
@param {Object} params.block - The original block object to be updated.
@param {Object} params.updated_data - The new data to update the block with.
@param {string} params.updated_data.code - The updated code for the block.
@param {Array} params.updated_data.fields - The updated fields for the block.
@param {Array} params.updated_data.entries - The updated entries for the block.
@returns {Promise<void>}

@description
In the doing() method:
- Updates the block's code in the database if changed.
- Handles field and entries changes, updating the database and obtaining new database IDs.
- Updates `updated_fields`, `updated_entries`, and changes with the new database IDs.
- Synchronizes changes across all instances of the block (i.e. section siblings).

In the undoing() method:
- Reverts changes made in the doing() method.
- Recreates deleted fields and entries, obtaining new database IDs.
- Updates the reverted data and intial changes with the new database IDs so.

This ensures that all data is consistent with the database state in both forward and backward operations.
Especially when deleting entries/fields, since they're recreated in undoing() and need to be refereced correctly in doing()