Shrinking an array with `length =` and growing it back loses the patches for the truncated indices
I maintainer di solito rispondono entro 4 giorni
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 75/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- javascript
- Ambito
- backend
Direzione di ricerca
Inizia in src/plugins/patches.ts, soprattutto in generateArrayPatches_, e segui come il ridimensionamento di un array draft modifica copy_ e assigned_. Aggiungi il test di regressione fornito per ridurre e poi aumentare di nuovo length, quindi esegui i test relativi alle patch. Il lavoro è completato quando le patch in avanti riproducono il risultato della recipe e le patch inverse ripristinano la base.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
🐛 Bug Report
With enablePatches(), if a recipe shrinks a draft array by assigning .length and then grows it back to at least its original length, no replace patch (and no inverse patch) is produced for the truncated indices. Replaying the patches on the base gives a different state than the recipe, and the inverse patches do not restore the base. The same recipe written with splice(0) produces correct patches.
Link to repro
Not applicable: no CodeSandbox account; the script below and the unit test at the end reproduce it.
To Reproduce
npm i [email protected], save as t.mjs, run node t.mjs:
import { produceWithPatches, applyPatches, enablePatches } from "immer";
enablePatches();
const base = [1];
const [result, patches, inverse] = produceWithPatches(base, d => {
d.length = 0; // truncate index 0
d[1] = 2; // grow again
});
console.log(result);
console.log(patches);
console.log(inverse);
console.log(applyPatches(base, patches));
console.log(applyPatches(result, inverse));
const [r2, p2, i2] = produceWithPatches([1, 2], d => { d.length = 0; d.length = 2; });
console.log(r2, p2, i2);
Observed behavior
[ <1 empty item>, 2 ]
[ { op: 'add', path: [ 1 ], value: 2 } ]
[ { op: 'remove', path: [ 1 ] } ]
[ 1, 2 ]
[ <1 empty item> ]
[ <2 empty items> ] [] []
applyPatches(base, patches) keeps the stale 1 at index 0, and applyPatches(result, inverse) does not bring it back. The second recipe changes both elements but produces no patches at all.
Expected behavior
The same patches as for d.splice(0); d[1] = 2, which immer already gets right:
[
{ op: 'replace', path: [ 0 ], value: undefined },
{ op: 'add', path: [ 1 ], value: 2 }
] [
{ op: 'replace', path: [ 0 ], value: 1 },
{ op: 'remove', path: [ 1 ] }
]
so that applyPatches(base, patches) gives [ undefined, 2 ] and applyPatches(result, inverse) gives [ 1 ].
generateArrayPatches_ in src/plugins/patches.ts only emits a replace for an index below base.length when assigned_.get(i) is set (or allIndicesReassigned_). Assigning a smaller length truncates copy_ without marking the dropped indices as assigned, so they are skipped once the array is long again.
Unit test:
test("length shrink then grow produces replace patches", () => {
const base = [1]
const [result, patches, inverse] = produceWithPatches(base, d => {
d.length = 0
d[1] = 2
})
expect(applyPatches(base, patches)).toEqual(result)
expect(applyPatches(result, inverse)).toEqual(base)
})
Environment
We only accept bug reports against the latest Immer version.
- Immer version: 11.2.9 (also main 75a290e, built from source), Node.js v26.13.0
- I filed this report against the latest version of Immer
- Occurs with
setUseProxies(true) - Occurs with
setUseProxies(false)(ES5 only)
Credit: https://ucsbplse.github.io/
- Lingua principale
- JavaScript
- Stelle
- 29k
- Fork
- 905
- Merge medio
- 3g 16h
- PR unite (30g)
- 22
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di immerjs/immer
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
I maintainer di solito rispondono entro 4 giorni
-
Docs: Chinese (zh-CN) website translation is outdated vs English docsForse di nuovo libera @lijiayou0728 l’ha presa 91 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
immerjs/immer#1242 · 5 commenti ·
I maintainer di solito rispondono entro 4 giorni
-
question
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
immerjs/immer#1217 · 1 commento ·
I maintainer di solito rispondono entro 4 giorni
-
[Feature Request] Support for "Splice" patches in arrays for CRDT/Y.js integration (and others)Apertaproposal
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
immerjs/immer#1202 · 2 commenti · 1 reazione ·
I maintainer di solito rispondono entro 4 giorni
Tutte le issue di immerjs/immer
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Automattic/node-canvas#2633 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
capricorn86/happy-dom#2594 ·
I maintainer di solito rispondono entro 1 giorno
-
Decoding tag 1 (epoch date) with an 8-byte integer throws "Cannot mix BigInt and other types"Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 79/100
microsoft/monaco-editor#5575 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno