Skip to content

Commit 4034924

Browse files
committed
fix(array): update
1 parent 6825509 commit 4034924

File tree

6 files changed

+11248
-47
lines changed

6 files changed

+11248
-47
lines changed

src/draft.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,15 @@ import {
3434
import { checkReadable } from './unsafe';
3535
import { generatePatches } from './patch';
3636

37-
const draftsCache = new WeakSet<object>();
38-
39-
let arrayHandling = false;
40-
4137
// The array methods that need to be handled by the draft.
4238
// `sort` is not included, because array items may be modified by mutations in the sort function, it has to be drafted.
43-
const proxyArrayMethods = [
44-
'splice',
45-
'shift',
46-
'unshift',
47-
'reverse',
48-
'copyWithin',
49-
];
39+
const proxyArrayMethods = ['splice', 'shift', 'unshift', 'reverse'];
5040

5141
const proxyHandler: ProxyHandler<ProxyDraft> = {
5242
get(target: ProxyDraft, key: string | number | symbol, receiver: any) {
5343
const copy = target.copy?.[key];
5444
// Improve draft reading performance by caching the draft copy.
55-
if (copy && draftsCache.has(copy)) {
45+
if (copy && target.finalities.draftsCache.has(copy)) {
5646
return copy;
5747
}
5848
if (key === PROXY_DRAFT) return target;
@@ -74,6 +64,15 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
7464
}
7565
}
7666
const source = latest(target);
67+
const skipFinalization = target.options.skipFinalization;
68+
69+
if (
70+
skipFinalization &&
71+
source[key] &&
72+
target.finalities.draftsCache.has(source[key])
73+
) {
74+
return source[key];
75+
}
7776

7877
if (source instanceof Map && mapHandlerKeys.includes(key as any)) {
7978
if (key === 'size') {
@@ -99,8 +98,6 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
9998
}
10099
}
101100

102-
const skipFinalization = target.options.skipFinalization;
103-
104101
if (!has(source, key)) {
105102
const desc = getDescriptor(source, key);
106103
const value = desc?.value;
@@ -111,21 +108,21 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
111108
) {
112109
return function (this: any, ...args: any[]) {
113110
let returnValue: any;
114-
arrayHandling = true;
111+
target.finalities.arrayHandling = true;
115112
try {
116113
returnValue = value.apply(this, args);
117114
if (isDraftable(returnValue, target.options)) {
118115
returnValue = createDraft({
119116
original: returnValue,
120-
parentDraft: target,
117+
parentDraft: undefined,
121118
key: undefined,
122119
finalities: target.finalities,
123120
options: target.options,
124121
});
125122
}
126123
return returnValue;
127124
} finally {
128-
arrayHandling = false;
125+
target.finalities.arrayHandling = false;
129126
}
130127
};
131128
}
@@ -145,7 +142,7 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
145142
}
146143
// Ensure that the assigned values are not drafted
147144
if (
148-
!arrayHandling &&
145+
!target.finalities.arrayHandling &&
149146
(value === peek(target.original, key) || skipFinalization?.has(value))
150147
) {
151148
const shouldSkip = skipFinalization?.has(value);
@@ -171,12 +168,12 @@ const proxyHandler: ProxyHandler<ProxyDraft> = {
171168
return target.copy![key];
172169
}
173170
if (
174-
arrayHandling &&
171+
target.finalities.arrayHandling &&
175172
skipFinalization &&
176173
!isDraft(value) &&
177174
isDraftable(value)
178175
) {
179-
// !case: handle the case of assigning the original array item via array methods(`splice`, `shift``, `unshift`, `reverse`, `copyWithin`)
176+
// !case: handle the case of assigning the original array item via array methods(`splice`, `shift``, `unshift`, `reverse`)
180177
skipFinalization.add(value);
181178
}
182179
return value;
@@ -313,7 +310,7 @@ export function createDraft<T extends object>(createDraftOptions: {
313310
proxyHandler
314311
);
315312
finalities.revoke.push(revoke);
316-
draftsCache.add(proxy);
313+
finalities.draftsCache.add(proxy);
317314
proxyDraft.proxy = proxy;
318315
if (parentDraft) {
319316
const target = parentDraft;

src/draftify.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export function draftify<
2121
draft: [],
2222
revoke: [],
2323
handledSet: new WeakSet<any>(),
24+
draftsCache: new WeakSet<object>(),
25+
arrayHandling: false,
2426
};
2527
let patches: Patches | undefined;
2628
let inversePatches: Patches | undefined;

src/interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export interface Finalities {
3232
draft: ((patches?: Patches, inversePatches?: Patches) => void)[];
3333
revoke: (() => void)[];
3434
handledSet: WeakSet<any>;
35+
draftsCache: WeakSet<object>;
36+
arrayHandling: boolean;
3537
}
3638

3739
export interface ProxyDraft<T = any> {

0 commit comments

Comments
 (0)