source: frontend/node_modules/immer/src/plugins/mapset.ts

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 8.0 KB
Line 
1// types only!
2import {
3 ImmerState,
4 AnyMap,
5 AnySet,
6 MapState,
7 SetState,
8 DRAFT_STATE,
9 getCurrentScope,
10 latest,
11 iteratorSymbol,
12 isDraftable,
13 createProxy,
14 loadPlugin,
15 markChanged,
16 ProxyType,
17 die,
18 each
19} from "../internal"
20
21export function enableMapSet() {
22 /* istanbul ignore next */
23 var extendStatics = function(d: any, b: any): any {
24 extendStatics =
25 Object.setPrototypeOf ||
26 ({__proto__: []} instanceof Array &&
27 function(d, b) {
28 d.__proto__ = b
29 }) ||
30 function(d, b) {
31 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]
32 }
33 return extendStatics(d, b)
34 }
35
36 // Ugly hack to resolve #502 and inherit built in Map / Set
37 function __extends(d: any, b: any): any {
38 extendStatics(d, b)
39 function __(this: any): any {
40 this.constructor = d
41 }
42 d.prototype =
43 // @ts-ignore
44 ((__.prototype = b.prototype), new __())
45 }
46
47 const DraftMap = (function(_super) {
48 __extends(DraftMap, _super)
49 // Create class manually, cause #502
50 function DraftMap(this: any, target: AnyMap, parent?: ImmerState): any {
51 this[DRAFT_STATE] = {
52 type_: ProxyType.Map,
53 parent_: parent,
54 scope_: parent ? parent.scope_ : getCurrentScope()!,
55 modified_: false,
56 finalized_: false,
57 copy_: undefined,
58 assigned_: undefined,
59 base_: target,
60 draft_: this as any,
61 isManual_: false,
62 revoked_: false
63 } as MapState
64 return this
65 }
66 const p = DraftMap.prototype
67
68 Object.defineProperty(p, "size", {
69 get: function() {
70 return latest(this[DRAFT_STATE]).size
71 }
72 // enumerable: false,
73 // configurable: true
74 })
75
76 p.has = function(key: any): boolean {
77 return latest(this[DRAFT_STATE]).has(key)
78 }
79
80 p.set = function(key: any, value: any) {
81 const state: MapState = this[DRAFT_STATE]
82 assertUnrevoked(state)
83 if (!latest(state).has(key) || latest(state).get(key) !== value) {
84 prepareMapCopy(state)
85 markChanged(state)
86 state.assigned_!.set(key, true)
87 state.copy_!.set(key, value)
88 state.assigned_!.set(key, true)
89 }
90 return this
91 }
92
93 p.delete = function(key: any): boolean {
94 if (!this.has(key)) {
95 return false
96 }
97
98 const state: MapState = this[DRAFT_STATE]
99 assertUnrevoked(state)
100 prepareMapCopy(state)
101 markChanged(state)
102 if (state.base_.has(key)) {
103 state.assigned_!.set(key, false)
104 } else {
105 state.assigned_!.delete(key)
106 }
107 state.copy_!.delete(key)
108 return true
109 }
110
111 p.clear = function() {
112 const state: MapState = this[DRAFT_STATE]
113 assertUnrevoked(state)
114 if (latest(state).size) {
115 prepareMapCopy(state)
116 markChanged(state)
117 state.assigned_ = new Map()
118 each(state.base_, key => {
119 state.assigned_!.set(key, false)
120 })
121 state.copy_!.clear()
122 }
123 }
124
125 p.forEach = function(
126 cb: (value: any, key: any, self: any) => void,
127 thisArg?: any
128 ) {
129 const state: MapState = this[DRAFT_STATE]
130 latest(state).forEach((_value: any, key: any, _map: any) => {
131 cb.call(thisArg, this.get(key), key, this)
132 })
133 }
134
135 p.get = function(key: any): any {
136 const state: MapState = this[DRAFT_STATE]
137 assertUnrevoked(state)
138 const value = latest(state).get(key)
139 if (state.finalized_ || !isDraftable(value)) {
140 return value
141 }
142 if (value !== state.base_.get(key)) {
143 return value // either already drafted or reassigned
144 }
145 // despite what it looks, this creates a draft only once, see above condition
146 const draft = createProxy(state.scope_.immer_, value, state)
147 prepareMapCopy(state)
148 state.copy_!.set(key, draft)
149 return draft
150 }
151
152 p.keys = function(): IterableIterator<any> {
153 return latest(this[DRAFT_STATE]).keys()
154 }
155
156 p.values = function(): IterableIterator<any> {
157 const iterator = this.keys()
158 return {
159 [iteratorSymbol]: () => this.values(),
160 next: () => {
161 const r = iterator.next()
162 /* istanbul ignore next */
163 if (r.done) return r
164 const value = this.get(r.value)
165 return {
166 done: false,
167 value
168 }
169 }
170 } as any
171 }
172
173 p.entries = function(): IterableIterator<[any, any]> {
174 const iterator = this.keys()
175 return {
176 [iteratorSymbol]: () => this.entries(),
177 next: () => {
178 const r = iterator.next()
179 /* istanbul ignore next */
180 if (r.done) return r
181 const value = this.get(r.value)
182 return {
183 done: false,
184 value: [r.value, value]
185 }
186 }
187 } as any
188 }
189
190 p[iteratorSymbol] = function() {
191 return this.entries()
192 }
193
194 return DraftMap
195 })(Map)
196
197 function proxyMap_<T extends AnyMap>(target: T, parent?: ImmerState): T {
198 // @ts-ignore
199 return new DraftMap(target, parent)
200 }
201
202 function prepareMapCopy(state: MapState) {
203 if (!state.copy_) {
204 state.assigned_ = new Map()
205 state.copy_ = new Map(state.base_)
206 }
207 }
208
209 const DraftSet = (function(_super) {
210 __extends(DraftSet, _super)
211 // Create class manually, cause #502
212 function DraftSet(this: any, target: AnySet, parent?: ImmerState) {
213 this[DRAFT_STATE] = {
214 type_: ProxyType.Set,
215 parent_: parent,
216 scope_: parent ? parent.scope_ : getCurrentScope()!,
217 modified_: false,
218 finalized_: false,
219 copy_: undefined,
220 base_: target,
221 draft_: this,
222 drafts_: new Map(),
223 revoked_: false,
224 isManual_: false
225 } as SetState
226 return this
227 }
228 const p = DraftSet.prototype
229
230 Object.defineProperty(p, "size", {
231 get: function() {
232 return latest(this[DRAFT_STATE]).size
233 }
234 // enumerable: true,
235 })
236
237 p.has = function(value: any): boolean {
238 const state: SetState = this[DRAFT_STATE]
239 assertUnrevoked(state)
240 // bit of trickery here, to be able to recognize both the value, and the draft of its value
241 if (!state.copy_) {
242 return state.base_.has(value)
243 }
244 if (state.copy_.has(value)) return true
245 if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value)))
246 return true
247 return false
248 }
249
250 p.add = function(value: any): any {
251 const state: SetState = this[DRAFT_STATE]
252 assertUnrevoked(state)
253 if (!this.has(value)) {
254 prepareSetCopy(state)
255 markChanged(state)
256 state.copy_!.add(value)
257 }
258 return this
259 }
260
261 p.delete = function(value: any): any {
262 if (!this.has(value)) {
263 return false
264 }
265
266 const state: SetState = this[DRAFT_STATE]
267 assertUnrevoked(state)
268 prepareSetCopy(state)
269 markChanged(state)
270 return (
271 state.copy_!.delete(value) ||
272 (state.drafts_.has(value)
273 ? state.copy_!.delete(state.drafts_.get(value))
274 : /* istanbul ignore next */ false)
275 )
276 }
277
278 p.clear = function() {
279 const state: SetState = this[DRAFT_STATE]
280 assertUnrevoked(state)
281 if (latest(state).size) {
282 prepareSetCopy(state)
283 markChanged(state)
284 state.copy_!.clear()
285 }
286 }
287
288 p.values = function(): IterableIterator<any> {
289 const state: SetState = this[DRAFT_STATE]
290 assertUnrevoked(state)
291 prepareSetCopy(state)
292 return state.copy_!.values()
293 }
294
295 p.entries = function entries(): IterableIterator<[any, any]> {
296 const state: SetState = this[DRAFT_STATE]
297 assertUnrevoked(state)
298 prepareSetCopy(state)
299 return state.copy_!.entries()
300 }
301
302 p.keys = function(): IterableIterator<any> {
303 return this.values()
304 }
305
306 p[iteratorSymbol] = function() {
307 return this.values()
308 }
309
310 p.forEach = function forEach(cb: any, thisArg?: any) {
311 const iterator = this.values()
312 let result = iterator.next()
313 while (!result.done) {
314 cb.call(thisArg, result.value, result.value, this)
315 result = iterator.next()
316 }
317 }
318
319 return DraftSet
320 })(Set)
321
322 function proxySet_<T extends AnySet>(target: T, parent?: ImmerState): T {
323 // @ts-ignore
324 return new DraftSet(target, parent)
325 }
326
327 function prepareSetCopy(state: SetState) {
328 if (!state.copy_) {
329 // create drafts for all entries to preserve insertion order
330 state.copy_ = new Set()
331 state.base_.forEach(value => {
332 if (isDraftable(value)) {
333 const draft = createProxy(state.scope_.immer_, value, state)
334 state.drafts_.set(value, draft)
335 state.copy_!.add(draft)
336 } else {
337 state.copy_!.add(value)
338 }
339 })
340 }
341 }
342
343 function assertUnrevoked(state: any /*ES5State | MapState | SetState*/) {
344 if (state.revoked_) die(3, JSON.stringify(latest(state)))
345 }
346
347 loadPlugin("MapSet", {proxyMap_, proxySet_})
348}
Note: See TracBrowser for help on using the repository browser.