mutate-cow 6.0.0 → 7.0.0
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/package.json +7 -5
- package/{CowContext.js → src/index.js} +149 -26
- package/{index.js.flow → src/index.js.flow} +62 -88
- package/{index.d.ts → types/index.d.ts} +23 -13
- package/canClone.js +0 -40
- package/clone.js +0 -99
- package/constants.js +0 -23
- package/index.js +0 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mutate-cow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Update immutable objects as if they were mutable with copy-on-write",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"immutable",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"copy on write",
|
|
9
9
|
"state management"
|
|
10
10
|
],
|
|
11
|
-
"main": "index.js",
|
|
12
|
-
"types": "index.d.ts",
|
|
11
|
+
"main": "src/index.js",
|
|
12
|
+
"types": "types/index.d.ts",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"author": "Michael Wiencek <mwtuea@gmail.com>",
|
|
15
15
|
"repository": {
|
|
@@ -18,13 +18,15 @@
|
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"benchmark": "2.1.4",
|
|
21
|
-
"flow-bin": "0.
|
|
21
|
+
"flow-bin": "0.275.0",
|
|
22
|
+
"immer": "10.1.1",
|
|
23
|
+
"mutative": "1.2.0",
|
|
22
24
|
"tsd": "0.29.0"
|
|
23
25
|
},
|
|
24
26
|
"sideEffects": false,
|
|
25
27
|
"type": "module",
|
|
26
28
|
"scripts": {
|
|
27
|
-
"test": "node --test --experimental-test-coverage"
|
|
29
|
+
"test": "node --test --experimental-test-coverage test/index.js"
|
|
28
30
|
},
|
|
29
31
|
"packageManager": "yarn@4.9.2+sha512.1fc009bc09d13cfd0e19efa44cbfc2b9cf6ca61482725eb35bbc5e257e093ebf4130db6dfe15d604ff4b79efd8e1e8e99b25fa7d0a6197c9f9826358d4d65c3c"
|
|
30
32
|
}
|
|
@@ -5,20 +5,130 @@
|
|
|
5
5
|
* in the file named "LICENSE" at the root directory of this distribution.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
STATUS_CHANGED,
|
|
11
|
-
STATUS_NONE,
|
|
12
|
-
STATUS_REVOKED,
|
|
13
|
-
} from './constants.js';
|
|
8
|
+
const NATIVE_CODE_REGEXP = /^function \w*\(\) \{\s*\[native code\]\s*\}$/m;
|
|
14
9
|
|
|
15
|
-
const
|
|
10
|
+
const STATUS_NONE = 1;
|
|
11
|
+
const STATUS_CHANGED = 2;
|
|
12
|
+
const STATUS_REVOKED = 3;
|
|
13
|
+
const STATUS_STALE = 4;
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
function isPrimitive(value) {
|
|
16
|
+
if (value === null) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
const type = typeof value;
|
|
20
|
+
return (type !== 'function' && type !== 'object');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getCloneableType(value) {
|
|
24
|
+
if (isPrimitive(value)) {
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
if (typeof value !== 'object') {
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
let proto = Object.getPrototypeOf(value);
|
|
31
|
+
while (proto) {
|
|
32
|
+
let ctor = proto.constructor;
|
|
33
|
+
// A Generator object's constructor is an object.
|
|
34
|
+
if (ctor && typeof ctor === 'object') {
|
|
35
|
+
ctor = ctor.constructor;
|
|
36
|
+
}
|
|
37
|
+
if (
|
|
38
|
+
typeof ctor === 'function' &&
|
|
39
|
+
ctor.name !== 'Array' &&
|
|
40
|
+
ctor.name !== 'Object' &&
|
|
41
|
+
NATIVE_CODE_REGEXP.test(Function.prototype.toString.call(ctor))
|
|
42
|
+
) {
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
proto = Object.getPrototypeOf(proto);
|
|
46
|
+
}
|
|
47
|
+
return 2;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function throwIfTypeNotCloneable(cloneableType) {
|
|
51
|
+
if (cloneableType === 0) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
'Only plain objects, arrays, and class instances ' +
|
|
54
|
+
'can be cloned. Primitives, functions, and built-ins ' +
|
|
55
|
+
'are unsupported.',
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function restoreDescriptors(copy, changedDescriptors) {
|
|
61
|
+
for (let i = 0; i < changedDescriptors.length; i++) {
|
|
62
|
+
const [name, origDesc] = changedDescriptors[i];
|
|
63
|
+
const descriptor = Object.getOwnPropertyDescriptor(copy, name);
|
|
64
|
+
if (descriptor) {
|
|
65
|
+
Object.assign(descriptor, origDesc);
|
|
66
|
+
Reflect.defineProperty(copy, name, descriptor);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function clone(source, callbacks) {
|
|
72
|
+
const cloneableType = getCloneableType(source);
|
|
73
|
+
throwIfTypeNotCloneable(cloneableType);
|
|
74
|
+
if (cloneableType === 1) {
|
|
75
|
+
return source;
|
|
76
|
+
}
|
|
77
|
+
const proto = Object.getPrototypeOf(source);
|
|
78
|
+
let changedDescriptors = [];
|
|
79
|
+
let copy;
|
|
80
|
+
if (Array.isArray(source)) {
|
|
81
|
+
copy = Reflect.construct(Array, source, proto.constructor);
|
|
82
|
+
} else {
|
|
83
|
+
copy = Object.create(proto);
|
|
84
|
+
}
|
|
85
|
+
const ownKeys = Reflect.ownKeys(source);
|
|
86
|
+
for (let i = 0; i < ownKeys.length; i++) {
|
|
87
|
+
const key = ownKeys[i];
|
|
88
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
89
|
+
let origDesc;
|
|
90
|
+
if (descriptor.configurable === false) {
|
|
91
|
+
descriptor.configurable = true;
|
|
92
|
+
origDesc = {configurable: false};
|
|
93
|
+
}
|
|
94
|
+
if (descriptor.writable === false) {
|
|
95
|
+
descriptor.writable = true;
|
|
96
|
+
origDesc = {...origDesc, writable: false};
|
|
97
|
+
}
|
|
98
|
+
if (origDesc) {
|
|
99
|
+
changedDescriptors.push([key, origDesc]);
|
|
100
|
+
}
|
|
101
|
+
Reflect.defineProperty(copy, key, descriptor);
|
|
102
|
+
}
|
|
103
|
+
if (changedDescriptors.length) {
|
|
104
|
+
callbacks.push({
|
|
105
|
+
func: restoreDescriptors,
|
|
106
|
+
args: [copy, changedDescriptors],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (Object.isFrozen(source)) {
|
|
110
|
+
callbacks.push({
|
|
111
|
+
func: Object.freeze,
|
|
112
|
+
args: [copy],
|
|
113
|
+
});
|
|
114
|
+
} else if (Object.isSealed(source)) {
|
|
115
|
+
callbacks.push({
|
|
116
|
+
func: Object.seal,
|
|
117
|
+
args: [copy],
|
|
118
|
+
});
|
|
119
|
+
} else if (!Object.isExtensible(source)) {
|
|
120
|
+
callbacks.push({
|
|
121
|
+
func: Object.preventExtensions,
|
|
122
|
+
args: [copy],
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return copy;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export class CowContext {
|
|
129
|
+
constructor(source, prop, parent) {
|
|
19
130
|
this._source = source;
|
|
20
131
|
this._prop = prop;
|
|
21
|
-
this._root = root || this;
|
|
22
132
|
this._parent = parent;
|
|
23
133
|
this._callbacks = [];
|
|
24
134
|
this._result = null;
|
|
@@ -52,8 +162,7 @@ export default class CowContext {
|
|
|
52
162
|
}
|
|
53
163
|
}
|
|
54
164
|
|
|
55
|
-
|
|
56
|
-
const target = this.read();
|
|
165
|
+
_getPropDescriptor(target, prop) {
|
|
57
166
|
const descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
58
167
|
if (descriptor) {
|
|
59
168
|
if (descriptor.get) {
|
|
@@ -62,22 +171,29 @@ export default class CowContext {
|
|
|
62
171
|
if (descriptor.set) {
|
|
63
172
|
throw new Error('Setters are unsupported.');
|
|
64
173
|
}
|
|
174
|
+
return descriptor;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
_getPropValue(prop) {
|
|
179
|
+
const target = this.read();
|
|
180
|
+
const descriptor = this._getPropDescriptor(target, prop);
|
|
181
|
+
if (descriptor) {
|
|
65
182
|
return descriptor.value;
|
|
66
183
|
}
|
|
67
184
|
return Reflect.get(target, prop);
|
|
68
185
|
}
|
|
69
186
|
|
|
70
187
|
_getSource() {
|
|
71
|
-
|
|
72
|
-
if (source === STALE_VALUE) {
|
|
188
|
+
if (this._status === STATUS_STALE) {
|
|
73
189
|
/*
|
|
74
190
|
* `this._parent` should always be defined here, because we only
|
|
75
|
-
* ever
|
|
191
|
+
* ever set `STATUS_STALE` onto child contexts.
|
|
76
192
|
*/
|
|
77
|
-
|
|
78
|
-
this.
|
|
193
|
+
this._source = this._parent._getPropValue(this._prop);
|
|
194
|
+
this._status = STATUS_NONE;
|
|
79
195
|
}
|
|
80
|
-
return
|
|
196
|
+
return this._source;
|
|
81
197
|
}
|
|
82
198
|
|
|
83
199
|
_throwIfRevoked() {
|
|
@@ -113,7 +229,7 @@ export default class CowContext {
|
|
|
113
229
|
return child;
|
|
114
230
|
}
|
|
115
231
|
|
|
116
|
-
child = new CowContext(value, prop, this
|
|
232
|
+
child = new CowContext(value, prop, this);
|
|
117
233
|
children.set(prop, child);
|
|
118
234
|
return child;
|
|
119
235
|
}
|
|
@@ -136,9 +252,8 @@ export default class CowContext {
|
|
|
136
252
|
}
|
|
137
253
|
|
|
138
254
|
_set(prop, newValue) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
if (!Object.is(origValue, newValue)) {
|
|
255
|
+
const descriptor = this._getPropDescriptor(this.read(), prop);
|
|
256
|
+
if (descriptor === undefined || !Object.is(descriptor.value, newValue)) {
|
|
142
257
|
this._copyForWrite();
|
|
143
258
|
this._result[prop] = newValue;
|
|
144
259
|
|
|
@@ -148,10 +263,10 @@ export default class CowContext {
|
|
|
148
263
|
if (children) {
|
|
149
264
|
const child = children.get(prop);
|
|
150
265
|
if (child) {
|
|
151
|
-
child._source =
|
|
266
|
+
child._source = null;
|
|
152
267
|
child._callbacks = [];
|
|
153
268
|
child._result = null;
|
|
154
|
-
child._status =
|
|
269
|
+
child._status = STATUS_STALE;
|
|
155
270
|
}
|
|
156
271
|
}
|
|
157
272
|
}
|
|
@@ -186,7 +301,11 @@ export default class CowContext {
|
|
|
186
301
|
|
|
187
302
|
root() {
|
|
188
303
|
this._throwIfRevoked();
|
|
189
|
-
|
|
304
|
+
let root = this;
|
|
305
|
+
while (root._parent !== null) {
|
|
306
|
+
root = root._parent;
|
|
307
|
+
}
|
|
308
|
+
return root;
|
|
190
309
|
}
|
|
191
310
|
|
|
192
311
|
revoke() {
|
|
@@ -204,7 +323,6 @@ export default class CowContext {
|
|
|
204
323
|
}
|
|
205
324
|
this._source = null;
|
|
206
325
|
this._prop = null;
|
|
207
|
-
this._root = null;
|
|
208
326
|
this._parent = null;
|
|
209
327
|
this._callbacks = null;
|
|
210
328
|
this._result = null;
|
|
@@ -236,3 +354,8 @@ export default class CowContext {
|
|
|
236
354
|
return this.root().final();
|
|
237
355
|
}
|
|
238
356
|
}
|
|
357
|
+
|
|
358
|
+
export default function mutate(source) {
|
|
359
|
+
throwIfTypeNotCloneable(getCloneableType(source));
|
|
360
|
+
return new CowContext(source, null, null);
|
|
361
|
+
}
|
|
@@ -1,54 +1,20 @@
|
|
|
1
1
|
// @flow strict
|
|
2
2
|
|
|
3
|
-
export type
|
|
4
|
-
| interface {}
|
|
5
|
-
| {__proto__: null, ...};
|
|
6
|
-
|
|
7
|
-
export type KeyType<+T: mixed> =
|
|
3
|
+
export type KeyType<+T> =
|
|
8
4
|
T extends $ReadOnlyArray<mixed> ? number :
|
|
9
|
-
T extends {__proto__: null, ...} ? $Keys<T> :
|
|
10
|
-
T extends interface {} ? $Keys<T> :
|
|
11
|
-
empty;
|
|
12
|
-
export type KeyType2<+T, +K1: KeyType<T>> =
|
|
13
|
-
PropType<T, K1> extends $ReadOnlyArray<mixed> ? number :
|
|
14
|
-
PropType<T, K1> extends {__proto__: null, ...} ? $Keys<PropType<T, K1>> :
|
|
15
|
-
PropType<T, K1> extends interface {} ? $Keys<PropType<T, K1>> :
|
|
16
|
-
empty;
|
|
17
|
-
export type KeyType3<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>> =
|
|
18
|
-
PropType2<T, K1, K2> extends $ReadOnlyArray<mixed> ? number :
|
|
19
|
-
PropType2<T, K1, K2> extends {__proto__: null, ...} ? $Keys<PropType2<T, K1, K2>> :
|
|
20
|
-
PropType2<T, K1, K2> extends interface {} ? $Keys<PropType2<T, K1, K2>> :
|
|
21
|
-
empty;
|
|
22
|
-
export type KeyType4<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>> =
|
|
23
|
-
PropType3<T, K1, K2, K3> extends $ReadOnlyArray<mixed> ? number :
|
|
24
|
-
PropType3<T, K1, K2, K3> extends {__proto__: null, ...} ? $Keys<PropType3<T, K1, K2, K3>> :
|
|
25
|
-
PropType3<T, K1, K2, K3> extends interface {} ? $Keys<PropType3<T, K1, K2, K3>> :
|
|
26
|
-
empty;
|
|
27
|
-
export type KeyType5<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>> =
|
|
28
|
-
PropType4<T, K1, K2, K3, K4> extends $ReadOnlyArray<mixed> ? number :
|
|
29
|
-
PropType4<T, K1, K2, K3, K4> extends {__proto__: null, ...} ? $Keys<PropType4<T, K1, K2, K3, K4>> :
|
|
30
|
-
PropType4<T, K1, K2, K3, K4> extends interface {} ? $Keys<PropType4<T, K1, K2, K3, K4>> :
|
|
31
|
-
empty;
|
|
32
|
-
export type KeyType6<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>, +K5: KeyType5<T, K1, K2, K3, K4>> =
|
|
33
|
-
PropType5<T, K1, K2, K3, K4, K5> extends $ReadOnlyArray<mixed> ? number :
|
|
34
|
-
PropType5<T, K1, K2, K3, K4, K5> extends {__proto__: null, ...} ? $Keys<PropType5<T, K1, K2, K3, K4, K5>> :
|
|
35
|
-
PropType5<T, K1, K2, K3, K4, K5> extends interface {} ? $Keys<PropType5<T, K1, K2, K3, K4, K5>> :
|
|
36
|
-
empty;
|
|
37
|
-
export type KeyType7<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>, +K5: KeyType5<T, K1, K2, K3, K4>, +K6: KeyType6<T, K1, K2, K3, K4, K5>> =
|
|
38
|
-
PropType6<T, K1, K2, K3, K4, K5, K6> extends $ReadOnlyArray<mixed> ? number :
|
|
39
|
-
PropType6<T, K1, K2, K3, K4, K5, K6> extends {__proto__: null, ...} ? $Keys<PropType6<T, K1, K2, K3, K4, K5, K6>> :
|
|
40
|
-
PropType6<T, K1, K2, K3, K4, K5, K6> extends interface {} ? $Keys<PropType6<T, K1, K2, K3, K4, K5, K6>> :
|
|
41
|
-
empty;
|
|
42
|
-
export type KeyType8<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>, +K5: KeyType5<T, K1, K2, K3, K4>, +K6: KeyType6<T, K1, K2, K3, K4, K5>, +K7: KeyType7<T, K1, K2, K3, K4, K5, K6>> =
|
|
43
|
-
PropType7<T, K1, K2, K3, K4, K5, K6, K7> extends $ReadOnlyArray<mixed> ? number :
|
|
44
|
-
PropType7<T, K1, K2, K3, K4, K5, K6, K7> extends {__proto__: null, ...} ? $Keys<PropType7<T, K1, K2, K3, K4, K5, K6, K7>> :
|
|
45
|
-
PropType7<T, K1, K2, K3, K4, K5, K6, K7> extends interface {} ? $Keys<PropType7<T, K1, K2, K3, K4, K5, K6, K7>> :
|
|
5
|
+
T extends ({__proto__: null, ...} | interface {}) ? $Keys<T> :
|
|
46
6
|
empty;
|
|
7
|
+
export type KeyType2<+T, +K1: KeyType<T>> = KeyType<PropType<T, K1>>;
|
|
8
|
+
export type KeyType3<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>> = KeyType<PropType2<T, K1, K2>>;
|
|
9
|
+
export type KeyType4<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>> = KeyType<PropType3<T, K1, K2, K3>>;
|
|
10
|
+
export type KeyType5<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>> = KeyType<PropType4<T, K1, K2, K3, K4>>;
|
|
11
|
+
export type KeyType6<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>, +K5: KeyType5<T, K1, K2, K3, K4>> = KeyType<PropType5<T, K1, K2, K3, K4, K5>>;
|
|
12
|
+
export type KeyType7<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>, +K5: KeyType5<T, K1, K2, K3, K4>, +K6: KeyType6<T, K1, K2, K3, K4, K5>> = KeyType<PropType6<T, K1, K2, K3, K4, K5, K6>>;
|
|
13
|
+
export type KeyType8<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>, +K3: KeyType3<T, K1, K2>, +K4: KeyType4<T, K1, K2, K3>, +K5: KeyType5<T, K1, K2, K3, K4>, +K6: KeyType6<T, K1, K2, K3, K4, K5>, +K7: KeyType7<T, K1, K2, K3, K4, K5, K6>> = KeyType<PropType7<T, K1, K2, K3, K4, K5, K6, K7>>;
|
|
47
14
|
|
|
48
|
-
export type PropType<+T
|
|
15
|
+
export type PropType<+T, +K: KeyType<T>> =
|
|
49
16
|
T extends $ReadOnlyArray<infer V> ? V :
|
|
50
|
-
T extends {__proto__: null, ...} ? T[K] :
|
|
51
|
-
T extends interface {} ? T[K] :
|
|
17
|
+
T extends ({__proto__: null, ...} | interface {}) ? T[K] :
|
|
52
18
|
empty;
|
|
53
19
|
export type PropType2<+T, +K1: KeyType<T>, +K2: KeyType2<T, K1>> =
|
|
54
20
|
PropType<PropType<T, K1>, K2>;
|
|
@@ -71,44 +37,52 @@ export type ShallowReadWrite<+T> =
|
|
|
71
37
|
T extends {...} ? {...T} :
|
|
72
38
|
T;
|
|
73
39
|
|
|
74
|
-
export type CowRootContext<+R> = CowContext<R,
|
|
40
|
+
export type CowRootContext<+R> = CowContext<R, null>;
|
|
41
|
+
|
|
42
|
+
export type CowAnyContext = CowContext<mixed, CowAnyContext | null>;
|
|
43
|
+
|
|
44
|
+
type $Get1<+T, +K1, +ThisContext> =
|
|
45
|
+
CowContext<PropType<T, K1>, ThisContext>;
|
|
46
|
+
type $Get2<+T, +K1, +K2, +ThisContext> =
|
|
47
|
+
CowContext<PropType2<T, K1, K2>, $Get1<T, K1, ThisContext>>;
|
|
48
|
+
type $Get3<+T, +K1, +K2, +K3, +ThisContext> =
|
|
49
|
+
CowContext<PropType3<T, K1, K2, K3>, $Get2<T, K1, K2, ThisContext>>;
|
|
50
|
+
type $Get4<+T, +K1, +K2, +K3, +K4, +ThisContext> =
|
|
51
|
+
CowContext<PropType4<T, K1, K2, K3, K4>, $Get3<T, K1, K2, K3, ThisContext>>;
|
|
52
|
+
type $Get5<+T, +K1, +K2, +K3, +K4, +K5, +ThisContext> =
|
|
53
|
+
CowContext<PropType5<T, K1, K2, K3, K4, K5>, $Get4<T, K1, K2, K3, K4, ThisContext>>;
|
|
54
|
+
type $Get6<+T, +K1, +K2, +K3, +K4, +K5, +K6, +ThisContext> =
|
|
55
|
+
CowContext<PropType6<T, K1, K2, K3, K4, K5, K6>, $Get5<T, K1, K2, K3, K4, K5, ThisContext>>;
|
|
56
|
+
type $Get7<+T, +K1, +K2, +K3, +K4, +K5, +K6, +K7, +ThisContext> =
|
|
57
|
+
CowContext<PropType7<T, K1, K2, K3, K4, K5, K6, K7>, $Get6<T, K1, K2, K3, K4, K5, K6, ThisContext>>;
|
|
58
|
+
type $Get8<+T, +K1, +K2, +K3, +K4, +K5, +K6, +K7, +K8, +ThisContext> =
|
|
59
|
+
CowContext<PropType8<T, K1, K2, K3, K4, K5, K6, K7, K8>, $Get7<T, K1, K2, K3, K4, K5, K6, K7, ThisContext>>;
|
|
75
60
|
|
|
76
|
-
export type
|
|
77
|
-
CowContext<
|
|
61
|
+
export type GetCowContextSource<+C> =
|
|
62
|
+
C extends CowContext<infer T, mixed>
|
|
63
|
+
? T
|
|
64
|
+
: empty;
|
|
78
65
|
|
|
79
|
-
type
|
|
80
|
-
CowContext<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
type $Get3<+T, +K1, +K2, +K3, +R, +ThisContext> =
|
|
84
|
-
CowContext<PropType3<T, K1, K2, K3>, R, $Get2<T, K1, K2, R, ThisContext>>;
|
|
85
|
-
type $Get4<+T, +K1, +K2, +K3, +K4, +R, +ThisContext> =
|
|
86
|
-
CowContext<PropType4<T, K1, K2, K3, K4>, R, $Get3<T, K1, K2, K3, R, ThisContext>>;
|
|
87
|
-
type $Get5<+T, +K1, +K2, +K3, +K4, +K5, +R, +ThisContext> =
|
|
88
|
-
CowContext<PropType5<T, K1, K2, K3, K4, K5>, R, $Get4<T, K1, K2, K3, K4, R, ThisContext>>;
|
|
89
|
-
type $Get6<+T, +K1, +K2, +K3, +K4, +K5, +K6, +R, +ThisContext> =
|
|
90
|
-
CowContext<PropType6<T, K1, K2, K3, K4, K5, K6>, R, $Get5<T, K1, K2, K3, K4, K5, R, ThisContext>>;
|
|
91
|
-
type $Get7<+T, +K1, +K2, +K3, +K4, +K5, +K6, +K7, +R, +ThisContext> =
|
|
92
|
-
CowContext<PropType7<T, K1, K2, K3, K4, K5, K6, K7>, R, $Get6<T, K1, K2, K3, K4, K5, K6, R, ThisContext>>;
|
|
93
|
-
type $Get8<+T, +K1, +K2, +K3, +K4, +K5, +K6, +K7, +K8, +R, +ThisContext> =
|
|
94
|
-
CowContext<PropType8<T, K1, K2, K3, K4, K5, K6, K7, K8>, R, $Get7<T, K1, K2, K3, K4, K5, K6, K7, R, ThisContext>>;
|
|
66
|
+
export type GetCowContextRoot<+C> =
|
|
67
|
+
C extends CowContext<infer T, infer P>
|
|
68
|
+
? (P extends null ? C : GetCowContextRoot<P>)
|
|
69
|
+
: empty;
|
|
95
70
|
|
|
96
|
-
declare
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
> {
|
|
71
|
+
declare class CowContext<
|
|
72
|
+
+T,
|
|
73
|
+
+ParentContext: CowAnyContext | null = CowAnyContext | null,
|
|
74
|
+
>{
|
|
101
75
|
read(): T;
|
|
102
76
|
write(): ShallowReadWrite<T>;
|
|
103
77
|
get(): this;
|
|
104
|
-
get<const K1: KeyType<T>>(prop1: K1): $Get1<T, K1,
|
|
105
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>>(prop1: K1, prop2: K2): $Get2<T, K1, K2,
|
|
106
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>>(prop1: K1, prop2: K2, prop3: K3): $Get3<T, K1, K2, K3,
|
|
107
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4): $Get4<T, K1, K2, K3, K4,
|
|
108
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5): $Get5<T, K1, K2, K3, K4, K5,
|
|
109
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6): $Get6<T, K1, K2, K3, K4, K5, K6,
|
|
110
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7): $Get7<T, K1, K2, K3, K4, K5, K6, K7,
|
|
111
|
-
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>, const K8: KeyType8<T, K1, K2, K3, K4, K5, K6, K7>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, prop8: K8): $Get8<T, K1, K2, K3, K4, K5, K6, K7, K8,
|
|
78
|
+
get<const K1: KeyType<T>>(prop1: K1): $Get1<T, K1, this>;
|
|
79
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>>(prop1: K1, prop2: K2): $Get2<T, K1, K2, this>;
|
|
80
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>>(prop1: K1, prop2: K2, prop3: K3): $Get3<T, K1, K2, K3, this>;
|
|
81
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4): $Get4<T, K1, K2, K3, K4, this>;
|
|
82
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5): $Get5<T, K1, K2, K3, K4, K5, this>;
|
|
83
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6): $Get6<T, K1, K2, K3, K4, K5, K6, this>;
|
|
84
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7): $Get7<T, K1, K2, K3, K4, K5, K6, K7, this>;
|
|
85
|
+
get<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>, const K8: KeyType8<T, K1, K2, K3, K4, K5, K6, K7>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, prop8: K8): $Get8<T, K1, K2, K3, K4, K5, K6, K7, K8, this>;
|
|
112
86
|
set(newValue: T): this;
|
|
113
87
|
set<const K1: KeyType<T>>(prop1: K1, newValue: PropType<T, K1>): this;
|
|
114
88
|
set<const K1: KeyType<T>, const K2: KeyType2<T, K1>>(prop1: K1, prop2: K2, newValue: PropType2<T, K1, K2>): this;
|
|
@@ -119,22 +93,22 @@ declare export class CowContext<
|
|
|
119
93
|
set<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, newValue: PropType7<T, K1, K2, K3, K4, K5, K6, K7>): this;
|
|
120
94
|
set<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>, const K8: KeyType8<T, K1, K2, K3, K4, K5, K6, K7>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, prop8: K8, newValue: PropType8<T, K1, K2, K3, K4, K5, K6, K7, K8>): this;
|
|
121
95
|
update(updater: (this) => mixed): this;
|
|
122
|
-
update<const K1: KeyType<T>>(prop1: K1, updater: ($Get1<T, K1,
|
|
123
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>>(prop1: K1, prop2: K2, updater: ($Get2<T, K1, K2,
|
|
124
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>>(prop1: K1, prop2: K2, prop3: K3, updater: ($Get3<T, K1, K2, K3,
|
|
125
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, updater: ($Get4<T, K1, K2, K3, K4,
|
|
126
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, updater: ($Get5<T, K1, K2, K3, K4, K5,
|
|
127
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, updater: ($Get6<T, K1, K2, K3, K4, K5, K6,
|
|
128
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, updater: ($Get7<T, K1, K2, K3, K4, K5, K6, K7,
|
|
129
|
-
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>, const K8: KeyType8<T, K1, K2, K3, K4, K5, K6, K7>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, prop8: K8, updater: ($Get8<T, K1, K2, K3, K4, K5, K6, K7, K8,
|
|
96
|
+
update<const K1: KeyType<T>>(prop1: K1, updater: ($Get1<T, K1, this>) => mixed): this;
|
|
97
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>>(prop1: K1, prop2: K2, updater: ($Get2<T, K1, K2, this>) => mixed): this;
|
|
98
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>>(prop1: K1, prop2: K2, prop3: K3, updater: ($Get3<T, K1, K2, K3, this>) => mixed): this;
|
|
99
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, updater: ($Get4<T, K1, K2, K3, K4, this>) => mixed): this;
|
|
100
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, updater: ($Get5<T, K1, K2, K3, K4, K5, this>) => mixed): this;
|
|
101
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, updater: ($Get6<T, K1, K2, K3, K4, K5, K6, this>) => mixed): this;
|
|
102
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, updater: ($Get7<T, K1, K2, K3, K4, K5, K6, K7, this>) => mixed): this;
|
|
103
|
+
update<const K1: KeyType<T>, const K2: KeyType2<T, K1>, const K3: KeyType3<T, K1, K2>, const K4: KeyType4<T, K1, K2, K3>, const K5: KeyType5<T, K1, K2, K3, K4>, const K6: KeyType6<T, K1, K2, K3, K4, K5>, const K7: KeyType7<T, K1, K2, K3, K4, K5, K6>, const K8: KeyType8<T, K1, K2, K3, K4, K5, K6, K7>>(prop1: K1, prop2: K2, prop3: K3, prop4: K4, prop5: K5, prop6: K6, prop7: K7, prop8: K8, updater: ($Get8<T, K1, K2, K3, K4, K5, K6, K7, K8, this>) => mixed): this;
|
|
130
104
|
parent(): ParentContext;
|
|
131
|
-
root():
|
|
105
|
+
root(): GetCowContextRoot<this>;
|
|
132
106
|
revoke(): void;
|
|
133
107
|
isRevoked(): boolean;
|
|
134
108
|
final(): T;
|
|
135
|
-
finalRoot():
|
|
109
|
+
finalRoot(): GetCowContextSource<GetCowContextRoot<this>>;
|
|
136
110
|
}
|
|
137
111
|
|
|
138
|
-
declare export default function mutate<T
|
|
112
|
+
declare export default function mutate<T>(
|
|
139
113
|
source: T,
|
|
140
114
|
): CowRootContext<T>;
|
|
@@ -7,43 +7,53 @@ type NestedProp<T, Path extends ReadonlyArray<PropertyKey>> =
|
|
|
7
7
|
)
|
|
8
8
|
: T;
|
|
9
9
|
|
|
10
|
-
type NestedContext<T,
|
|
10
|
+
type NestedContext<T, ParentContext extends CowAnyContext | null, Path extends ReadonlyArray<PropertyKey>> =
|
|
11
11
|
Path extends [infer First, ...infer Rest]
|
|
12
12
|
? (
|
|
13
13
|
First extends keyof T
|
|
14
|
-
? NestedContext<T[First],
|
|
14
|
+
? NestedContext<T[First], CowContext<T, ParentContext>, Extract<Rest, ReadonlyArray<PropertyKey>>>
|
|
15
15
|
: never
|
|
16
16
|
)
|
|
17
|
-
: CowContext<T,
|
|
17
|
+
: CowContext<T, ParentContext>;
|
|
18
18
|
|
|
19
19
|
type ShallowReadWrite<T> =
|
|
20
20
|
T extends ReadonlyArray<infer V> ? Array<V> :
|
|
21
21
|
T extends object ? {-readonly [K in keyof T]: T[K]} : never;
|
|
22
22
|
|
|
23
|
-
type CowRootContext<R
|
|
23
|
+
type CowRootContext<R> = CowContext<R, null>;
|
|
24
24
|
|
|
25
|
-
type CowAnyContext
|
|
26
|
-
CowContext<unknown,
|
|
25
|
+
type CowAnyContext =
|
|
26
|
+
CowContext<unknown, CowAnyContext | null>;
|
|
27
|
+
|
|
28
|
+
type GetCowContextSource<C> =
|
|
29
|
+
C extends CowContext<infer T, CowAnyContext | null>
|
|
30
|
+
? T
|
|
31
|
+
: never;
|
|
32
|
+
|
|
33
|
+
type GetCowContextRoot<C> =
|
|
34
|
+
C extends CowContext<infer T, infer P>
|
|
35
|
+
? (P extends null ? C : GetCowContextRoot<P>)
|
|
36
|
+
: never;
|
|
27
37
|
|
|
28
38
|
declare class CowContext<
|
|
29
39
|
out T,
|
|
30
|
-
|
|
31
|
-
out ParentContext extends CowAnyContext
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
out ParentContext extends CowAnyContext | null = CowAnyContext | null,
|
|
32
42
|
> {
|
|
33
43
|
read(): T;
|
|
34
44
|
write(): ShallowReadWrite<T>;
|
|
35
|
-
get<Path extends ReadonlyArray<PropertyKey>>(...path: Path): NestedContext<T,
|
|
45
|
+
get<Path extends ReadonlyArray<PropertyKey>>(...path: Path): NestedContext<T, ParentContext, Path>;
|
|
36
46
|
set<Path extends ReadonlyArray<PropertyKey>>(...args: [...Path, NestedProp<T, Path>]): this;
|
|
37
|
-
update<Path extends ReadonlyArray<PropertyKey>>(...args: [...Path, (childContext: NestedContext<T,
|
|
47
|
+
update<Path extends ReadonlyArray<PropertyKey>>(...args: [...Path, (childContext: NestedContext<T, ParentContext, Path>) => unknown]): this;
|
|
38
48
|
parent(): ParentContext;
|
|
39
|
-
root():
|
|
49
|
+
root(): GetCowContextRoot<this>;
|
|
40
50
|
revoke(): void;
|
|
41
51
|
isRevoked(): boolean;
|
|
42
52
|
final(): T;
|
|
43
|
-
finalRoot():
|
|
53
|
+
finalRoot(): GetCowContextSource<GetCowContextRoot<this>>;
|
|
44
54
|
}
|
|
45
55
|
|
|
46
|
-
declare function mutate<T
|
|
56
|
+
declare function mutate<T>(
|
|
47
57
|
source: T,
|
|
48
58
|
): CowRootContext<T>;
|
|
49
59
|
|
package/canClone.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023 Michael Wiencek
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license. A copy can be found
|
|
5
|
-
* in the file named "LICENSE" at the root directory of this distribution.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const funcToString = Function.prototype.toString;
|
|
9
|
-
|
|
10
|
-
const nativeCodeRegExp = /^function \w*\(\) \{\s*\[native code\]\s*\}$/m;
|
|
11
|
-
|
|
12
|
-
export const CANNOT_CLONE_ERROR =
|
|
13
|
-
'Only plain objects, arrays, and class instances ' +
|
|
14
|
-
'can be cloned. Primitives, functions, and built-ins ' +
|
|
15
|
-
'are unsupported.';
|
|
16
|
-
|
|
17
|
-
export default function canClone(object) {
|
|
18
|
-
if (!object || typeof object !== 'object') {
|
|
19
|
-
throw new Error(CANNOT_CLONE_ERROR);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let proto = Reflect.getPrototypeOf(object);
|
|
23
|
-
|
|
24
|
-
while (proto) {
|
|
25
|
-
let ctor = proto.constructor;
|
|
26
|
-
// A Generator object's constructor is an object.
|
|
27
|
-
if (ctor && typeof ctor === 'object') {
|
|
28
|
-
ctor = ctor.constructor;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (typeof ctor === 'function' &&
|
|
32
|
-
ctor.name !== 'Array' &&
|
|
33
|
-
ctor.name !== 'Object' &&
|
|
34
|
-
nativeCodeRegExp.test(funcToString.call(ctor))) {
|
|
35
|
-
throw new Error(CANNOT_CLONE_ERROR);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
proto = Reflect.getPrototypeOf(proto);
|
|
39
|
-
}
|
|
40
|
-
}
|
package/clone.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023 Michael Wiencek
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license. A copy can be found
|
|
5
|
-
* in the file named "LICENSE" at the root directory of this distribution.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import canClone from './canClone.js';
|
|
9
|
-
import {
|
|
10
|
-
NON_CONFIGURABLE,
|
|
11
|
-
NON_CONFIGURABLE_AND_WRITABLE,
|
|
12
|
-
NON_WRITABLE,
|
|
13
|
-
} from './constants.js';
|
|
14
|
-
|
|
15
|
-
function isPrimitive(value) {
|
|
16
|
-
switch (typeof value) {
|
|
17
|
-
case 'bigint':
|
|
18
|
-
case 'boolean':
|
|
19
|
-
case 'number':
|
|
20
|
-
case 'string':
|
|
21
|
-
case 'symbol':
|
|
22
|
-
case 'undefined':
|
|
23
|
-
return true;
|
|
24
|
-
default:
|
|
25
|
-
return value === null;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function restoreDescriptors(copy, changedDescriptors) {
|
|
30
|
-
for (let i = 0; i < changedDescriptors.length; i++) {
|
|
31
|
-
const [name, origDesc] = changedDescriptors[i];
|
|
32
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(copy, name);
|
|
33
|
-
if (descriptor) {
|
|
34
|
-
Object.assign(descriptor, origDesc);
|
|
35
|
-
Reflect.defineProperty(copy, name, descriptor);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default function clone(source, callbacks) {
|
|
41
|
-
if (isPrimitive(source)) {
|
|
42
|
-
return source;
|
|
43
|
-
}
|
|
44
|
-
canClone(source);
|
|
45
|
-
let changedDescriptors;
|
|
46
|
-
let copy;
|
|
47
|
-
if (Array.isArray(source)) {
|
|
48
|
-
copy = new Array(source.length);
|
|
49
|
-
} else {
|
|
50
|
-
copy = Object.create(Reflect.getPrototypeOf(source));
|
|
51
|
-
}
|
|
52
|
-
const ownNames = Object.getOwnPropertyNames(source);
|
|
53
|
-
for (let i = 0; i < ownNames.length; i++) {
|
|
54
|
-
const name = ownNames[i];
|
|
55
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(source, name);
|
|
56
|
-
const nonConfigurable = descriptor.configurable === false;
|
|
57
|
-
let origDesc;
|
|
58
|
-
if (nonConfigurable) {
|
|
59
|
-
descriptor.configurable = true;
|
|
60
|
-
origDesc = NON_CONFIGURABLE;
|
|
61
|
-
}
|
|
62
|
-
if (descriptor.writable === false) {
|
|
63
|
-
descriptor.writable = true;
|
|
64
|
-
origDesc = nonConfigurable
|
|
65
|
-
? NON_CONFIGURABLE_AND_WRITABLE
|
|
66
|
-
: NON_WRITABLE;
|
|
67
|
-
}
|
|
68
|
-
if (origDesc) {
|
|
69
|
-
if (!changedDescriptors) {
|
|
70
|
-
changedDescriptors = [];
|
|
71
|
-
}
|
|
72
|
-
changedDescriptors.push([name, origDesc]);
|
|
73
|
-
}
|
|
74
|
-
Reflect.defineProperty(copy, name, descriptor);
|
|
75
|
-
}
|
|
76
|
-
if (changedDescriptors) {
|
|
77
|
-
callbacks.push({
|
|
78
|
-
func: restoreDescriptors,
|
|
79
|
-
args: [copy, changedDescriptors],
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
if (Object.isFrozen(source)) {
|
|
83
|
-
callbacks.push({
|
|
84
|
-
func: Object.freeze,
|
|
85
|
-
args: [copy],
|
|
86
|
-
});
|
|
87
|
-
} else if (Object.isSealed(source)) {
|
|
88
|
-
callbacks.push({
|
|
89
|
-
func: Object.seal,
|
|
90
|
-
args: [copy],
|
|
91
|
-
});
|
|
92
|
-
} else if (!Reflect.isExtensible(source)) {
|
|
93
|
-
callbacks.push({
|
|
94
|
-
func: Reflect.preventExtensions,
|
|
95
|
-
args: [copy],
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
return copy;
|
|
99
|
-
}
|
package/constants.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export const NON_CONFIGURABLE =
|
|
2
|
-
Object.freeze({configurable: false});
|
|
3
|
-
|
|
4
|
-
export const NON_WRITABLE =
|
|
5
|
-
Object.freeze({writable: false});
|
|
6
|
-
|
|
7
|
-
export const NON_CONFIGURABLE_AND_WRITABLE =
|
|
8
|
-
Object.freeze({
|
|
9
|
-
configurable: false,
|
|
10
|
-
writable: false,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
export const CONFIGURABLE_AND_WRITABLE =
|
|
14
|
-
Object.freeze({
|
|
15
|
-
configurable: true,
|
|
16
|
-
writable: true,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
export const STATUS_NONE = 1;
|
|
20
|
-
|
|
21
|
-
export const STATUS_CHANGED = 2;
|
|
22
|
-
|
|
23
|
-
export const STATUS_REVOKED = 3;
|
package/index.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023 Michael Wiencek
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license. A copy can be found
|
|
5
|
-
* in the file named "LICENSE" at the root directory of this distribution.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import canClone from './canClone.js';
|
|
9
|
-
import CowContext from './CowContext.js';
|
|
10
|
-
|
|
11
|
-
export default function mutate(source) {
|
|
12
|
-
canClone(source);
|
|
13
|
-
return new CowContext(source, null, null, null);
|
|
14
|
-
}
|