3
3
Finalities ,
4
4
Patches ,
5
5
ProxyDraft ,
6
- Options ,
7
6
Operation ,
7
+ DraftOptions ,
8
8
} from './interface' ;
9
9
import { dataTypes , PROXY_DRAFT } from './constant' ;
10
10
import { mapHandler , mapHandlerKeys } from './map' ;
@@ -38,7 +38,7 @@ const draftsCache = new WeakSet<object>();
38
38
39
39
let arrayHandling = false ;
40
40
41
- const proxyArrayMethods = [ 'splice' , 'shift' , 'unshift' , 'reverse' ] ;
41
+ const proxyArrayMethods = [ 'splice' , 'shift' , 'unshift' ] ;
42
42
43
43
const proxyHandler : ProxyHandler < ProxyDraft > = {
44
44
get ( target : ProxyDraft , key : string | number | symbol , receiver : any ) {
@@ -94,19 +94,39 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
94
94
if ( ! has ( source , key ) ) {
95
95
const desc = getDescriptor ( source , key ) ;
96
96
const value = desc ?. value ;
97
- if ( target . type === DraftType . Array ) {
98
- if ( proxyArrayMethods . includes ( key as string ) ) {
99
- return function ( this : any , ...args : any [ ] ) {
100
- let returnValue : any ;
101
- arrayHandling = true ;
102
- try {
103
- returnValue = value . apply ( this , args ) ;
104
- } finally {
105
- arrayHandling = false ;
97
+ if (
98
+ target . type === DraftType . Array &&
99
+ proxyArrayMethods . includes ( key as string )
100
+ ) {
101
+ const handleItem = ( item : any ) => {
102
+ if ( ! isDraftable ( item ) ) return item ;
103
+ ensureShallowCopy ( target ) ;
104
+ const draft = createDraft ( {
105
+ original : item ,
106
+ parentDraft : target ,
107
+ key : undefined ,
108
+ finalities : target . finalities ,
109
+ options : target . options ,
110
+ } ) ;
111
+ // TODO: support for custom shallow copy function
112
+ return draft ;
113
+ } ;
114
+ return function ( this : any , ...args : any [ ] ) {
115
+ let returnValue : any ;
116
+ arrayHandling = true ;
117
+ try {
118
+ returnValue = value . apply ( this , args ) ;
119
+ if ( key === 'splice' && returnValue . length > 0 ) {
120
+ returnValue = returnValue . map ( handleItem ) ;
121
+ }
122
+ if ( key === 'shift' && typeof returnValue === 'object' ) {
123
+ returnValue = handleItem ( returnValue ) ;
106
124
}
107
125
return returnValue ;
108
- } ;
109
- }
126
+ } finally {
127
+ arrayHandling = false ;
128
+ }
129
+ } ;
110
130
}
111
131
return desc
112
132
? `value` in desc
@@ -126,11 +146,11 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
126
146
if (
127
147
! arrayHandling &&
128
148
( value === peek ( target . original , key ) ||
129
- target . options . skipFinalization ! . has ( value ) )
149
+ target . options . skipFinalization . has ( value ) )
130
150
) {
131
- const shouldSkip = target . options . skipFinalization ! . has ( value ) ;
151
+ const shouldSkip = target . options . skipFinalization . has ( value ) ;
132
152
if ( shouldSkip ) {
133
- target . options . skipFinalization ! . delete ( value ) ;
153
+ target . options . skipFinalization . delete ( value ) ;
134
154
}
135
155
ensureShallowCopy ( target ) ;
136
156
target . copy ! [ key ] = createDraft ( {
@@ -151,7 +171,8 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
151
171
return target . copy ! [ key ] ;
152
172
}
153
173
if ( arrayHandling && ! isDraft ( value ) && isDraftable ( value ) ) {
154
- target . options . skipFinalization ! . add ( value ) ;
174
+ // !case: handle the case of assigning the original array item via array methods(`splice`, `shift``, `unshift`, `reverse`)
175
+ target . options . skipFinalization . add ( value ) ;
155
176
}
156
177
return value ;
157
178
} ,
@@ -258,7 +279,7 @@ export function createDraft<T extends object>(createDraftOptions: {
258
279
parentDraft ?: ProxyDraft | null ;
259
280
key ?: string | number | symbol ;
260
281
finalities : Finalities ;
261
- options : Options < any , any > ;
282
+ options : DraftOptions ;
262
283
} ) : T {
263
284
const { original, parentDraft, key, finalities, options } =
264
285
createDraftOptions ;
0 commit comments