-
-
Notifications
You must be signed in to change notification settings - Fork 868
Expand file tree
/
Copy pathimmerClass.ts
More file actions
114 lines (101 loc) · 3.29 KB
/
immerClass.ts
File metadata and controls
114 lines (101 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import {
IProduceWithPatches,
IProduce,
ImmerState,
Drafted,
Patch,
Objectish,
Draft,
PatchListener,
isMap,
isSet,
createProxyProxy,
getPlugin,
getCurrentScope,
DEFAULT_AUTOFREEZE,
DEFAULT_USE_STRICT_SHALLOW_COPY,
ImmerContext,
applyPatchesImpl,
createDraftImpl,
finishDraftImpl,
produceImpl,
produceWithPatchesImpl,
setAutoFreezeImpl,
setUseStrictShallowCopyImpl
} from "../internal"
interface ProducersFns {
produce: IProduce
produceWithPatches: IProduceWithPatches
}
export type StrictMode = boolean | "class_only";
export class Immer implements ProducersFns, ImmerContext {
autoFreeze_: boolean = DEFAULT_AUTOFREEZE
useStrictShallowCopy_: StrictMode = DEFAULT_USE_STRICT_SHALLOW_COPY
constructor(config?: {
autoFreeze?: boolean
useStrictShallowCopy?: StrictMode
}) {
if (typeof config?.autoFreeze === "boolean")
this.setAutoFreeze(config!.autoFreeze)
if (typeof config?.useStrictShallowCopy === "boolean")
this.setUseStrictShallowCopy(config!.useStrictShallowCopy)
}
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
produce: IProduce = produceImpl.bind(this)
produceWithPatches: IProduceWithPatches = produceWithPatchesImpl.bind(this)
createDraft = createDraftImpl.bind(this) as <T extends Objectish>(
base: T
) => Draft<T>
finishDraft = finishDraftImpl.bind(this) as <D extends Draft<any>>(
draft: D,
patchListener?: PatchListener
) => D extends Draft<infer T> ? T : never
/**
* Pass true to automatically freeze all copies created by Immer.
*
* By default, auto-freezing is enabled.
*/
setAutoFreeze = setAutoFreezeImpl.bind(this)
/**
* Pass true to enable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
setUseStrictShallowCopy = setUseStrictShallowCopyImpl.bind(this)
applyPatches = applyPatchesImpl.bind(this) as <T extends Objectish>(
base: T,
patches: readonly Patch[]
) => T
}
export function createProxy<T extends Objectish>(
value: T,
parent?: ImmerState
): Drafted<T, ImmerState> {
// precondition: createProxy should be guarded by isDraftable, so we know we can safely draft
const draft: Drafted = isMap(value)
? getPlugin("MapSet").proxyMap_(value, parent)
: isSet(value)
? getPlugin("MapSet").proxySet_(value, parent)
: createProxyProxy(value, parent)
const scope = parent ? parent.scope_ : getCurrentScope()
scope.drafts_.push(draft)
return draft
}