@magic/types 0.1.28 → 0.1.30

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
@@ -360,6 +360,15 @@ update dependencies
360
360
  - options.strict makes the tests include sort order of objects and array, [1, 2] is [2, 1] if options.strict = true
361
361
  - update dependencies
362
362
 
363
- ##### 0.1.29 - unreleased
363
+ ##### 0.1.29
364
+
365
+ - change types of is.ln, is.len, is.length and is.count to reflect their type as function with subfunctions
366
+
367
+ ##### 0.1.30
368
+
369
+ - fix deep.equal and deep.different implementations and tests
370
+ - update dependencies
371
+
372
+ ##### 0.1.31 - unreleased
364
373
 
365
374
  ...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magic/types",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "author": "Wizards & Witches",
5
5
  "homepage": "https://github.com/magic/types",
6
6
  "license": "AGPL-3.0",
@@ -10,8 +10,8 @@
10
10
  "type": "module",
11
11
  "scripts": {
12
12
  "start": "t",
13
- "build": "tsc && npm run format && echo 'Types generated in dist/*'",
14
- "prepublishOnly": "npm run build",
13
+ "build": "tsc && npm run format",
14
+ "prepublishOnly": "npm run test && npm run build",
15
15
  "build:docs": "NODE_ENV=production magic build",
16
16
  "prod": "NODE_ENV=production magic build serve",
17
17
  "clean": "magic clean",
@@ -20,7 +20,8 @@
20
20
  "test": "t",
21
21
  "format": "f -w --exclude docs",
22
22
  "format:check": "f --exclude docs",
23
- "calls": "calls"
23
+ "calls": "calls",
24
+ "lint": "tsc --noEmit"
24
25
  },
25
26
  "engines": {
26
27
  "node": ">=18"
@@ -45,8 +46,7 @@
45
46
  "@magic-themes/docs": "0.0.15",
46
47
  "@magic/core": "0.0.156",
47
48
  "@magic/format": "0.0.68",
48
- "@magic/fs": "0.0.31",
49
- "@magic/test": "0.2.20",
49
+ "@magic/test": "0.2.24",
50
50
  "typescript": "5.9.3"
51
51
  },
52
52
  "keywords": [
@@ -61,6 +61,6 @@
61
61
  }
62
62
  ],
63
63
  "dependencies": {
64
- "@types/node": "24.7.1"
64
+ "@types/node": "24.9.2"
65
65
  }
66
66
  }
package/src/deep/equal.js CHANGED
@@ -18,9 +18,12 @@ import is from '../lib.js'
18
18
  * @param {unknown} [b]
19
19
  * @param {object} [options]
20
20
  * @param {boolean} [options.strict=false]
21
+ * @param {boolean} [options.arrayOrderStrict=true]
21
22
  * @returns {boolean | ((c: unknown) => boolean)}
22
23
  */
23
- export const equal = (a, b, options = { strict: false }) => {
24
+ export const equal = (a, b, options = {}) => {
25
+ const { strict = false, arrayOrderStrict = false } = options
26
+
24
27
  // curry
25
28
  if (is.undefined(b)) {
26
29
  if (is.undefined(a)) {
@@ -39,15 +42,11 @@ export const equal = (a, b, options = { strict: false }) => {
39
42
  return false
40
43
  }
41
44
 
42
- // bool, string, number, falsy values
43
- if (is.comparable(a) || is.comparable(b)) {
44
- return a === b
45
+ /* functions are handled by their toString value */
46
+ if (is.function(a) && is.function(b)) {
47
+ return a.toString() === b.toString()
45
48
  }
46
49
 
47
- // if (is.arguments(a)) {
48
- // return is.length.eq(a, b)
49
- // }
50
-
51
50
  if (!is.object(a) || !is.object(b)) {
52
51
  return a === b
53
52
  }
@@ -58,30 +57,17 @@ export const equal = (a, b, options = { strict: false }) => {
58
57
  }
59
58
 
60
59
  // real types must match too
61
- // if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) {
62
- // return false
63
- // }
60
+ if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) {
61
+ return false
62
+ }
64
63
 
65
64
  // dates
66
65
  if (is.date(a)) {
67
- return a === b
66
+ return a.toString() === b.toString()
68
67
  }
69
68
 
70
- /* functions are handled by prototype comparison above */
71
- // if (is.function(a)) {
72
- // if (!is.function(b)) {
73
- // return false
74
- // }
75
-
76
- // return a.toString() === b.toString()
77
- // }
78
-
79
69
  // buffers
80
- if (is.buffer(a)) {
81
- if (!is.buffer(b)) {
82
- return false
83
- }
84
-
70
+ if (is.buffer(a) && is.buffer(b)) {
85
71
  if (a.length !== b.length) {
86
72
  return false
87
73
  }
@@ -95,24 +81,17 @@ export const equal = (a, b, options = { strict: false }) => {
95
81
  return true
96
82
  }
97
83
 
98
- if (is.objectNative(a) || is.array(a)) {
99
- if (is.array(a)) {
100
- if (!is.array(b)) {
101
- return false
102
- }
103
-
104
- if (!options.strict) {
105
- a.sort()
106
- b.sort()
107
- }
108
-
109
- return !a.some((v, i) => v !== b[i])
84
+ if (is.array(a) && is.array(b)) {
85
+ if (!strict && !arrayOrderStrict) {
86
+ a.sort()
87
+ b.sort()
110
88
  }
111
89
 
112
- if (!is.objectNative(b)) {
113
- return false
114
- }
90
+ const allEqual = !a.some((v, i) => !equal(v, b[i]))
91
+ return allEqual
92
+ }
115
93
 
94
+ if (is.objectNative(a) && is.objectNative(b)) {
116
95
  const aObj = a
117
96
  const bObj = b
118
97
 
@@ -124,7 +103,7 @@ export const equal = (a, b, options = { strict: false }) => {
124
103
  return false
125
104
  }
126
105
 
127
- if (!options.strict) {
106
+ if (!strict) {
128
107
  ka.sort()
129
108
  kb.sort()
130
109
  }
@@ -137,15 +116,8 @@ export const equal = (a, b, options = { strict: false }) => {
137
116
  }
138
117
 
139
118
  // equivalent values for every corresponding key, and
140
- // ~~~possibly expensive deep test
141
- let key
142
- for (let i = ka.length - 1; i >= 0; i--) {
143
- key = ka[i]
144
-
145
- if (!equal(aObj[key], bObj[key])) {
146
- return false
147
- }
148
- }
119
+ // ~~~ possibly expensive deep test
120
+ return !ka.some(key => !equal(aObj[key], bObj[key]))
149
121
  }
150
122
 
151
123
  return typeof a === typeof b
package/src/fns.js CHANGED
@@ -340,7 +340,7 @@ export const isLengthSmallerOrEqual = (a, b) =>
340
340
  * - null/undefined → true
341
341
  * - arrays, objects, regex → empty if size < 1
342
342
  * - errors/dates → never empty
343
- * - numbers, strings → falsy or 0/""
343
+ * - numbers, strings → falsy or 0, ""
344
344
  * @param {unknown} e
345
345
  * @returns {boolean}
346
346
  */
package/src/lib.js CHANGED
@@ -1,11 +1,68 @@
1
1
  import * as fns from './fns.js'
2
2
  import * as deep from './deep/index.js'
3
3
 
4
- export const is = {
5
- count: fns.getLength,
6
- length: fns.getLength,
7
- len: fns.getLength,
8
- ln: fns.getLength,
4
+ // count, length, len and ln are functions that return the length,
5
+ // but they also have comparison methods attached as properties.
6
+ // This creates enhanced length functions with comparison capabilities.
7
+
8
+ /**
9
+ * @typedef {typeof fns.isLengthEqual} LengthComparison
10
+ */
11
+
12
+ /**
13
+ * @typedef {typeof fns.getLength & {
14
+ * eq: LengthComparison,
15
+ * equal: LengthComparison,
16
+ * gt: LengthComparison,
17
+ * bigger: LengthComparison,
18
+ * biggerequal: LengthComparison,
19
+ * greater: LengthComparison,
20
+ * greaterequal: LengthComparison,
21
+ * gte: LengthComparison,
22
+ * gteq: LengthComparison,
23
+ * lower: LengthComparison,
24
+ * smaller: LengthComparison,
25
+ * lt: LengthComparison,
26
+ * lowerequal: LengthComparison,
27
+ * smallerequal: LengthComparison,
28
+ * lte: LengthComparison,
29
+ * lteq: LengthComparison
30
+ * }} EnhancedLengthFunction
31
+ */
32
+
33
+ // Create enhanced length functions with comparison methods
34
+ const lengthFunctions = {
35
+ eq: fns.isLengthEqual,
36
+ equal: fns.isLengthEqual,
37
+ gt: fns.isLengthGreater,
38
+ bigger: fns.isLengthGreater,
39
+ biggerequal: fns.isLengthGreaterOrEqual,
40
+ greater: fns.isLengthGreater,
41
+ greaterequal: fns.isLengthGreaterOrEqual,
42
+ gte: fns.isLengthGreaterOrEqual,
43
+ gteq: fns.isLengthGreaterOrEqual,
44
+ lower: fns.isLengthSmaller,
45
+ smaller: fns.isLengthSmaller,
46
+ lt: fns.isLengthSmaller,
47
+ lowerequal: fns.isLengthSmallerOrEqual,
48
+ smallerequal: fns.isLengthSmallerOrEqual,
49
+ lte: fns.isLengthSmallerOrEqual,
50
+ lteq: fns.isLengthSmallerOrEqual,
51
+ }
52
+
53
+ // Replace the original length functions with enhanced versions
54
+ const ln = /** @type {EnhancedLengthFunction} */ (fns.getLength)
55
+ Object.assign(ln, lengthFunctions)
56
+
57
+ const length = ln
58
+ const len = ln
59
+ const count = ln
60
+
61
+ export const is = /** @type {const} */ {
62
+ count,
63
+ length,
64
+ len,
65
+ ln,
9
66
 
10
67
  isError: fns.isError,
11
68
  error: fns.isError,
@@ -269,34 +326,4 @@ export const is = {
269
326
  ...deep,
270
327
  }
271
328
 
272
- // count, length, len and ln are functions that return the length,
273
- // but they also have comparison methods attached as properties.
274
- // This creates enhanced length functions with comparison capabilities.
275
-
276
- // Create enhanced length functions with comparison methods
277
- const lengthFunctions = {
278
- eq: fns.isLengthEqual,
279
- equal: fns.isLengthEqual,
280
- gt: fns.isLengthGreater,
281
- bigger: fns.isLengthGreater,
282
- biggerequal: fns.isLengthGreaterOrEqual,
283
- greater: fns.isLengthGreater,
284
- greaterequal: fns.isLengthGreaterOrEqual,
285
- gte: fns.isLengthGreaterOrEqual,
286
- gteq: fns.isLengthGreaterOrEqual,
287
- lower: fns.isLengthSmaller,
288
- smaller: fns.isLengthSmaller,
289
- lt: fns.isLengthSmaller,
290
- lowerequal: fns.isLengthSmallerOrEqual,
291
- smallerequal: fns.isLengthSmallerOrEqual,
292
- lte: fns.isLengthSmallerOrEqual,
293
- lteq: fns.isLengthSmallerOrEqual,
294
- }
295
-
296
- // Replace the original length functions with enhanced versions
297
- is.ln = fns.getLength
298
- Object.assign(is.ln, lengthFunctions)
299
-
300
- is.length = is.len = is.count = is.ln
301
-
302
329
  export default is
package/types/index.d.ts CHANGED
@@ -183,10 +183,10 @@ export const is: {
183
183
  (a: unknown): (c: unknown) => boolean
184
184
  }
185
185
  }
186
- count: (arg: unknown) => number
187
- length: (arg: unknown) => number
188
- len: (arg: unknown) => number
189
- ln: (arg: unknown) => number
186
+ count: import('./lib.js').EnhancedLengthFunction
187
+ length: import('./lib.js').EnhancedLengthFunction
188
+ len: import('./lib.js').EnhancedLengthFunction
189
+ ln: import('./lib.js').EnhancedLengthFunction
190
190
  isError: (e: unknown) => e is Error
191
191
  error: (e: unknown) => e is Error
192
192
  err: (e: unknown) => e is Error
package/types/lib.d.ts CHANGED
@@ -181,10 +181,10 @@ export const is: {
181
181
  (a: unknown): (c: unknown) => boolean
182
182
  }
183
183
  }
184
- count: (arg: unknown) => number
185
- length: (arg: unknown) => number
186
- len: (arg: unknown) => number
187
- ln: (arg: unknown) => number
184
+ count: EnhancedLengthFunction
185
+ length: EnhancedLengthFunction
186
+ len: EnhancedLengthFunction
187
+ ln: EnhancedLengthFunction
188
188
  isError: (e: unknown) => e is Error
189
189
  error: (e: unknown) => e is Error
190
190
  err: (e: unknown) => e is Error
@@ -508,3 +508,23 @@ export const is: {
508
508
  }
509
509
  }
510
510
  export default is
511
+ export type LengthComparison = typeof fns.isLengthEqual
512
+ export type EnhancedLengthFunction = typeof fns.getLength & {
513
+ eq: LengthComparison
514
+ equal: LengthComparison
515
+ gt: LengthComparison
516
+ bigger: LengthComparison
517
+ biggerequal: LengthComparison
518
+ greater: LengthComparison
519
+ greaterequal: LengthComparison
520
+ gte: LengthComparison
521
+ gteq: LengthComparison
522
+ lower: LengthComparison
523
+ smaller: LengthComparison
524
+ lt: LengthComparison
525
+ lowerequal: LengthComparison
526
+ smallerequal: LengthComparison
527
+ lte: LengthComparison
528
+ lteq: LengthComparison
529
+ }
530
+ import * as fns from './fns.js'