tspo 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # tspo ✈️
1
+ # 🟦 tspo
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/tspo?label=npm&color=0ea5e9)](https://www.npmjs.com/package/tspo)
4
4
  [![downloads](https://img.shields.io/npm/dm/tspo?label=downloads&color=38bdf8)](https://www.npmjs.com/package/tspo)
@@ -6,4 +6,10 @@
6
6
  [![bundle size](https://img.shields.io/bundlephobia/minzip/tspo?label=bundle&color=0f172a)](https://bundlephobia.com/package/tspo)
7
7
  [![license](https://img.shields.io/npm/l/tspo?label=license&color=334155)](LICENSE)
8
8
 
9
+ > `tspo (TypeScript Plain Object)` is a collection of utilities for handling both runtime and compile-time behavior for plain-objects.
10
+
11
+ <p align="center">
12
+ <img src="https://raw.githubusercontent.com/seanpmaxwell/tspo/master/screenshot.png" alt="tspo screenshot" />
13
+ </p>
14
+
9
15
  Please refer to the official <a href="https://github.com/seanpmaxwell/tspo">github repo</a> for the most up-to-date documentation.
package/dist/cjs/tspo.js CHANGED
@@ -2,20 +2,43 @@ import isPlainObject, {} from './isPlainObject.js';
2
2
  import compare from './utils/compare.js';
3
3
  import copy from './utils/copy.js';
4
4
  import iterate from './utils/iterate.js';
5
+ const hop = Object.prototype.hasOwnProperty;
5
6
  function omit(obj, keys) {
6
- const retVal = {}, set = new Set(Array.isArray(keys) ? keys : [keys]);
7
+ const retVal = {};
8
+ const dict = obj;
9
+ if (Array.isArray(keys)) {
10
+ const set = new Set(keys);
11
+ for (const key in obj) {
12
+ if (!set.has(key)) {
13
+ retVal[key] = dict[key];
14
+ }
15
+ }
16
+ return retVal;
17
+ }
18
+ const omittedKey = keys;
7
19
  for (const key in obj) {
8
- if (!set.has(key)) {
9
- retVal[key] = obj[key];
20
+ if (key !== omittedKey) {
21
+ retVal[key] = dict[key];
10
22
  }
11
23
  }
12
24
  return retVal;
13
25
  }
14
26
  function pick(obj, keys) {
15
- const retVal = {}, set = new Set(Array.isArray(keys) ? keys : [keys]);
27
+ const retVal = {};
28
+ const dict = obj;
29
+ if (Array.isArray(keys)) {
30
+ const set = new Set(keys);
31
+ for (const key in obj) {
32
+ if (set.has(key)) {
33
+ retVal[key] = dict[key];
34
+ }
35
+ }
36
+ return retVal;
37
+ }
38
+ const pickedKey = keys;
16
39
  for (const key in obj) {
17
- if (set.has(key)) {
18
- retVal[key] = obj[key];
40
+ if (key === pickedKey) {
41
+ retVal[key] = dict[key];
19
42
  }
20
43
  }
21
44
  return retVal;
@@ -61,17 +84,23 @@ function reverseIndex(obj, value) {
61
84
  return retVal;
62
85
  }
63
86
  function safeReverseIndex(obj, value) {
64
- const retVal = [];
87
+ let found = false;
88
+ let retVal;
65
89
  for (const key in obj) {
66
90
  if (obj[key] === value) {
67
- retVal.push(key);
91
+ if (found) {
92
+ throw new Error('.safeReverseIndex found 0 or more than 1 keys for value: ' +
93
+ String(value));
94
+ }
95
+ found = true;
96
+ retVal = key;
68
97
  }
69
98
  }
70
- if (retVal.length !== 1) {
99
+ if (!found) {
71
100
  throw new Error('.safeReverseIndex found 0 or more than 1 keys for value: ' +
72
101
  String(value));
73
102
  }
74
- return retVal[0];
103
+ return retVal;
75
104
  }
76
105
  function isKey(obj, arg) {
77
106
  const keyArr = Array.isArray(arg) ? arg : [arg];
@@ -82,9 +111,23 @@ function isKey(obj, arg) {
82
111
  return true;
83
112
  }
84
113
  function isValue(obj, arg) {
85
- const valArr = Array.isArray(arg) ? arg : [arg], valSet = new Set(Object.values(obj));
86
- for (const val of valArr) {
87
- if (!valSet.has(val))
114
+ const dict = obj;
115
+ if (!Array.isArray(arg)) {
116
+ for (const key in obj) {
117
+ if (hop.call(obj, key) && sameValueZero(dict[key], arg))
118
+ return true;
119
+ }
120
+ return false;
121
+ }
122
+ for (const val of arg) {
123
+ let found = false;
124
+ for (const key in obj) {
125
+ if (hop.call(obj, key) && sameValueZero(dict[key], val)) {
126
+ found = true;
127
+ break;
128
+ }
129
+ }
130
+ if (!found)
88
131
  return false;
89
132
  }
90
133
  return true;
@@ -99,7 +142,16 @@ function entries(obj) {
99
142
  return Object.entries(obj);
100
143
  }
101
144
  function firstEntry(obj) {
102
- return Object.entries(obj)[0];
145
+ const dict = obj;
146
+ for (const key in obj) {
147
+ if (hop.call(obj, key)) {
148
+ return [key, dict[key]];
149
+ }
150
+ }
151
+ return undefined;
152
+ }
153
+ function sameValueZero(a, b) {
154
+ return a === b || (a !== a && b !== b);
103
155
  }
104
156
  function toDict(obj) {
105
157
  if (!isPlainObject(obj)) {
@@ -7,16 +7,22 @@ function compare(a, b) {
7
7
  return comparePlainObjects(a, b);
8
8
  }
9
9
  function comparePlainObjects(a, b) {
10
- const aKeys = Object.keys(a), bKeys = Object.keys(b);
11
- if (aKeys.length !== bKeys.length)
12
- return false;
13
- for (const key of aKeys) {
10
+ let aSize = 0;
11
+ for (const key in a) {
12
+ if (!hop.call(a, key))
13
+ continue;
14
+ aSize++;
14
15
  if (!hop.call(b, key))
15
16
  return false;
16
17
  if (!compareValue(a[key], b[key]))
17
18
  return false;
18
19
  }
19
- return true;
20
+ let bSize = 0;
21
+ for (const key in b) {
22
+ if (hop.call(b, key))
23
+ bSize++;
24
+ }
25
+ return aSize === bSize;
20
26
  }
21
27
  function compareValue(a, b) {
22
28
  if (Object.is(a, b))
@@ -1,28 +1,28 @@
1
1
  import isPlainObject, {} from '../isPlainObject.js';
2
- import {} from '../utility-types.js';
3
2
  const hop = Object.prototype.hasOwnProperty;
4
3
  function copy(value, options) {
5
4
  if (!isPlainObject(value)) {
6
5
  throw new TypeError('copy only accepts a plain-object as the root value');
7
6
  }
8
7
  const resetDates = options?.resetDates === true;
9
- return clonePlainObject(value, Object.getPrototypeOf(value), resetDates);
8
+ const deepCloneAll = options?.deepCloneAll === true;
9
+ return clonePlainObject(value, Object.getPrototypeOf(value), resetDates, deepCloneAll);
10
10
  }
11
- function clonePlainObject(source, proto, resetDates) {
11
+ function clonePlainObject(source, proto, resetDates, deepCloneAll) {
12
12
  const out = proto === null ? Object.create(null) : {};
13
13
  for (const key in source) {
14
14
  if (!hop.call(source, key))
15
15
  continue;
16
- out[key] = cloneValue(source[key], resetDates);
16
+ out[key] = cloneValue(source[key], resetDates, deepCloneAll);
17
17
  }
18
18
  return out;
19
19
  }
20
- function cloneValue(value, resetDates) {
20
+ function cloneValue(value, resetDates, deepCloneAll) {
21
21
  if (isPlainObject(value)) {
22
- return clonePlainObject(value, Object.getPrototypeOf(value), resetDates);
22
+ return clonePlainObject(value, Object.getPrototypeOf(value), resetDates, deepCloneAll);
23
23
  }
24
24
  if (Array.isArray(value)) {
25
- return cloneArray(value, resetDates);
25
+ return cloneArray(value, resetDates, deepCloneAll);
26
26
  }
27
27
  if (value instanceof Date) {
28
28
  if (resetDates) {
@@ -31,15 +31,18 @@ function cloneValue(value, resetDates) {
31
31
  return new Date(value.getTime());
32
32
  }
33
33
  if (typeof value === 'object' && value !== null) {
34
+ if (deepCloneAll) {
35
+ return cloneNonPlainDeep(value, resetDates);
36
+ }
34
37
  return cloneNonPlainShallow(value);
35
38
  }
36
39
  return value;
37
40
  }
38
- function cloneArray(source, resetDates) {
41
+ function cloneArray(source, resetDates, deepCloneAll) {
39
42
  const len = source.length;
40
43
  const out = new Array(len);
41
44
  for (let i = 0; i < len; i++) {
42
- out[i] = cloneValue(source[i], resetDates);
45
+ out[i] = cloneValue(source[i], resetDates, deepCloneAll);
43
46
  }
44
47
  return out;
45
48
  }
@@ -72,4 +75,44 @@ function cloneNonPlainShallow(value) {
72
75
  }
73
76
  return out;
74
77
  }
78
+ function cloneNonPlainDeep(value, resetDates) {
79
+ if (value instanceof RegExp) {
80
+ const re = new RegExp(value.source, value.flags);
81
+ re.lastIndex = value.lastIndex;
82
+ return re;
83
+ }
84
+ if (value instanceof Map) {
85
+ const out = new Map();
86
+ for (const [key, val] of value) {
87
+ out.set(cloneValue(key, resetDates, true), cloneValue(val, resetDates, true));
88
+ }
89
+ return out;
90
+ }
91
+ if (value instanceof Set) {
92
+ const out = new Set();
93
+ for (const entry of value) {
94
+ out.add(cloneValue(entry, resetDates, true));
95
+ }
96
+ return out;
97
+ }
98
+ if (ArrayBuffer.isView(value)) {
99
+ const anyVal = value;
100
+ if (typeof anyVal.slice === 'function')
101
+ return anyVal.slice();
102
+ if (value instanceof DataView) {
103
+ return new DataView(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
104
+ }
105
+ return new anyVal.constructor(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
106
+ }
107
+ if (value instanceof ArrayBuffer)
108
+ return value.slice(0);
109
+ const proto = Object.getPrototypeOf(value);
110
+ const out = Object.create(proto);
111
+ for (const key in value) {
112
+ if (!hop.call(value, key))
113
+ continue;
114
+ out[key] = cloneValue(value[key], resetDates, true);
115
+ }
116
+ return out;
117
+ }
75
118
  export default copy;
@@ -1,4 +1,5 @@
1
1
  import isPlainObject, {} from '../isPlainObject.js';
2
+ const hop = Object.prototype.hasOwnProperty;
2
3
  function iterate(root, cb) {
3
4
  if (!isPlainObject(root))
4
5
  return;
@@ -6,25 +7,31 @@ function iterate(root, cb) {
6
7
  }
7
8
  function iterateHelper(node, path, cb) {
8
9
  if (Array.isArray(node)) {
9
- let i = 0;
10
- for (const [key, value] of node.entries()) {
10
+ for (let i = 0; i < node.length; i++) {
11
+ const value = node[i];
12
+ cb({ parent: node, key: i, value, path: copyPath(path) });
11
13
  if (isPlainObject(value) || Array.isArray(value)) {
12
- iterateHelper(value, [...path, key, i], cb);
14
+ path.push(i);
15
+ iterateHelper(value, path, cb);
16
+ path.pop();
13
17
  }
14
- else {
15
- cb({ parent: node, key, value, path });
16
- }
17
- i++;
18
18
  }
19
19
  return;
20
20
  }
21
- for (const [key, value] of Object.entries(node)) {
21
+ const dict = node;
22
+ for (const key in dict) {
23
+ if (!hop.call(dict, key))
24
+ continue;
25
+ const value = dict[key];
26
+ cb({ parent: dict, key, value, path: copyPath(path) });
22
27
  if (isPlainObject(value) || Array.isArray(value)) {
23
- iterateHelper(value, [...path, key], cb);
24
- }
25
- else {
26
- cb({ parent: node, key, value, path });
28
+ path.push(key);
29
+ iterateHelper(value, path, cb);
30
+ path.pop();
27
31
  }
28
32
  }
29
33
  }
34
+ function copyPath(path) {
35
+ return path.slice();
36
+ }
30
37
  export default iterate;
package/dist/esm/tspo.js CHANGED
@@ -2,20 +2,43 @@ import isPlainObject, {} from './isPlainObject.js';
2
2
  import compare from './utils/compare.js';
3
3
  import copy from './utils/copy.js';
4
4
  import iterate from './utils/iterate.js';
5
+ const hop = Object.prototype.hasOwnProperty;
5
6
  function omit(obj, keys) {
6
- const retVal = {}, set = new Set(Array.isArray(keys) ? keys : [keys]);
7
+ const retVal = {};
8
+ const dict = obj;
9
+ if (Array.isArray(keys)) {
10
+ const set = new Set(keys);
11
+ for (const key in obj) {
12
+ if (!set.has(key)) {
13
+ retVal[key] = dict[key];
14
+ }
15
+ }
16
+ return retVal;
17
+ }
18
+ const omittedKey = keys;
7
19
  for (const key in obj) {
8
- if (!set.has(key)) {
9
- retVal[key] = obj[key];
20
+ if (key !== omittedKey) {
21
+ retVal[key] = dict[key];
10
22
  }
11
23
  }
12
24
  return retVal;
13
25
  }
14
26
  function pick(obj, keys) {
15
- const retVal = {}, set = new Set(Array.isArray(keys) ? keys : [keys]);
27
+ const retVal = {};
28
+ const dict = obj;
29
+ if (Array.isArray(keys)) {
30
+ const set = new Set(keys);
31
+ for (const key in obj) {
32
+ if (set.has(key)) {
33
+ retVal[key] = dict[key];
34
+ }
35
+ }
36
+ return retVal;
37
+ }
38
+ const pickedKey = keys;
16
39
  for (const key in obj) {
17
- if (set.has(key)) {
18
- retVal[key] = obj[key];
40
+ if (key === pickedKey) {
41
+ retVal[key] = dict[key];
19
42
  }
20
43
  }
21
44
  return retVal;
@@ -61,17 +84,23 @@ function reverseIndex(obj, value) {
61
84
  return retVal;
62
85
  }
63
86
  function safeReverseIndex(obj, value) {
64
- const retVal = [];
87
+ let found = false;
88
+ let retVal;
65
89
  for (const key in obj) {
66
90
  if (obj[key] === value) {
67
- retVal.push(key);
91
+ if (found) {
92
+ throw new Error('.safeReverseIndex found 0 or more than 1 keys for value: ' +
93
+ String(value));
94
+ }
95
+ found = true;
96
+ retVal = key;
68
97
  }
69
98
  }
70
- if (retVal.length !== 1) {
99
+ if (!found) {
71
100
  throw new Error('.safeReverseIndex found 0 or more than 1 keys for value: ' +
72
101
  String(value));
73
102
  }
74
- return retVal[0];
103
+ return retVal;
75
104
  }
76
105
  function isKey(obj, arg) {
77
106
  const keyArr = Array.isArray(arg) ? arg : [arg];
@@ -82,9 +111,23 @@ function isKey(obj, arg) {
82
111
  return true;
83
112
  }
84
113
  function isValue(obj, arg) {
85
- const valArr = Array.isArray(arg) ? arg : [arg], valSet = new Set(Object.values(obj));
86
- for (const val of valArr) {
87
- if (!valSet.has(val))
114
+ const dict = obj;
115
+ if (!Array.isArray(arg)) {
116
+ for (const key in obj) {
117
+ if (hop.call(obj, key) && sameValueZero(dict[key], arg))
118
+ return true;
119
+ }
120
+ return false;
121
+ }
122
+ for (const val of arg) {
123
+ let found = false;
124
+ for (const key in obj) {
125
+ if (hop.call(obj, key) && sameValueZero(dict[key], val)) {
126
+ found = true;
127
+ break;
128
+ }
129
+ }
130
+ if (!found)
88
131
  return false;
89
132
  }
90
133
  return true;
@@ -99,7 +142,16 @@ function entries(obj) {
99
142
  return Object.entries(obj);
100
143
  }
101
144
  function firstEntry(obj) {
102
- return Object.entries(obj)[0];
145
+ const dict = obj;
146
+ for (const key in obj) {
147
+ if (hop.call(obj, key)) {
148
+ return [key, dict[key]];
149
+ }
150
+ }
151
+ return undefined;
152
+ }
153
+ function sameValueZero(a, b) {
154
+ return a === b || (a !== a && b !== b);
103
155
  }
104
156
  function toDict(obj) {
105
157
  if (!isPlainObject(obj)) {
@@ -7,16 +7,22 @@ function compare(a, b) {
7
7
  return comparePlainObjects(a, b);
8
8
  }
9
9
  function comparePlainObjects(a, b) {
10
- const aKeys = Object.keys(a), bKeys = Object.keys(b);
11
- if (aKeys.length !== bKeys.length)
12
- return false;
13
- for (const key of aKeys) {
10
+ let aSize = 0;
11
+ for (const key in a) {
12
+ if (!hop.call(a, key))
13
+ continue;
14
+ aSize++;
14
15
  if (!hop.call(b, key))
15
16
  return false;
16
17
  if (!compareValue(a[key], b[key]))
17
18
  return false;
18
19
  }
19
- return true;
20
+ let bSize = 0;
21
+ for (const key in b) {
22
+ if (hop.call(b, key))
23
+ bSize++;
24
+ }
25
+ return aSize === bSize;
20
26
  }
21
27
  function compareValue(a, b) {
22
28
  if (Object.is(a, b))
@@ -1,28 +1,28 @@
1
1
  import isPlainObject, {} from '../isPlainObject.js';
2
- import {} from '../utility-types.js';
3
2
  const hop = Object.prototype.hasOwnProperty;
4
3
  function copy(value, options) {
5
4
  if (!isPlainObject(value)) {
6
5
  throw new TypeError('copy only accepts a plain-object as the root value');
7
6
  }
8
7
  const resetDates = options?.resetDates === true;
9
- return clonePlainObject(value, Object.getPrototypeOf(value), resetDates);
8
+ const deepCloneAll = options?.deepCloneAll === true;
9
+ return clonePlainObject(value, Object.getPrototypeOf(value), resetDates, deepCloneAll);
10
10
  }
11
- function clonePlainObject(source, proto, resetDates) {
11
+ function clonePlainObject(source, proto, resetDates, deepCloneAll) {
12
12
  const out = proto === null ? Object.create(null) : {};
13
13
  for (const key in source) {
14
14
  if (!hop.call(source, key))
15
15
  continue;
16
- out[key] = cloneValue(source[key], resetDates);
16
+ out[key] = cloneValue(source[key], resetDates, deepCloneAll);
17
17
  }
18
18
  return out;
19
19
  }
20
- function cloneValue(value, resetDates) {
20
+ function cloneValue(value, resetDates, deepCloneAll) {
21
21
  if (isPlainObject(value)) {
22
- return clonePlainObject(value, Object.getPrototypeOf(value), resetDates);
22
+ return clonePlainObject(value, Object.getPrototypeOf(value), resetDates, deepCloneAll);
23
23
  }
24
24
  if (Array.isArray(value)) {
25
- return cloneArray(value, resetDates);
25
+ return cloneArray(value, resetDates, deepCloneAll);
26
26
  }
27
27
  if (value instanceof Date) {
28
28
  if (resetDates) {
@@ -31,15 +31,18 @@ function cloneValue(value, resetDates) {
31
31
  return new Date(value.getTime());
32
32
  }
33
33
  if (typeof value === 'object' && value !== null) {
34
+ if (deepCloneAll) {
35
+ return cloneNonPlainDeep(value, resetDates);
36
+ }
34
37
  return cloneNonPlainShallow(value);
35
38
  }
36
39
  return value;
37
40
  }
38
- function cloneArray(source, resetDates) {
41
+ function cloneArray(source, resetDates, deepCloneAll) {
39
42
  const len = source.length;
40
43
  const out = new Array(len);
41
44
  for (let i = 0; i < len; i++) {
42
- out[i] = cloneValue(source[i], resetDates);
45
+ out[i] = cloneValue(source[i], resetDates, deepCloneAll);
43
46
  }
44
47
  return out;
45
48
  }
@@ -72,4 +75,44 @@ function cloneNonPlainShallow(value) {
72
75
  }
73
76
  return out;
74
77
  }
78
+ function cloneNonPlainDeep(value, resetDates) {
79
+ if (value instanceof RegExp) {
80
+ const re = new RegExp(value.source, value.flags);
81
+ re.lastIndex = value.lastIndex;
82
+ return re;
83
+ }
84
+ if (value instanceof Map) {
85
+ const out = new Map();
86
+ for (const [key, val] of value) {
87
+ out.set(cloneValue(key, resetDates, true), cloneValue(val, resetDates, true));
88
+ }
89
+ return out;
90
+ }
91
+ if (value instanceof Set) {
92
+ const out = new Set();
93
+ for (const entry of value) {
94
+ out.add(cloneValue(entry, resetDates, true));
95
+ }
96
+ return out;
97
+ }
98
+ if (ArrayBuffer.isView(value)) {
99
+ const anyVal = value;
100
+ if (typeof anyVal.slice === 'function')
101
+ return anyVal.slice();
102
+ if (value instanceof DataView) {
103
+ return new DataView(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
104
+ }
105
+ return new anyVal.constructor(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
106
+ }
107
+ if (value instanceof ArrayBuffer)
108
+ return value.slice(0);
109
+ const proto = Object.getPrototypeOf(value);
110
+ const out = Object.create(proto);
111
+ for (const key in value) {
112
+ if (!hop.call(value, key))
113
+ continue;
114
+ out[key] = cloneValue(value[key], resetDates, true);
115
+ }
116
+ return out;
117
+ }
75
118
  export default copy;
@@ -1,4 +1,5 @@
1
1
  import isPlainObject, {} from '../isPlainObject.js';
2
+ const hop = Object.prototype.hasOwnProperty;
2
3
  function iterate(root, cb) {
3
4
  if (!isPlainObject(root))
4
5
  return;
@@ -6,25 +7,31 @@ function iterate(root, cb) {
6
7
  }
7
8
  function iterateHelper(node, path, cb) {
8
9
  if (Array.isArray(node)) {
9
- let i = 0;
10
- for (const [key, value] of node.entries()) {
10
+ for (let i = 0; i < node.length; i++) {
11
+ const value = node[i];
12
+ cb({ parent: node, key: i, value, path: copyPath(path) });
11
13
  if (isPlainObject(value) || Array.isArray(value)) {
12
- iterateHelper(value, [...path, key, i], cb);
14
+ path.push(i);
15
+ iterateHelper(value, path, cb);
16
+ path.pop();
13
17
  }
14
- else {
15
- cb({ parent: node, key, value, path });
16
- }
17
- i++;
18
18
  }
19
19
  return;
20
20
  }
21
- for (const [key, value] of Object.entries(node)) {
21
+ const dict = node;
22
+ for (const key in dict) {
23
+ if (!hop.call(dict, key))
24
+ continue;
25
+ const value = dict[key];
26
+ cb({ parent: dict, key, value, path: copyPath(path) });
22
27
  if (isPlainObject(value) || Array.isArray(value)) {
23
- iterateHelper(value, [...path, key], cb);
24
- }
25
- else {
26
- cb({ parent: node, key, value, path });
28
+ path.push(key);
29
+ iterateHelper(value, path, cb);
30
+ path.pop();
27
31
  }
28
32
  }
29
33
  }
34
+ function copyPath(path) {
35
+ return path.slice();
36
+ }
30
37
  export default iterate;
@@ -1,5 +1,5 @@
1
1
  import isPlainObject, { type Dict, type PlainObject } from './isPlainObject.js';
2
- import type { DeepWiden, EntriesTuple, KeysParam, KeyTuple, KeyUnion, Mutable, OmitKeys, PickKeys, SetToNever, ValueTuple } from './utility-types.js';
2
+ import type { DeepWiden, EntriesTuple, Entry, KeysParam, KeyTuple, KeyUnion, OmitKeys, PickKeys, SetToNever, ValueTuple } from './utility-types.js';
3
3
  import compare from './utils/compare.js';
4
4
  import copy from './utils/copy.js';
5
5
  import iterate from './utils/iterate.js';
@@ -23,12 +23,12 @@ declare function pick<T extends PlainObject, K extends KeysParam<T>>(obj: T, key
23
23
  /**
24
24
  * Merge two object together and return a new type.
25
25
  */
26
- declare function merge<T extends PlainObject, U extends PlainObject>(a: T, b: U): CollapseType<Mutable<Omit<T, keyof U> & U>>;
26
+ declare function merge<T extends PlainObject, U extends PlainObject>(a: T, b: U): CollapseType<Omit<T, keyof U> & U>;
27
27
  /**
28
28
  * Fill the missing entries in a partial, will the values from a 'defaults'
29
29
  * object.
30
30
  */
31
- declare function fill<const T extends object>(defaults: T, partial?: Partial<DeepWiden<T>>): CollapseType<Mutable<DeepWiden<T>>>;
31
+ declare function fill<const T extends object>(defaults: T, partial?: Partial<DeepWiden<T>>): CollapseType<DeepWiden<T>>;
32
32
  /**
33
33
  * Append one object to another, modifying the reference to the original
34
34
  * object.
@@ -81,7 +81,7 @@ declare function entries<T extends object>(obj: T): EntriesTuple<T>;
81
81
  /**
82
82
  * Get a type-safe array of the object e
83
83
  */
84
- declare function firstEntry<T extends object, K extends keyof T>(obj: T): [K, T[K]];
84
+ declare function firstEntry<T extends object>(obj: T): Entry<T>;
85
85
  /**
86
86
  * Check if something is a plain
87
87
  */
@@ -2,9 +2,9 @@ export type KeysParam<T extends object> = keyof T | (keyof T)[];
2
2
  export type KeyUnion<T extends object, K extends KeysParam<T>> = K extends (keyof T)[] ? K[number] : K;
3
3
  export type OmitKeys<T extends object, K extends KeysParam<T>> = Omit<T, KeyUnion<T, K>>;
4
4
  export type PickKeys<T extends object, K extends KeysParam<T>> = Pick<T, KeyUnion<T, K>>;
5
- export type Mutable<T> = {
6
- -readonly [K in keyof T]: T[K];
7
- };
5
+ export type Entry<T extends object> = T extends object ? {
6
+ [K in keyof T]-?: [K, T[K]];
7
+ }[keyof T] : never;
8
8
  export type SetToNever<T, K extends PropertyKey> = T & {
9
9
  [P in K]: never;
10
10
  };
@@ -1,7 +1,10 @@
1
1
  import { type PlainObject } from '../isPlainObject.js';
2
- import { type Mutable } from '../utility-types.js';
3
2
  type CopyOptions = {
4
3
  resetDates?: boolean;
4
+ deepCloneAll?: boolean;
5
+ };
6
+ type Mutable<T> = {
7
+ -readonly [K in keyof T]: T[K];
5
8
  };
6
9
  /**
7
10
  * Deep clones ONLY plain-objects (incl. null-prototype).
@@ -10,7 +13,8 @@ type CopyOptions = {
10
13
  * - Recursion descends only into plain-objects and arrays.
11
14
  * - Nested Date values are copied by epoch.
12
15
  * - `resetDates` resets all nested Date values to current time.
13
- * - Other nested non-plain objects are shallow-cloned.
16
+ * - Other nested non-plain objects are shallow-cloned by default.
17
+ * - `deepCloneAll` deep-clones all nested object values.
14
18
  */
15
19
  declare function copy<T extends PlainObject>(value: T, options?: CopyOptions): Mutable<T>;
16
20
  export default copy;
@@ -16,10 +16,10 @@ type IterateCb = (args: {
16
16
  ******************************************************************************/
17
17
  /**
18
18
  * Recursively walks plain-objects and arrays, and calls a callback for
19
- * every key whose value is neither a plain-object nor an array.
19
+ * every key before descending into nested values.
20
20
  *
21
21
  * - Descends into a value if it is a plain-object or array.
22
- * - Fires callback for every non-descended value.
22
+ * - Fires callback for every entry (including plain-objects/arrays).
23
23
  */
24
24
  declare function iterate(root: unknown, cb: IterateCb): void;
25
25
  /******************************************************************************
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tspo",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A collection of utilities for handling both runtime and compile-time behavior for plain-objects.",
5
5
  "keywords": [
6
6
  "typescript",