fix: #3563399 prevent data loss when updating index schema
Saving a search_api_index entity fired updateIndex(), which always reindexed, dropped and recreated the Typesense collection, losing all indexed documents even when nothing relevant changed (for example a processor toggle imported with drush cim). A second latent bug: schema changes imported via configuration never rebuilt the collection at all, because the rebuild was only triggered by the schema admin form.
Introduce a CollectionManager service that converges the live collection toward the typesense_schema config entity, the single source of truth:
- SchemaComparator produces an attribute-level SchemaDiff classified as NONE (no-op), COMPATIBLE (field add/drop/attribute change, applied in place with the new TypesenseClient::updateCollectionSchema() PATCH method, preserving all documents) or BREAKING (top-level attributes, field type changes: full rebuild).
- TypesenseSchema::postSave() compares the original and saved schema via isEquals() and reconciles on real changes, for every save channel.
- SearchApiTypesenseBackend::updateIndex() becomes a pure reconciliation pass (ensure collection exists, diff, apply), which also repairs drift no entity save announced. Errors are logged, never re-thrown, so a Typesense failure cannot abort a configuration import.
- SchemaForm no longer saves the index to force a rebuild.
- The collection rebuild moved to a dedicated rebuildCollection() method, used only for breaking changes.
Includes unit coverage for the comparator (server-added defaults, module only attributes, add/drop/modify, id field protection, type and default_sorting_field changes, embed redaction).
Assisted-by: claude-code/claude-fable-5
Closes #3563399