@vve/immer 9.0.0-alpha.1 → 9.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/common.js +83 -0
- package/es/common.js.map +1 -0
- package/es/es5.js +242 -0
- package/es/es5.js.map +1 -0
- package/es/immer.js +263 -0
- package/es/immer.js.map +1 -0
- package/es/index.js +65 -0
- package/es/index.js.map +1 -0
- package/es/patches.js +149 -0
- package/es/patches.js.map +1 -0
- package/es/proxy.js +164 -0
- package/es/proxy.js.map +1 -0
- package/es/scope.js +42 -0
- package/es/scope.js.map +1 -0
- package/lib/common.js +103 -0
- package/lib/common.js.map +1 -0
- package/lib/es5.js +246 -0
- package/lib/es5.js.map +1 -0
- package/lib/immer.d.ts +248 -0
- package/lib/immer.js +272 -0
- package/lib/immer.js.map +1 -0
- package/lib/index.js +119 -0
- package/lib/index.js.map +1 -0
- package/lib/patches.js +156 -0
- package/lib/patches.js.map +1 -0
- package/lib/proxy.js +168 -0
- package/lib/proxy.js.map +1 -0
- package/lib/scope.js +48 -0
- package/lib/scope.js.map +1 -0
- package/package.json +12 -12
- package/umd/index.js +1134 -0
- package/umd/index.js.map +1 -0
- package/umd/index.min.js +2 -0
- package/umd/index.min.js.map +1 -0
- package/dist/immer.js +0 -1016
- package/dist/immer.js.map +0 -1
- package/dist/immer.module.js +0 -999
- package/dist/immer.module.js.map +0 -1
- package/dist/immer.umd.js +0 -2
- package/dist/immer.umd.js.map +0 -1
- /package/{dist → es}/immer.d.ts +0 -0
package/es/common.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export var NOTHING = typeof Symbol !== "undefined" ? Symbol("immer-nothing") : {
|
|
2
|
+
["immer-nothing"]: true
|
|
3
|
+
};
|
|
4
|
+
export var DRAFTABLE = typeof Symbol !== "undefined" && Symbol.for ? Symbol.for("immer-draftable") : "__$immer_draftable";
|
|
5
|
+
export var DRAFT_STATE = typeof Symbol !== "undefined" && Symbol.for ? Symbol.for("immer-state") : "__$immer_state";
|
|
6
|
+
export function isDraft(value) {
|
|
7
|
+
return !!value && !!value[DRAFT_STATE];
|
|
8
|
+
}
|
|
9
|
+
export function isDraftable(value) {
|
|
10
|
+
if (!value || typeof value !== "object") return false;
|
|
11
|
+
if (Array.isArray(value)) return true;
|
|
12
|
+
var proto = Object.getPrototypeOf(value);
|
|
13
|
+
if (!proto || proto === Object.prototype) return true;
|
|
14
|
+
return !!value[DRAFTABLE] || !!value.constructor[DRAFTABLE];
|
|
15
|
+
}
|
|
16
|
+
export function original(value) {
|
|
17
|
+
if (value && value[DRAFT_STATE]) {
|
|
18
|
+
return value[DRAFT_STATE].base;
|
|
19
|
+
}
|
|
20
|
+
// otherwise return undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export var assign = Object.assign || function assign(target, value) {
|
|
24
|
+
for (var key in value) {
|
|
25
|
+
if (has(value, key)) {
|
|
26
|
+
target[key] = value[key];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return target;
|
|
30
|
+
};
|
|
31
|
+
export var ownKeys = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : typeof Object.getOwnPropertySymbols !== "undefined" ? obj => Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)) : Object.getOwnPropertyNames;
|
|
32
|
+
export function shallowCopy(base) {
|
|
33
|
+
var invokeGetters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
34
|
+
if (Array.isArray(base)) return base.slice();
|
|
35
|
+
var clone = Object.create(Object.getPrototypeOf(base));
|
|
36
|
+
ownKeys(base).forEach(key => {
|
|
37
|
+
if (key === DRAFT_STATE) {
|
|
38
|
+
return; // Never copy over draft state.
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var desc = Object.getOwnPropertyDescriptor(base, key);
|
|
42
|
+
var value = desc.value;
|
|
43
|
+
if (desc.get) {
|
|
44
|
+
if (!invokeGetters) {
|
|
45
|
+
throw new Error("Immer drafts cannot have computed properties");
|
|
46
|
+
}
|
|
47
|
+
value = desc.get.call(base);
|
|
48
|
+
}
|
|
49
|
+
if (desc.enumerable) {
|
|
50
|
+
clone[key] = value;
|
|
51
|
+
} else {
|
|
52
|
+
Object.defineProperty(clone, key, {
|
|
53
|
+
value,
|
|
54
|
+
writable: true,
|
|
55
|
+
configurable: true
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return clone;
|
|
60
|
+
}
|
|
61
|
+
export function each(value, cb) {
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
for (var i = 0; i < value.length; i++) cb(i, value[i], value);
|
|
64
|
+
} else {
|
|
65
|
+
ownKeys(value).forEach(key => cb(key, value[key], value));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function isEnumerable(base, prop) {
|
|
69
|
+
var desc = Object.getOwnPropertyDescriptor(base, prop);
|
|
70
|
+
return !!desc && desc.enumerable;
|
|
71
|
+
}
|
|
72
|
+
export function has(thing, prop) {
|
|
73
|
+
return Object.prototype.hasOwnProperty.call(thing, prop);
|
|
74
|
+
}
|
|
75
|
+
export function is(x, y) {
|
|
76
|
+
// From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
|
|
77
|
+
if (x === y) {
|
|
78
|
+
return x !== 0 || 1 / x === 1 / y;
|
|
79
|
+
} else {
|
|
80
|
+
return x !== x && y !== y;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=common.js.map
|
package/es/common.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","names":["NOTHING","Symbol","DRAFTABLE","for","DRAFT_STATE","isDraft","value","isDraftable","Array","isArray","proto","Object","getPrototypeOf","prototype","constructor","original","base","assign","target","key","has","ownKeys","Reflect","getOwnPropertySymbols","obj","getOwnPropertyNames","concat","shallowCopy","invokeGetters","arguments","length","undefined","slice","clone","create","forEach","desc","getOwnPropertyDescriptor","get","Error","call","enumerable","defineProperty","writable","configurable","each","cb","i","isEnumerable","prop","thing","hasOwnProperty","is","x","y"],"sources":["../common.js"],"sourcesContent":["export const NOTHING =\n typeof Symbol !== \"undefined\"\n ? Symbol(\"immer-nothing\")\n : {[\"immer-nothing\"]: true}\n\nexport const DRAFTABLE =\n typeof Symbol !== \"undefined\" && Symbol.for\n ? Symbol.for(\"immer-draftable\")\n : \"__$immer_draftable\"\n\nexport const DRAFT_STATE =\n typeof Symbol !== \"undefined\" && Symbol.for\n ? Symbol.for(\"immer-state\")\n : \"__$immer_state\"\n\nexport function isDraft(value) {\n return !!value && !!value[DRAFT_STATE]\n}\n\nexport function isDraftable(value) {\n if (!value || typeof value !== \"object\") return false\n if (Array.isArray(value)) return true\n const proto = Object.getPrototypeOf(value)\n if (!proto || proto === Object.prototype) return true\n return !!value[DRAFTABLE] || !!value.constructor[DRAFTABLE]\n}\n\nexport function original(value) {\n if (value && value[DRAFT_STATE]) {\n return value[DRAFT_STATE].base\n }\n // otherwise return undefined\n}\n\nexport const assign =\n Object.assign ||\n function assign(target, value) {\n for (let key in value) {\n if (has(value, key)) {\n target[key] = value[key]\n }\n }\n return target\n }\n\nexport const ownKeys =\n typeof Reflect !== \"undefined\" && Reflect.ownKeys\n ? Reflect.ownKeys\n : typeof Object.getOwnPropertySymbols !== \"undefined\"\n ? obj =>\n Object.getOwnPropertyNames(obj).concat(\n Object.getOwnPropertySymbols(obj)\n )\n : Object.getOwnPropertyNames\n\nexport function shallowCopy(base, invokeGetters = false) {\n if (Array.isArray(base)) return base.slice()\n const clone = Object.create(Object.getPrototypeOf(base))\n ownKeys(base).forEach(key => {\n if (key === DRAFT_STATE) {\n return // Never copy over draft state.\n }\n const desc = Object.getOwnPropertyDescriptor(base, key)\n let {value} = desc\n if (desc.get) {\n if (!invokeGetters) {\n throw new Error(\"Immer drafts cannot have computed properties\")\n }\n value = desc.get.call(base)\n }\n if (desc.enumerable) {\n clone[key] = value\n } else {\n Object.defineProperty(clone, key, {\n value,\n writable: true,\n configurable: true\n })\n }\n })\n return clone\n}\n\nexport function each(value, cb) {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) cb(i, value[i], value)\n } else {\n ownKeys(value).forEach(key => cb(key, value[key], value))\n }\n}\n\nexport function isEnumerable(base, prop) {\n const desc = Object.getOwnPropertyDescriptor(base, prop)\n return !!desc && desc.enumerable\n}\n\nexport function has(thing, prop) {\n return Object.prototype.hasOwnProperty.call(thing, prop)\n}\n\nexport function is(x, y) {\n // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js\n if (x === y) {\n return x !== 0 || 1 / x === 1 / y\n } else {\n return x !== x && y !== y\n }\n}\n"],"mappings":"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"}
|
package/es/es5.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { each, has, is, isDraft, isDraftable, isEnumerable, shallowCopy, DRAFT_STATE } from "./common";
|
|
4
|
+
import { ImmerScope } from "./scope";
|
|
5
|
+
|
|
6
|
+
// property descriptors are recycled to make sure we don't create a get and set closure per property,
|
|
7
|
+
// but share them all instead
|
|
8
|
+
var descriptors = {};
|
|
9
|
+
var noop = () => {};
|
|
10
|
+
export function willFinalize(scope, result, isReplaced) {
|
|
11
|
+
scope.drafts.forEach(draft => {
|
|
12
|
+
draft[DRAFT_STATE].finalizing = true;
|
|
13
|
+
});
|
|
14
|
+
if (!isReplaced) {
|
|
15
|
+
if (scope.patches) {
|
|
16
|
+
markChangesRecursively(scope.drafts[0]);
|
|
17
|
+
}
|
|
18
|
+
// This is faster when we don't care about which attributes changed.
|
|
19
|
+
markChangesSweep(scope.drafts);
|
|
20
|
+
}
|
|
21
|
+
// When a child draft is returned, look for changes.
|
|
22
|
+
else if (isDraft(result) && result[DRAFT_STATE].scope === scope) {
|
|
23
|
+
markChangesSweep(scope.drafts);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function createProxy(base, parent) {
|
|
27
|
+
var isArray = Array.isArray(base);
|
|
28
|
+
var draft = clonePotentialDraft(base);
|
|
29
|
+
each(draft, prop => {
|
|
30
|
+
proxyProperty(draft, prop, isArray || isEnumerable(base, prop));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// See "proxy.js" for property documentation.
|
|
34
|
+
var scope = parent ? parent.scope : ImmerScope.current;
|
|
35
|
+
var state = {
|
|
36
|
+
scope,
|
|
37
|
+
modified: false,
|
|
38
|
+
finalizing: false,
|
|
39
|
+
// es5 only
|
|
40
|
+
finalized: false,
|
|
41
|
+
assigned: {},
|
|
42
|
+
parent,
|
|
43
|
+
base,
|
|
44
|
+
draft,
|
|
45
|
+
copy: null,
|
|
46
|
+
revoke,
|
|
47
|
+
revoked: false // es5 only
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
createHiddenProperty(draft, DRAFT_STATE, state);
|
|
51
|
+
scope.drafts.push(draft);
|
|
52
|
+
return draft;
|
|
53
|
+
}
|
|
54
|
+
function revoke() {
|
|
55
|
+
this.revoked = true;
|
|
56
|
+
}
|
|
57
|
+
function source(state) {
|
|
58
|
+
return state.copy || state.base;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Access a property without creating an Immer draft.
|
|
62
|
+
function peek(draft, prop) {
|
|
63
|
+
var state = draft[DRAFT_STATE];
|
|
64
|
+
if (state && !state.finalizing) {
|
|
65
|
+
state.finalizing = true;
|
|
66
|
+
var value = draft[prop];
|
|
67
|
+
state.finalizing = false;
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
return draft[prop];
|
|
71
|
+
}
|
|
72
|
+
function get(state, prop) {
|
|
73
|
+
assertUnrevoked(state);
|
|
74
|
+
var value = peek(source(state), prop);
|
|
75
|
+
if (state.finalizing) return value;
|
|
76
|
+
// Create a draft if the value is unmodified.
|
|
77
|
+
if (value === peek(state.base, prop) && isDraftable(value)) {
|
|
78
|
+
prepareCopy(state);
|
|
79
|
+
return state.copy[prop] = createProxy(value, state);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
function set(state, prop, value) {
|
|
84
|
+
assertUnrevoked(state);
|
|
85
|
+
state.assigned[prop] = true;
|
|
86
|
+
if (!state.modified) {
|
|
87
|
+
if (is(value, peek(source(state), prop))) return;
|
|
88
|
+
markChanged(state);
|
|
89
|
+
prepareCopy(state);
|
|
90
|
+
}
|
|
91
|
+
state.copy[prop] = value;
|
|
92
|
+
}
|
|
93
|
+
function markChanged(state) {
|
|
94
|
+
if (!state.modified) {
|
|
95
|
+
state.modified = true;
|
|
96
|
+
if (state.parent) markChanged(state.parent);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function prepareCopy(state) {
|
|
100
|
+
if (!state.copy) state.copy = clonePotentialDraft(state.base);
|
|
101
|
+
}
|
|
102
|
+
function clonePotentialDraft(base) {
|
|
103
|
+
var state = base && base[DRAFT_STATE];
|
|
104
|
+
if (state) {
|
|
105
|
+
state.finalizing = true;
|
|
106
|
+
var draft = shallowCopy(state.draft, true);
|
|
107
|
+
state.finalizing = false;
|
|
108
|
+
return draft;
|
|
109
|
+
}
|
|
110
|
+
return shallowCopy(base);
|
|
111
|
+
}
|
|
112
|
+
function proxyProperty(draft, prop, enumerable) {
|
|
113
|
+
var desc = descriptors[prop];
|
|
114
|
+
if (desc) {
|
|
115
|
+
desc.enumerable = enumerable;
|
|
116
|
+
} else {
|
|
117
|
+
descriptors[prop] = desc = {
|
|
118
|
+
configurable: true,
|
|
119
|
+
enumerable,
|
|
120
|
+
get() {
|
|
121
|
+
return get(this[DRAFT_STATE], prop);
|
|
122
|
+
},
|
|
123
|
+
set(value) {
|
|
124
|
+
set(this[DRAFT_STATE], prop, value);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
Object.defineProperty(draft, prop, desc);
|
|
129
|
+
}
|
|
130
|
+
function assertUnrevoked(state) {
|
|
131
|
+
if (state.revoked === true) throw new Error("Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + JSON.stringify(source(state)));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// This looks expensive, but only proxies are visited, and only objects without known changes are scanned.
|
|
135
|
+
function markChangesSweep(drafts) {
|
|
136
|
+
// The natural order of drafts in the `scope` array is based on when they
|
|
137
|
+
// were accessed. By processing drafts in reverse natural order, we have a
|
|
138
|
+
// better chance of processing leaf nodes first. When a leaf node is known to
|
|
139
|
+
// have changed, we can avoid any traversal of its ancestor nodes.
|
|
140
|
+
for (var i = drafts.length - 1; i >= 0; i--) {
|
|
141
|
+
var state = drafts[i][DRAFT_STATE];
|
|
142
|
+
if (!state.modified) {
|
|
143
|
+
if (Array.isArray(state.base)) {
|
|
144
|
+
if (hasArrayChanges(state)) markChanged(state);
|
|
145
|
+
} else if (hasObjectChanges(state)) markChanged(state);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function markChangesRecursively(object) {
|
|
150
|
+
if (!object || typeof object !== "object") return;
|
|
151
|
+
var state = object[DRAFT_STATE];
|
|
152
|
+
if (!state) return;
|
|
153
|
+
var base = state.base,
|
|
154
|
+
draft = state.draft,
|
|
155
|
+
assigned = state.assigned;
|
|
156
|
+
if (!Array.isArray(object)) {
|
|
157
|
+
// Look for added keys.
|
|
158
|
+
Object.keys(draft).forEach(key => {
|
|
159
|
+
// The `undefined` check is a fast path for pre-existing keys.
|
|
160
|
+
if (base[key] === undefined && !has(base, key)) {
|
|
161
|
+
assigned[key] = true;
|
|
162
|
+
markChanged(state);
|
|
163
|
+
} else if (!assigned[key]) {
|
|
164
|
+
// Only untouched properties trigger recursion.
|
|
165
|
+
markChangesRecursively(draft[key]);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
// Look for removed keys.
|
|
169
|
+
Object.keys(base).forEach(key => {
|
|
170
|
+
// The `undefined` check is a fast path for pre-existing keys.
|
|
171
|
+
if (draft[key] === undefined && !has(draft, key)) {
|
|
172
|
+
assigned[key] = false;
|
|
173
|
+
markChanged(state);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
} else if (hasArrayChanges(state)) {
|
|
177
|
+
markChanged(state);
|
|
178
|
+
assigned.length = true;
|
|
179
|
+
if (draft.length < base.length) {
|
|
180
|
+
for (var i = draft.length; i < base.length; i++) assigned[i] = false;
|
|
181
|
+
} else {
|
|
182
|
+
for (var _i = base.length; _i < draft.length; _i++) assigned[_i] = true;
|
|
183
|
+
}
|
|
184
|
+
for (var _i2 = 0; _i2 < draft.length; _i2++) {
|
|
185
|
+
// Only untouched indices trigger recursion.
|
|
186
|
+
if (assigned[_i2] === undefined) markChangesRecursively(draft[_i2]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function hasObjectChanges(state) {
|
|
191
|
+
var base = state.base,
|
|
192
|
+
draft = state.draft;
|
|
193
|
+
|
|
194
|
+
// Search for added keys and changed keys. Start at the back, because
|
|
195
|
+
// non-numeric keys are ordered by time of definition on the object.
|
|
196
|
+
var keys = Object.keys(draft);
|
|
197
|
+
for (var i = keys.length - 1; i >= 0; i--) {
|
|
198
|
+
var key = keys[i];
|
|
199
|
+
var baseValue = base[key];
|
|
200
|
+
// The `undefined` check is a fast path for pre-existing keys.
|
|
201
|
+
if (baseValue === undefined && !has(base, key)) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
// Once a base key is deleted, future changes go undetected, because its
|
|
205
|
+
// descriptor is erased. This branch detects any missed changes.
|
|
206
|
+
else {
|
|
207
|
+
var value = draft[key];
|
|
208
|
+
var _state = value && value[DRAFT_STATE];
|
|
209
|
+
if (_state ? _state.base !== baseValue : !is(value, baseValue)) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// At this point, no keys were added or changed.
|
|
216
|
+
// Compare key count to determine if keys were deleted.
|
|
217
|
+
return keys.length !== Object.keys(base).length;
|
|
218
|
+
}
|
|
219
|
+
function hasArrayChanges(state) {
|
|
220
|
+
var draft = state.draft;
|
|
221
|
+
if (draft.length !== state.base.length) return true;
|
|
222
|
+
// See #116
|
|
223
|
+
// If we first shorten the length, our array interceptors will be removed.
|
|
224
|
+
// If after that new items are added, result in the same original length,
|
|
225
|
+
// those last items will have no intercepting property.
|
|
226
|
+
// So if there is no own descriptor on the last position, we know that items were removed and added
|
|
227
|
+
// N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check
|
|
228
|
+
// the last one
|
|
229
|
+
var descriptor = Object.getOwnPropertyDescriptor(draft, draft.length - 1);
|
|
230
|
+
// descriptor can be null, but only for newly created sparse arrays, eg. new Array(10)
|
|
231
|
+
if (descriptor && !descriptor.get) return true;
|
|
232
|
+
// For all other cases, we don't have to compare, as they would have been picked up by the index setters
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
function createHiddenProperty(target, prop, value) {
|
|
236
|
+
Object.defineProperty(target, prop, {
|
|
237
|
+
value: value,
|
|
238
|
+
enumerable: false,
|
|
239
|
+
writable: true
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=es5.js.map
|
package/es/es5.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"es5.js","names":["each","has","is","isDraft","isDraftable","isEnumerable","shallowCopy","DRAFT_STATE","ImmerScope","descriptors","noop","willFinalize","scope","result","isReplaced","drafts","forEach","draft","finalizing","patches","markChangesRecursively","markChangesSweep","createProxy","base","parent","isArray","Array","clonePotentialDraft","prop","proxyProperty","current","state","modified","finalized","assigned","copy","revoke","revoked","createHiddenProperty","push","source","peek","value","get","assertUnrevoked","prepareCopy","set","markChanged","enumerable","desc","configurable","Object","defineProperty","Error","JSON","stringify","i","length","hasArrayChanges","hasObjectChanges","object","keys","key","undefined","baseValue","descriptor","getOwnPropertyDescriptor","target","writable"],"sources":["../es5.js"],"sourcesContent":["\"use strict\"\nimport {\n each,\n has,\n is,\n isDraft,\n isDraftable,\n isEnumerable,\n shallowCopy,\n DRAFT_STATE\n} from \"./common\"\nimport {ImmerScope} from \"./scope\"\n\n// property descriptors are recycled to make sure we don't create a get and set closure per property,\n// but share them all instead\nconst descriptors = {}\nconst noop = () => {}\n\nexport function willFinalize(scope, result, isReplaced) {\n scope.drafts.forEach(draft => {\n draft[DRAFT_STATE].finalizing = true\n })\n if (!isReplaced) {\n if (scope.patches) {\n markChangesRecursively(scope.drafts[0])\n }\n // This is faster when we don't care about which attributes changed.\n markChangesSweep(scope.drafts)\n }\n // When a child draft is returned, look for changes.\n else if (isDraft(result) && result[DRAFT_STATE].scope === scope) {\n markChangesSweep(scope.drafts)\n }\n}\n\nexport function createProxy(base, parent) {\n const isArray = Array.isArray(base)\n const draft = clonePotentialDraft(base)\n each(draft, prop => {\n proxyProperty(draft, prop, isArray || isEnumerable(base, prop))\n })\n\n // See \"proxy.js\" for property documentation.\n const scope = parent ? parent.scope : ImmerScope.current\n const state = {\n scope,\n modified: false,\n finalizing: false, // es5 only\n finalized: false,\n assigned: {},\n parent,\n base,\n draft,\n copy: null,\n revoke,\n revoked: false // es5 only\n }\n\n createHiddenProperty(draft, DRAFT_STATE, state)\n scope.drafts.push(draft)\n return draft\n}\n\nfunction revoke() {\n this.revoked = true\n}\n\nfunction source(state) {\n return state.copy || state.base\n}\n\n// Access a property without creating an Immer draft.\nfunction peek(draft, prop) {\n const state = draft[DRAFT_STATE]\n if (state && !state.finalizing) {\n state.finalizing = true\n const value = draft[prop]\n state.finalizing = false\n return value\n }\n return draft[prop]\n}\n\nfunction get(state, prop) {\n assertUnrevoked(state)\n const value = peek(source(state), prop)\n if (state.finalizing) return value\n // Create a draft if the value is unmodified.\n if (value === peek(state.base, prop) && isDraftable(value)) {\n prepareCopy(state)\n return (state.copy[prop] = createProxy(value, state))\n }\n return value\n}\n\nfunction set(state, prop, value) {\n assertUnrevoked(state)\n state.assigned[prop] = true\n if (!state.modified) {\n if (is(value, peek(source(state), prop))) return\n markChanged(state)\n prepareCopy(state)\n }\n state.copy[prop] = value\n}\n\nfunction markChanged(state) {\n if (!state.modified) {\n state.modified = true\n if (state.parent) markChanged(state.parent)\n }\n}\n\nfunction prepareCopy(state) {\n if (!state.copy) state.copy = clonePotentialDraft(state.base)\n}\n\nfunction clonePotentialDraft(base) {\n const state = base && base[DRAFT_STATE]\n if (state) {\n state.finalizing = true\n const draft = shallowCopy(state.draft, true)\n state.finalizing = false\n return draft\n }\n return shallowCopy(base)\n}\n\nfunction proxyProperty(draft, prop, enumerable) {\n let desc = descriptors[prop]\n if (desc) {\n desc.enumerable = enumerable\n } else {\n descriptors[prop] = desc = {\n configurable: true,\n enumerable,\n get() {\n return get(this[DRAFT_STATE], prop)\n },\n set(value) {\n set(this[DRAFT_STATE], prop, value)\n }\n }\n }\n Object.defineProperty(draft, prop, desc)\n}\n\nfunction assertUnrevoked(state) {\n if (state.revoked === true)\n throw new Error(\n \"Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? \" +\n JSON.stringify(source(state))\n )\n}\n\n// This looks expensive, but only proxies are visited, and only objects without known changes are scanned.\nfunction markChangesSweep(drafts) {\n // The natural order of drafts in the `scope` array is based on when they\n // were accessed. By processing drafts in reverse natural order, we have a\n // better chance of processing leaf nodes first. When a leaf node is known to\n // have changed, we can avoid any traversal of its ancestor nodes.\n for (let i = drafts.length - 1; i >= 0; i--) {\n const state = drafts[i][DRAFT_STATE]\n if (!state.modified) {\n if (Array.isArray(state.base)) {\n if (hasArrayChanges(state)) markChanged(state)\n } else if (hasObjectChanges(state)) markChanged(state)\n }\n }\n}\n\nfunction markChangesRecursively(object) {\n if (!object || typeof object !== \"object\") return\n const state = object[DRAFT_STATE]\n if (!state) return\n const {base, draft, assigned} = state\n if (!Array.isArray(object)) {\n // Look for added keys.\n Object.keys(draft).forEach(key => {\n // The `undefined` check is a fast path for pre-existing keys.\n if (base[key] === undefined && !has(base, key)) {\n assigned[key] = true\n markChanged(state)\n } else if (!assigned[key]) {\n // Only untouched properties trigger recursion.\n markChangesRecursively(draft[key])\n }\n })\n // Look for removed keys.\n Object.keys(base).forEach(key => {\n // The `undefined` check is a fast path for pre-existing keys.\n if (draft[key] === undefined && !has(draft, key)) {\n assigned[key] = false\n markChanged(state)\n }\n })\n } else if (hasArrayChanges(state)) {\n markChanged(state)\n assigned.length = true\n if (draft.length < base.length) {\n for (let i = draft.length; i < base.length; i++) assigned[i] = false\n } else {\n for (let i = base.length; i < draft.length; i++) assigned[i] = true\n }\n for (let i = 0; i < draft.length; i++) {\n // Only untouched indices trigger recursion.\n if (assigned[i] === undefined) markChangesRecursively(draft[i])\n }\n }\n}\n\nfunction hasObjectChanges(state) {\n const {base, draft} = state\n\n // Search for added keys and changed keys. Start at the back, because\n // non-numeric keys are ordered by time of definition on the object.\n const keys = Object.keys(draft)\n for (let i = keys.length - 1; i >= 0; i--) {\n const key = keys[i]\n const baseValue = base[key]\n // The `undefined` check is a fast path for pre-existing keys.\n if (baseValue === undefined && !has(base, key)) {\n return true\n }\n // Once a base key is deleted, future changes go undetected, because its\n // descriptor is erased. This branch detects any missed changes.\n else {\n const value = draft[key]\n const state = value && value[DRAFT_STATE]\n if (state ? state.base !== baseValue : !is(value, baseValue)) {\n return true\n }\n }\n }\n\n // At this point, no keys were added or changed.\n // Compare key count to determine if keys were deleted.\n return keys.length !== Object.keys(base).length\n}\n\nfunction hasArrayChanges(state) {\n const {draft} = state\n if (draft.length !== state.base.length) return true\n // See #116\n // If we first shorten the length, our array interceptors will be removed.\n // If after that new items are added, result in the same original length,\n // those last items will have no intercepting property.\n // So if there is no own descriptor on the last position, we know that items were removed and added\n // N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check\n // the last one\n const descriptor = Object.getOwnPropertyDescriptor(draft, draft.length - 1)\n // descriptor can be null, but only for newly created sparse arrays, eg. new Array(10)\n if (descriptor && !descriptor.get) return true\n // For all other cases, we don't have to compare, as they would have been picked up by the index setters\n return false\n}\n\nfunction createHiddenProperty(target, prop, value) {\n Object.defineProperty(target, prop, {\n value: value,\n enumerable: false,\n writable: true\n })\n}\n"],"mappings":"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"}
|
package/es/immer.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import * as legacyProxy from "./es5";
|
|
2
|
+
import * as modernProxy from "./proxy";
|
|
3
|
+
import { applyPatches, generatePatches } from "./patches";
|
|
4
|
+
import { assign, each, has, is, isDraft, isDraftable, isEnumerable, shallowCopy, DRAFT_STATE, NOTHING } from "./common";
|
|
5
|
+
import { ImmerScope } from "./scope";
|
|
6
|
+
function verifyMinified() {}
|
|
7
|
+
var configDefaults = {
|
|
8
|
+
useProxies: typeof Proxy !== "undefined" && typeof Reflect !== "undefined",
|
|
9
|
+
autoFreeze: typeof process !== "undefined" ? process.env.NODE_ENV !== "production" : verifyMinified.name === "verifyMinified",
|
|
10
|
+
onAssign: null,
|
|
11
|
+
onDelete: null,
|
|
12
|
+
onCopy: null
|
|
13
|
+
};
|
|
14
|
+
export class Immer {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
assign(this, configDefaults, config);
|
|
17
|
+
this.setUseProxies(this.useProxies);
|
|
18
|
+
this.produce = this.produce.bind(this);
|
|
19
|
+
}
|
|
20
|
+
produce(base, recipe, patchListener) {
|
|
21
|
+
// curried invocation
|
|
22
|
+
if (typeof base === "function" && typeof recipe !== "function") {
|
|
23
|
+
var defaultBase = recipe;
|
|
24
|
+
recipe = base;
|
|
25
|
+
var self = this;
|
|
26
|
+
return function curriedProduce() {
|
|
27
|
+
var base = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultBase;
|
|
28
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
29
|
+
args[_key - 1] = arguments[_key];
|
|
30
|
+
}
|
|
31
|
+
return self.produce(base, draft => recipe.call(this, draft, ...args)); // prettier-ignore
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// prettier-ignore
|
|
36
|
+
{
|
|
37
|
+
if (typeof recipe !== "function") {
|
|
38
|
+
throw new Error("The first or second argument to `produce` must be a function");
|
|
39
|
+
}
|
|
40
|
+
if (patchListener !== undefined && typeof patchListener !== "function") {
|
|
41
|
+
throw new Error("The third argument to `produce` must be a function or undefined");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
var result;
|
|
45
|
+
|
|
46
|
+
// Only plain objects, arrays, and "immerable classes" are drafted.
|
|
47
|
+
if (isDraftable(base)) {
|
|
48
|
+
var scope = ImmerScope.enter();
|
|
49
|
+
var proxy = this.createProxy(base);
|
|
50
|
+
var hasError = true;
|
|
51
|
+
try {
|
|
52
|
+
result = recipe(proxy);
|
|
53
|
+
hasError = false;
|
|
54
|
+
} finally {
|
|
55
|
+
// finally instead of catch + rethrow better preserves original stack
|
|
56
|
+
if (hasError) scope.revoke();else scope.leave();
|
|
57
|
+
}
|
|
58
|
+
if (result instanceof Promise) {
|
|
59
|
+
return result.then(result => {
|
|
60
|
+
scope.usePatches(patchListener);
|
|
61
|
+
return this.processResult(result, scope);
|
|
62
|
+
}, error => {
|
|
63
|
+
scope.revoke();
|
|
64
|
+
throw error;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
scope.usePatches(patchListener);
|
|
68
|
+
return this.processResult(result, scope);
|
|
69
|
+
} else {
|
|
70
|
+
result = recipe(base);
|
|
71
|
+
if (result === undefined) return base;
|
|
72
|
+
return result !== NOTHING ? result : undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
createDraft(base) {
|
|
76
|
+
if (!isDraftable(base)) {
|
|
77
|
+
throw new Error("First argument to `createDraft` must be a plain object, an array, or an immerable object"); // prettier-ignore
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
var scope = ImmerScope.enter();
|
|
81
|
+
var proxy = this.createProxy(base, null);
|
|
82
|
+
proxy[DRAFT_STATE].isManual = true;
|
|
83
|
+
scope.leave();
|
|
84
|
+
return proxy;
|
|
85
|
+
}
|
|
86
|
+
finishDraft(draft, patchListener, keepAlive) {
|
|
87
|
+
var state = draft && draft[DRAFT_STATE];
|
|
88
|
+
if (!state || !state.isManual) {
|
|
89
|
+
throw new Error("First argument to `finishDraft` must be a draft returned by `createDraft`"); // prettier-ignore
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (state.finalized) {
|
|
93
|
+
throw new Error("The given draft is already finalized"); // prettier-ignore
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
var scope = state.scope;
|
|
97
|
+
scope.usePatches(patchListener);
|
|
98
|
+
return this.processResult(undefined, scope, keepAlive);
|
|
99
|
+
}
|
|
100
|
+
setAutoFreeze(value) {
|
|
101
|
+
this.autoFreeze = value;
|
|
102
|
+
}
|
|
103
|
+
setUseProxies(value) {
|
|
104
|
+
this.useProxies = value;
|
|
105
|
+
assign(this, value ? modernProxy : legacyProxy);
|
|
106
|
+
}
|
|
107
|
+
applyPatches(base, patches) {
|
|
108
|
+
// Mutate the base state when a draft is passed.
|
|
109
|
+
if (isDraft(base)) {
|
|
110
|
+
return applyPatches(base, patches);
|
|
111
|
+
}
|
|
112
|
+
// Otherwise, produce a copy of the base state.
|
|
113
|
+
return this.produce(base, draft => applyPatches(draft, patches));
|
|
114
|
+
}
|
|
115
|
+
/** @internal */
|
|
116
|
+
processResult(result, scope, keepAlive) {
|
|
117
|
+
var baseDraft = scope.drafts[0];
|
|
118
|
+
var isReplaced = result !== undefined && result !== baseDraft;
|
|
119
|
+
this.willFinalize(scope, result, isReplaced);
|
|
120
|
+
if (isReplaced) {
|
|
121
|
+
if (baseDraft[DRAFT_STATE].modified) {
|
|
122
|
+
scope.revoke(keepAlive);
|
|
123
|
+
throw new Error("An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft."); // prettier-ignore
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (isDraftable(result)) {
|
|
127
|
+
// Finalize the result in case it contains (or is) a subset of the draft.
|
|
128
|
+
result = this.finalize(result, null, scope);
|
|
129
|
+
}
|
|
130
|
+
if (scope.patches) {
|
|
131
|
+
scope.patches.push({
|
|
132
|
+
op: "replace",
|
|
133
|
+
path: [],
|
|
134
|
+
value: result
|
|
135
|
+
});
|
|
136
|
+
scope.inversePatches.push({
|
|
137
|
+
op: "replace",
|
|
138
|
+
path: [],
|
|
139
|
+
value: baseDraft[DRAFT_STATE].base
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
// Finalize the base draft.
|
|
144
|
+
result = this.finalize(baseDraft, [], scope, keepAlive);
|
|
145
|
+
}
|
|
146
|
+
scope.revoke(keepAlive);
|
|
147
|
+
if (scope.patches) {
|
|
148
|
+
scope.patchListener(scope.patches, scope.inversePatches);
|
|
149
|
+
}
|
|
150
|
+
return result !== NOTHING ? result : undefined;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* @internal
|
|
154
|
+
* Finalize a draft, returning either the unmodified base state or a modified
|
|
155
|
+
* copy of the base state.
|
|
156
|
+
*/
|
|
157
|
+
finalize(draft, path, scope, keepAlive) {
|
|
158
|
+
var state = draft[DRAFT_STATE];
|
|
159
|
+
if (!state) {
|
|
160
|
+
if (Object.isFrozen(draft)) return draft;
|
|
161
|
+
return this.finalizeTree(draft, null, scope);
|
|
162
|
+
}
|
|
163
|
+
// Never finalize drafts owned by another scope.
|
|
164
|
+
if (state.scope !== scope) {
|
|
165
|
+
return draft;
|
|
166
|
+
}
|
|
167
|
+
if (!state.modified) {
|
|
168
|
+
return state.base;
|
|
169
|
+
}
|
|
170
|
+
if (!state.finalized) {
|
|
171
|
+
if (!keepAlive) state.finalized = true;
|
|
172
|
+
this.finalizeTree(state.draft, path, scope);
|
|
173
|
+
if (this.onDelete) {
|
|
174
|
+
// The `assigned` object is unreliable with ES5 drafts.
|
|
175
|
+
if (this.useProxies) {
|
|
176
|
+
var assigned = state.assigned;
|
|
177
|
+
for (var prop in assigned) {
|
|
178
|
+
if (!assigned[prop]) this.onDelete(state, prop);
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
var base = state.base,
|
|
182
|
+
copy = state.copy;
|
|
183
|
+
each(base, prop => {
|
|
184
|
+
if (!has(copy, prop)) this.onDelete(state, prop);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (this.onCopy) {
|
|
189
|
+
this.onCopy(state);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// At this point, all descendants of `state.copy` have been finalized,
|
|
193
|
+
// so we can be sure that `scope.canAutoFreeze` is accurate.
|
|
194
|
+
if (this.autoFreeze && scope.canAutoFreeze) {
|
|
195
|
+
Object.freeze(state.copy);
|
|
196
|
+
}
|
|
197
|
+
if (path && scope.patches) {
|
|
198
|
+
generatePatches(state, path, scope.patches, scope.inversePatches);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return state.copy;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* @internal
|
|
205
|
+
* Finalize all drafts in the given state tree.
|
|
206
|
+
*/
|
|
207
|
+
finalizeTree(root, rootPath, scope) {
|
|
208
|
+
var state = root[DRAFT_STATE];
|
|
209
|
+
if (state) {
|
|
210
|
+
if (!this.useProxies) {
|
|
211
|
+
// Create the final copy, with added keys and without deleted keys.
|
|
212
|
+
state.copy = shallowCopy(state.draft, true);
|
|
213
|
+
}
|
|
214
|
+
root = state.copy;
|
|
215
|
+
}
|
|
216
|
+
var needPatches = !!rootPath && !!scope.patches;
|
|
217
|
+
var finalizeProperty = (prop, value, parent) => {
|
|
218
|
+
if (value === parent) {
|
|
219
|
+
throw Error("Immer forbids circular references");
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// In the `finalizeTree` method, only the `root` object may be a draft.
|
|
223
|
+
var isDraftProp = !!state && parent === root;
|
|
224
|
+
if (isDraft(value)) {
|
|
225
|
+
var path = isDraftProp && needPatches && !state.assigned[prop] ? rootPath.concat(prop) : null;
|
|
226
|
+
|
|
227
|
+
// Drafts owned by `scope` are finalized here.
|
|
228
|
+
value = this.finalize(value, path, scope);
|
|
229
|
+
|
|
230
|
+
// Drafts from another scope must prevent auto-freezing.
|
|
231
|
+
if (isDraft(value)) {
|
|
232
|
+
scope.canAutoFreeze = false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Preserve non-enumerable properties.
|
|
236
|
+
if (Array.isArray(parent) || isEnumerable(parent, prop)) {
|
|
237
|
+
parent[prop] = value;
|
|
238
|
+
} else {
|
|
239
|
+
Object.defineProperty(parent, prop, {
|
|
240
|
+
value
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Unchanged drafts are never passed to the `onAssign` hook.
|
|
245
|
+
if (isDraftProp && value === state.base[prop]) return;
|
|
246
|
+
}
|
|
247
|
+
// Unchanged draft properties are ignored.
|
|
248
|
+
else if (isDraftProp && is(value, state.base[prop])) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// Search new objects for unfinalized drafts. Frozen objects should never contain drafts.
|
|
252
|
+
else if (isDraftable(value) && !Object.isFrozen(value)) {
|
|
253
|
+
each(value, finalizeProperty);
|
|
254
|
+
}
|
|
255
|
+
if (isDraftProp && this.onAssign) {
|
|
256
|
+
this.onAssign(state, prop, value);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
each(root, finalizeProperty);
|
|
260
|
+
return root;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=immer.js.map
|