[Feature Request] Support for "Splice" patches in arrays for CRDT/Y.js integration (and others)

Abierto
#1,202 2 comentarios 1 reacción 0 asignados Ver en GitHub

Los mantenedores suelen responder en 4 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
javascript

Línea de trabajo

Empieza evaluando la generación actual de parches de arrays de Immer para splice, shift y unshift frente a la opción arraySplice propuesta y al formato de parches. Compara el diseño con los casos de uso de Y.js, Automerge y MobX. Se considerará terminado cuando haya acuerdo sobre una representación opt-in de splice que preserve el comportamiento predeterminado de JSON Patch y cubra las operaciones de array indicadas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

proposal

Currently, when performing array operations like splice(), shift(), or unshift(), Immer generates standard JSON patches (RFC 6902). While spec-compliant, this approach is inefficient for arrays when items are added or removed from the middle.

For example, given [1, 2, 3, 4], calling .splice(1, 1) results in:

  • replace index 1 with 3
  • replace index 2 with 4
  • remove index 3

The Problem
This "shifting" behavior is problematic for CRDTs (like Y.js) or observation-based libraries (like MobX).

Performance: Large arrays trigger a cascade of patches for a single deletion.

Convergence: In Y.js, "replacing" an element is different from "shifting" it. If Immer reports that every element after the splice point has been replaced, the CRDT loses the identity of those objects, breaking the ability to merge concurrent changes effectively.

Proposed Solution

I propose an optional configuration (e.g., arraySplice: true) that generates a non-standard splice operation for array mutations. This would group push, pop, shift, unshift, and splice into a single descriptive patch.

Example Proposed Patch Format:

{
  "op": "splice",
  "path": "/arr",
  "index": 1,
  "deleteCount": 1,
  "items": [...]
}

Use Case

Y.js / Automerge integration: Directly mapping a splice patch to yArray.delete(index, count) and yArray.insert(index, items).

In MobX / other libs it is just calling a splice operation instead.

Performance Optimization: Reducing the payload size when syncing state across WebSockets.

Identity Preservation: Ensuring that elements not being deleted maintain their reference/identity in the eyes of the consumer.

Additional Context

Libraries like mobx use this observation pattern successfully. While I understand Immer aims for JSON Patch compatibility, providing an opt-in for "Rich Patches" or "Splice Patches" would make it the go-to library for distributed state management.

Lenguaje dominante
JavaScript
Estrellas
29k
Forks
905
Merge medio
3 d 16 h
PR fusionados (30 d)
22

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de immerjs/immer

Todos los issues de immerjs/immer

Issues similares

Más issues de JavaScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.