jsfunx 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.
Files changed (4) hide show
  1. package/README.md +2 -2
  2. package/jsfunx.cjs +602 -59
  3. package/jsfunx.mjs +569 -57
  4. package/package.json +1 -1
package/jsfunx.mjs CHANGED
@@ -38,7 +38,11 @@ export const and = "and";
38
38
 
39
39
  /** @type {string} */
40
40
 
41
- export const or = "or";
41
+ export const bi = "bigint";
42
+
43
+ /** @type {BigIntConstructor} */
44
+
45
+ export const BI = BigInt;
42
46
 
43
47
  /** @type {string} */
44
48
 
@@ -46,27 +50,95 @@ export const bigint = "bigint";
46
50
 
47
51
  /** @type {string} */
48
52
 
53
+ export const bool = "boolean";
54
+
55
+ /** @type {BooleanConstructor} */
56
+
57
+ export const Bool = Boolean;
58
+
59
+ /** @type {string} */
60
+
61
+ export const boolean = "boolean";
62
+
63
+ /** @type {string} */
64
+
65
+ export const fn = "function";
66
+
67
+ /** @type {FunctionConstructor} */
68
+
69
+ export const Fn = Function;
70
+
71
+ /** @type {string} */
72
+
73
+ export const fun = "function";
74
+
75
+ /** @type {FunctionConstructor} */
76
+
77
+ export const Fun = Function;
78
+
79
+ /** @type {string} */
80
+
49
81
  export const func = "function";
50
82
 
83
+ /** @type {FunctionConstructor} */
84
+
85
+ export const Func = Function;
86
+
87
+ /** @type {null} */
88
+
89
+ export const nil = null;
90
+
91
+ /** @type {string} */
92
+
93
+ export const num = "number";
94
+
95
+ /** @type {NumberConstructor} */
96
+
97
+ export const Num = Number;
98
+
51
99
  /** @type {string} */
52
100
 
53
101
  export const number = "number";
54
102
 
55
103
  /** @type {string} */
56
104
 
105
+ export const obj = "object";
106
+
107
+ /** @type {ObjectConstructor} */
108
+
109
+ export const Obj = Object;
110
+
111
+ /** @type {string} */
112
+
57
113
  export const object = "object";
58
114
 
59
115
  /** @type {string} */
60
116
 
117
+ export const or = "or";
118
+
119
+ /** @type {string} */
120
+
121
+ export const str = "string";
122
+
123
+ /** @type {StringConstructor} */
124
+
125
+ export const Str = String;
126
+
127
+ /** @type {string} */
128
+
61
129
  export const string = "string";
62
130
 
63
131
  /** @type {string} */
64
132
 
65
- export const symbol = "symbol";
133
+ export const sym = "symbol";
134
+
135
+ /** @type {SymbolConstructor} */
136
+
137
+ export const Sym = Symbol;
66
138
 
67
139
  /** @type {string} */
68
140
 
69
- export const boolean = "boolean";
141
+ export const symbol = "symbol";
70
142
 
71
143
  /** @type {string} */
72
144
 
@@ -88,17 +160,62 @@ export const undef = "undefined";
88
160
  */
89
161
 
90
162
  function checkType(data, dataType, logic, match, strict) {
91
- // if data or dataType is Array must be nested Array
163
+ /** @type {Set<string | null | undefined>} */
164
+
165
+ let setOfTypes = new Set([
166
+ and,
167
+ bi,
168
+ bool,
169
+ fn,
170
+ null,
171
+ num,
172
+ obj,
173
+ or,
174
+ str,
175
+ sym,
176
+ undef,
177
+ undefined,
178
+ ]);
92
179
 
93
180
  if (!(dataType instanceof Array)) {
181
+ if (!setOfTypes.has(dataType)) {
182
+ throw new TypeError("type undefined !");
183
+ }
184
+
94
185
  if (!(data instanceof Array)) {
186
+ if (data === null) {
187
+ return dataType === null;
188
+ }
189
+
190
+ if (dataType === undefined) {
191
+ return data === undefined;
192
+ }
193
+
95
194
  return typeof data === dataType;
96
195
  }
97
196
 
98
- if (logic === and) {
197
+ if (data.length === 0) {
198
+ data[0] = [];
199
+ }
200
+
201
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
99
202
  for (let dt of data) {
100
203
  // 1 step directly in all cases
101
204
 
205
+ if (dt === null) {
206
+ if (dataType !== null) {
207
+ return false;
208
+ }
209
+ continue;
210
+ }
211
+
212
+ if (dataType === undefined) {
213
+ if (dt !== undefined) {
214
+ return false;
215
+ }
216
+ continue;
217
+ }
218
+
102
219
  if (!(typeof dt === dataType)) {
103
220
  return false;
104
221
  }
@@ -114,10 +231,24 @@ function checkType(data, dataType, logic, match, strict) {
114
231
  return true;
115
232
  }
116
233
 
117
- if (logic === or) {
234
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
118
235
  for (let dt of data) {
119
236
  // 1 step directly in all cases
120
237
 
238
+ if (dt === null) {
239
+ if (dataType === null) {
240
+ return true;
241
+ }
242
+ continue;
243
+ }
244
+
245
+ if (dataType === undefined) {
246
+ if (dt === undefined) {
247
+ return true;
248
+ }
249
+ continue;
250
+ }
251
+
121
252
  if (typeof dt === dataType) {
122
253
  return true;
123
254
  }
@@ -140,6 +271,24 @@ function checkType(data, dataType, logic, match, strict) {
140
271
  for (let dtype of dataType) {
141
272
  // 1 step directly in all cases
142
273
 
274
+ if (!setOfTypes.has(dtype)) {
275
+ throw new TypeError(`type ${dtype} undefined !`);
276
+ }
277
+
278
+ if (data === null) {
279
+ if (dtype === null) {
280
+ return true;
281
+ }
282
+ continue;
283
+ }
284
+
285
+ if (dtype === undefined) {
286
+ if (data === undefined) {
287
+ return true;
288
+ }
289
+ continue;
290
+ }
291
+
143
292
  if (typeof data === dtype) {
144
293
  return true;
145
294
  }
@@ -155,10 +304,32 @@ function checkType(data, dataType, logic, match, strict) {
155
304
  return false;
156
305
  }
157
306
 
158
- if (!match) {
159
- if (logic === and) {
307
+ if (data.length === 0) {
308
+ data[0] = [];
309
+ }
310
+
311
+ if (not(match)) {
312
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
160
313
  outerLoop: for (let dt of data) {
161
314
  for (let dtype of dataType) {
315
+ if (!setOfTypes.has(dtype)) {
316
+ throw new TypeError(`type ${dtype} undefined !`);
317
+ }
318
+
319
+ if (dt === null) {
320
+ if (dtype === null) {
321
+ continue outerLoop;
322
+ }
323
+ continue;
324
+ }
325
+
326
+ if (dtype === undefined) {
327
+ if (dt === undefined) {
328
+ continue outerLoop;
329
+ }
330
+ continue;
331
+ }
332
+
162
333
  if (typeof dt === dtype) {
163
334
  continue outerLoop;
164
335
  }
@@ -196,6 +367,24 @@ function checkType(data, dataType, logic, match, strict) {
196
367
 
197
368
  // // // the same as this
198
369
 
370
+ // // // if (!setOfTypes.has(dtype)) {
371
+ // // // throw new TypeError(`type ${dtype} undefined !`);
372
+ // // // }
373
+
374
+ // // // if (data[0] === null) {
375
+ // // // if (dtype === null) {
376
+ // // // return true;
377
+ // // // }
378
+ // // // continue;
379
+ // // // }
380
+
381
+ // // // if (dtype === undefined) {
382
+ // // // if (data[0] === undefined) {
383
+ // // // return true;
384
+ // // // }
385
+ // // // continue;
386
+ // // // }
387
+
199
388
  // // // if (typeof data[0] === dtype) {
200
389
  // // // return true;
201
390
  // // // }
@@ -228,6 +417,24 @@ function checkType(data, dataType, logic, match, strict) {
228
417
 
229
418
  // // // the same as this
230
419
 
420
+ // // // if (!setOfTypes.has(dataType[0])) {
421
+ // // // throw new TypeError("type undefined !");
422
+ // // // }
423
+
424
+ // // // if (dt === null) {
425
+ // // // if (dataType[0] !== null) {
426
+ // // // return false;
427
+ // // // }
428
+ // // // continue;
429
+ // // // }
430
+
431
+ // // // if (dataType[0] === undefined) {
432
+ // // // if (dt !== undefined) {
433
+ // // // return false;
434
+ // // // }
435
+ // // // continue;
436
+ // // // }
437
+
231
438
  // // // if (!(typeof dt === dataType[0])) {
232
439
  // // // return false;
233
440
  // // // }
@@ -283,9 +490,27 @@ function checkType(data, dataType, logic, match, strict) {
283
490
  // return true;
284
491
  }
285
492
 
286
- if (logic === or) {
493
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
287
494
  for (let dt of data) {
288
495
  for (let dtype of dataType) {
496
+ if (!setOfTypes.has(dtype)) {
497
+ throw new TypeError(`type ${dtype} undefined !`);
498
+ }
499
+
500
+ if (dt === null) {
501
+ if (dtype === null) {
502
+ return true;
503
+ }
504
+ continue;
505
+ }
506
+
507
+ if (dtype === undefined) {
508
+ if (dt === undefined) {
509
+ return true;
510
+ }
511
+ continue;
512
+ }
513
+
289
514
  if (typeof dt === dtype) {
290
515
  return true;
291
516
  }
@@ -319,6 +544,24 @@ function checkType(data, dataType, logic, match, strict) {
319
544
 
320
545
  // // // the same as this
321
546
 
547
+ // // // if (!setOfTypes.has(dtype)) {
548
+ // // // throw new TypeError(`type ${dtype} undefined !`);
549
+ // // // }
550
+
551
+ // // // if (data[0] === null) {
552
+ // // // if (dtype === null) {
553
+ // // // return true;
554
+ // // // }
555
+ // // // continue;
556
+ // // // }
557
+
558
+ // // // if (dtype === undefined) {
559
+ // // // if (data[0] === undefined) {
560
+ // // // return true;
561
+ // // // }
562
+ // // // continue;
563
+ // // // }
564
+
322
565
  // // // if (typeof data[0] === dtype) {
323
566
  // // // return true;
324
567
  // // // }
@@ -353,9 +596,27 @@ function checkType(data, dataType, logic, match, strict) {
353
596
 
354
597
  // // // the same as this
355
598
 
356
- // // if (typeof dt === dataType[0]) {
357
- // // return true;
358
- // // }
599
+ // // // if (!setOfTypes.has(dataType[0])) {
600
+ // // // throw new TypeError("type undefined !");
601
+ // // // }
602
+
603
+ // // // if (dt === null) {
604
+ // // // if (dataType[0] === null) {
605
+ // // // return true;
606
+ // // // }
607
+ // // // continue;
608
+ // // // }
609
+
610
+ // // // if (dataType[0] === undefined) {
611
+ // // // if (dt === undefined) {
612
+ // // // return true;
613
+ // // // }
614
+ // // // continue;
615
+ // // // }
616
+
617
+ // // // if (typeof dt === dataType[0]) {
618
+ // // // return true;
619
+ // // // }
359
620
  // // }
360
621
 
361
622
  // // shared return
@@ -464,10 +725,28 @@ function checkType(data, dataType, logic, match, strict) {
464
725
  min = dataType.length;
465
726
  }
466
727
 
467
- if (logic === and) {
728
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
468
729
  for (let i = 0; i < min; ++i) {
469
730
  // 1 step directly in all cases
470
731
 
732
+ if (!setOfTypes.has(dataType[i])) {
733
+ throw new TypeError(`type ${dataType[i]} undefined !`);
734
+ }
735
+
736
+ if (data[i] === null) {
737
+ if (dataType[i] !== null) {
738
+ return false;
739
+ }
740
+ continue;
741
+ }
742
+
743
+ if (dataType[i] === undefined) {
744
+ if (data[i] !== undefined) {
745
+ return false;
746
+ }
747
+ continue;
748
+ }
749
+
471
750
  if (!(typeof data[i] === dataType[i])) {
472
751
  return false;
473
752
  }
@@ -485,10 +764,28 @@ function checkType(data, dataType, logic, match, strict) {
485
764
  return true;
486
765
  }
487
766
 
488
- if (logic === or) {
767
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
489
768
  for (let i = 0; i < min; ++i) {
490
769
  // 1 step directly in all cases
491
770
 
771
+ if (!setOfTypes.has(dataType[i])) {
772
+ throw new TypeError(`type ${dataType[i]} undefined !`);
773
+ }
774
+
775
+ if (data[i] === null) {
776
+ if (dataType[i] === null) {
777
+ return true;
778
+ }
779
+ continue;
780
+ }
781
+
782
+ if (dataType[i] === undefined) {
783
+ if (data[i] === undefined) {
784
+ return true;
785
+ }
786
+ continue;
787
+ }
788
+
492
789
  if (typeof data[i] === dataType[i]) {
493
790
  return true;
494
791
  }
@@ -509,10 +806,28 @@ function checkType(data, dataType, logic, match, strict) {
509
806
  throw new TypeError("logic type undefined !");
510
807
  }
511
808
 
512
- if (logic === and) {
809
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
513
810
  for (let i = 0; i < data.length; ++i) {
514
811
  // 1 step directly in all cases
515
812
 
813
+ if (!setOfTypes.has(dataType[i])) {
814
+ throw new TypeError(`type ${dataType[i]} undefined !`);
815
+ }
816
+
817
+ if (data[i] === null) {
818
+ if (dataType[i] !== null) {
819
+ return false;
820
+ }
821
+ continue;
822
+ }
823
+
824
+ if (dataType[i] === undefined) {
825
+ if (data[i] !== undefined) {
826
+ return false;
827
+ }
828
+ continue;
829
+ }
830
+
516
831
  if (!(typeof data[i] === dataType[i])) {
517
832
  return false;
518
833
  }
@@ -530,10 +845,28 @@ function checkType(data, dataType, logic, match, strict) {
530
845
  return true;
531
846
  }
532
847
 
533
- if (logic === or) {
848
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
534
849
  for (let i = 0; i < data.length; ++i) {
535
850
  // 1 step directly in all cases
536
851
 
852
+ if (!setOfTypes.has(dataType[i])) {
853
+ throw new TypeError(`type ${dataType[i]} undefined !`);
854
+ }
855
+
856
+ if (data[i] === null) {
857
+ if (dataType[i] === null) {
858
+ return true;
859
+ }
860
+ continue;
861
+ }
862
+
863
+ if (dataType[i] === undefined) {
864
+ if (data[i] === undefined) {
865
+ return true;
866
+ }
867
+ continue;
868
+ }
869
+
537
870
  if (typeof data[i] === dataType[i]) {
538
871
  return true;
539
872
  }
@@ -571,7 +904,7 @@ function checkType(data, dataType, logic, match, strict) {
571
904
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
572
905
  */
573
906
 
574
- function isinstances(objs, type, logic, match, strict) {
907
+ function isinstancesof(objs, type, logic, match, strict) {
575
908
  if (!(type instanceof Array)) {
576
909
  // uncomment (return objs instanceof type)
577
910
  // to enable the 1/4 of (one to one)
@@ -592,7 +925,7 @@ function isinstances(objs, type, logic, match, strict) {
592
925
  );
593
926
  }
594
927
 
595
- if (logic === and) {
928
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
596
929
  for (let obj of objs) {
597
930
  // 1 step directly in all cases
598
931
 
@@ -617,7 +950,7 @@ function isinstances(objs, type, logic, match, strict) {
617
950
  return true;
618
951
  }
619
952
 
620
- if (logic === or) {
953
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
621
954
  for (let obj of objs) {
622
955
  // 1 step directly in all cases
623
956
 
@@ -686,8 +1019,12 @@ function isinstances(objs, type, logic, match, strict) {
686
1019
  );
687
1020
  }
688
1021
 
689
- if (!match) {
690
- if (logic === and) {
1022
+ if (not(match)) {
1023
+ if (objs.length === 0) {
1024
+ objs[0] = [];
1025
+ }
1026
+
1027
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
691
1028
  outerLoop: for (let obj of objs) {
692
1029
  for (let dt of type) {
693
1030
  try {
@@ -820,7 +1157,7 @@ function isinstances(objs, type, logic, match, strict) {
820
1157
  // return true;
821
1158
  }
822
1159
 
823
- if (logic === or) {
1160
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
824
1161
  for (let obj of objs) {
825
1162
  for (let dt of type) {
826
1163
  try {
@@ -1007,7 +1344,7 @@ function isinstances(objs, type, logic, match, strict) {
1007
1344
  min = type.length;
1008
1345
  }
1009
1346
 
1010
- if (logic === and) {
1347
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
1011
1348
  for (let i = 0; i < min; ++i) {
1012
1349
  // 1 step directly in all cases
1013
1350
 
@@ -1034,7 +1371,7 @@ function isinstances(objs, type, logic, match, strict) {
1034
1371
  return true;
1035
1372
  }
1036
1373
 
1037
- if (logic === or) {
1374
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
1038
1375
  for (let i = 0; i < min; ++i) {
1039
1376
  // 1 step directly in all cases
1040
1377
 
@@ -1064,7 +1401,7 @@ function isinstances(objs, type, logic, match, strict) {
1064
1401
  throw new TypeError("logic type undefined !");
1065
1402
  }
1066
1403
 
1067
- if (logic === and) {
1404
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
1068
1405
  for (let i = 0; i < objs.length; ++i) {
1069
1406
  // 1 step directly in all cases
1070
1407
 
@@ -1091,7 +1428,7 @@ function isinstances(objs, type, logic, match, strict) {
1091
1428
  return true;
1092
1429
  }
1093
1430
 
1094
- if (logic === or) {
1431
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
1095
1432
  for (let i = 0; i < objs.length; ++i) {
1096
1433
  // 1 step directly in all cases
1097
1434
 
@@ -1121,6 +1458,21 @@ function isinstances(objs, type, logic, match, strict) {
1121
1458
  throw new TypeError("logic type undefined !");
1122
1459
  }
1123
1460
 
1461
+ /**
1462
+ * Logs any number of values to the console.
1463
+ *
1464
+ * @function
1465
+ * @param {...any} data - The values to be logged.
1466
+ * @returns {void}
1467
+ */
1468
+
1469
+ export function echo(data) {
1470
+ if (arguments.length > 1) {
1471
+ throw new TypeError('unexpected token ","');
1472
+ }
1473
+ process.stdout.write(data);
1474
+ }
1475
+
1124
1476
  /**
1125
1477
  * Checks whether one or more objects are instances of a given class (or classes),
1126
1478
  * similar to using the `instanceof` operator — but extended to handle arrays
@@ -1151,7 +1503,7 @@ export function instancesof(
1151
1503
 
1152
1504
  if (len < 2) {
1153
1505
  throw new TypeError(
1154
- len == 1
1506
+ len === 1
1155
1507
  ? "instancesof() missing 1 required arguments: 'type'"
1156
1508
  : "instancesof() missing 2 required arguments: 'objs' and 'type'"
1157
1509
  );
@@ -1164,30 +1516,70 @@ export function instancesof(
1164
1516
  }
1165
1517
 
1166
1518
  if (len === 3) {
1167
- switch (arguments[2]) {
1168
- case true:
1169
- case false:
1170
- return isinstances(objs, type, and, logic_or_match, strict);
1519
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1520
+ return isinstancesof(objs, type, and, logic_or_match, strict);
1171
1521
  }
1172
1522
  }
1173
1523
 
1174
1524
  if (len === 4) {
1175
- switch (arguments[3]) {
1176
- case true:
1177
- case false:
1178
- break;
1179
- default:
1180
- throw new TypeError("forth argument must be true or false");
1525
+ if (
1526
+ not(checkType(arguments[3], boolean)) &&
1527
+ not(arguments[3] instanceof Boolean)
1528
+ ) {
1529
+ throw new TypeError("forth argument must be true or false");
1181
1530
  }
1182
1531
 
1183
- switch (arguments[2]) {
1184
- case true:
1185
- case false:
1186
- return isinstances(objs, type, and, logic_or_match, match_or_strict);
1532
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1533
+ return isinstancesof(objs, type, and, logic_or_match, match_or_strict);
1187
1534
  }
1188
1535
  }
1189
1536
 
1190
- return isinstances(objs, type, logic_or_match, match_or_strict, strict);
1537
+ return isinstancesof(objs, type, logic_or_match, match_or_strict, strict);
1538
+ }
1539
+
1540
+ /**
1541
+ * Checks whether an object is an instance of a given class or constructor.
1542
+ *
1543
+ * @function
1544
+ * @param {any} obj - The object to check.
1545
+ * @param {Function} cls - The class or constructor to check against.
1546
+ * @returns {boolean} True if `obj` is an instance of `cls`, otherwise false.
1547
+ * @throws {TypeError} If `cls` is not a valid constructor.
1548
+ */
1549
+
1550
+ export function isinstance(obj, cls) {
1551
+ try {
1552
+ return obj instanceof cls;
1553
+ } catch (error) {
1554
+ throw new TypeError("Right-hand side of 'isinstance' is not callable");
1555
+ }
1556
+ }
1557
+
1558
+ /**
1559
+ * Checks whether one or more objects are instances of a given class (or classes),
1560
+ * similar to using the `instanceof` operator — but extended to handle arrays
1561
+ * and multiple constructors with logical control.
1562
+ *
1563
+ * Works like a plural form of `instanceof`, allowing you to check several objects
1564
+ * against one or more classes, using `"and"` or `"or"` logic.
1565
+ *
1566
+ * @template T - The instance type returned by the constructor(s).
1567
+ * @param {*|Array<*>} objs - The object or array of objects to test.
1568
+ * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
1569
+ * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1570
+ * @param {boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1571
+ * @param {boolean} strict - If `true`, enables strict comparison behavior.
1572
+ * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
1573
+ */
1574
+
1575
+ export function isinstances(
1576
+ objs,
1577
+ type,
1578
+ logic_or_match = and,
1579
+ match_or_strict = true,
1580
+ strict = true
1581
+ ) {
1582
+ return instancesof(objs, type, logic_or_match, match_or_strict, strict);
1191
1583
  }
1192
1584
 
1193
1585
  /**
@@ -1218,7 +1610,7 @@ export function isType(
1218
1610
 
1219
1611
  if (len < 2) {
1220
1612
  throw new TypeError(
1221
- len == 1
1613
+ len === 1
1222
1614
  ? "isType() missing 1 required arguments: 'dataType'"
1223
1615
  : "isType() missing 2 required arguments: 'data' and 'dataType'"
1224
1616
  );
@@ -1231,32 +1623,43 @@ export function isType(
1231
1623
  }
1232
1624
 
1233
1625
  if (len === 3) {
1234
- switch (arguments[2]) {
1235
- case true:
1236
- case false:
1237
- return checkType(data, dataType, and, logic_or_match, strict);
1626
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1627
+ return checkType(data, dataType, and, logic_or_match, strict);
1238
1628
  }
1239
1629
  }
1240
1630
 
1241
1631
  if (len === 4) {
1242
- switch (arguments[3]) {
1243
- case true:
1244
- case false:
1245
- break;
1246
- default:
1247
- throw new TypeError("forth argument must be true or false");
1632
+ if (
1633
+ not(checkType(arguments[3], boolean)) &&
1634
+ not(arguments[3] instanceof Boolean)
1635
+ ) {
1636
+ throw new TypeError("forth argument must be true or false");
1248
1637
  }
1249
1638
 
1250
- switch (arguments[2]) {
1251
- case true:
1252
- case false:
1253
- return checkType(data, dataType, and, logic_or_match, match_or_strict);
1639
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1640
+ return checkType(data, dataType, and, logic_or_match, match_or_strict);
1254
1641
  }
1255
1642
  }
1256
1643
 
1257
1644
  return checkType(data, dataType, logic_or_match, match_or_strict, strict);
1258
1645
  }
1259
1646
 
1647
+ /**
1648
+ * Returns the length of an iterable or object that has a `length` property.
1649
+ *
1650
+ * @function
1651
+ * @param {any} iter - The value to measure. Must have a `length` property.
1652
+ * @returns {number} The length of the given value.
1653
+ * @throws {TypeError} If the value does not have a `length` property.
1654
+ */
1655
+
1656
+ export function len(iter) {
1657
+ if (iter.length === undefined) {
1658
+ throw new TypeError(`type '${typeof iter}' has no len()`);
1659
+ }
1660
+ return iter.length;
1661
+ }
1662
+
1260
1663
  /**
1261
1664
  * Checks whether all provided values have the same length.
1262
1665
  * Each value must have a numeric `length` property (e.g., arrays, strings, typed arrays, etc.).
@@ -1312,6 +1715,35 @@ export function lengths(...objs) {
1312
1715
  return [lens, equal];
1313
1716
  }
1314
1717
 
1718
+ /**
1719
+ * Checks whether all provided values have the same length.
1720
+ * Each value must have a numeric `length` property (e.g., arrays, strings, typed arrays, etc.).
1721
+ *
1722
+ * If all lengths are equal, returns a tuple containing that length and `true`.
1723
+ * Otherwise, returns a tuple containing an array of all detected lengths and `false`.
1724
+ *
1725
+ * @param {...{length: number}} objs - The values to compare by their length property.
1726
+ * @returns {[number | number[], boolean]} A tuple:
1727
+ * - `[length, true]` if all values have the same length.
1728
+ * - `[lengths, false]` if the lengths differ.
1729
+ */
1730
+
1731
+ export function lens(...objs) {
1732
+ return lengths(...objs);
1733
+ }
1734
+
1735
+ /**
1736
+ * Logs any number of values to the console.
1737
+ *
1738
+ * @function
1739
+ * @param {...any} data - The values to be logged.
1740
+ * @returns {void}
1741
+ */
1742
+
1743
+ export function log(...data) {
1744
+ console.log(...data);
1745
+ }
1746
+
1315
1747
  /**
1316
1748
  * Evaluates the truthiness of a given value.
1317
1749
  * Works like the logical NOT operator (`!`), returning `true` if the value is falsy and `false` if it is truthy.
@@ -1332,6 +1764,86 @@ export function not(obj) {
1332
1764
  return obj?.length === 0 || !obj; // handling the object case
1333
1765
  }
1334
1766
 
1767
+ /**
1768
+ * Logs any number of values to the console.
1769
+ *
1770
+ * @function
1771
+ * @param {...any} data - The values to be logged.
1772
+ * @returns {void}
1773
+ */
1774
+
1775
+ export function print(...data) {
1776
+ console.log(...data);
1777
+ }
1778
+
1779
+ /**
1780
+ * Logs any number of values to the console.
1781
+ *
1782
+ * @function
1783
+ * @param {...any} data - The values to be logged.
1784
+ * @returns {void}
1785
+ */
1786
+
1787
+ export function printf(data) {
1788
+ if (arguments.length > 1) {
1789
+ throw new TypeError('unexpected token ","');
1790
+ }
1791
+ process.stdout.write(...data);
1792
+ }
1793
+
1794
+ /**
1795
+ * Logs any number of values to the console.
1796
+ *
1797
+ * @function
1798
+ * @param {...any} data - The values to be logged.
1799
+ * @returns {void}
1800
+ */
1801
+
1802
+ export function println(...data) {
1803
+ console.log(...data);
1804
+ }
1805
+
1806
+ /**
1807
+ * Logs any number of values to the console.
1808
+ *
1809
+ * @function
1810
+ * @param {...any} data - The values to be logged.
1811
+ * @returns {void}
1812
+ */
1813
+
1814
+ export function puts(...data) {
1815
+ console.log(...data);
1816
+ }
1817
+
1818
+ /**
1819
+ * Returns the JavaScript type of a value using the `typeof` operator.
1820
+ *
1821
+ * @function
1822
+ * @param {any} data - The value whose type will be determined.
1823
+ * @returns {string} The type of the value (e.g., "string", "number", "object", "undefined").
1824
+ */
1825
+
1826
+ export function type(data) {
1827
+ return typeof data;
1828
+ }
1829
+
1830
+ /**
1831
+ * Checks whether all provided values are of the same type.
1832
+ * Similar to the `typeof` operator but supports multiple inputs.
1833
+ *
1834
+ * If all values share the same type, returns a tuple containing that type as a string and `true`.
1835
+ * Otherwise, returns a tuple containing an array of the detected types and `false`.
1836
+ *
1837
+ * @param {...*} objs - The values to check.
1838
+ * @returns {[string | string[], boolean]} A tuple:
1839
+ * - `[type, true]` if all values are of the same type.
1840
+ * - `[types, false]` if values have mixed types.
1841
+ */
1842
+
1843
+ export function types(...objs) {
1844
+ return typesof(...objs);
1845
+ }
1846
+
1335
1847
  /**
1336
1848
  * Checks whether all provided values are of the same type.
1337
1849
  * Similar to the `typeof` operator but supports multiple inputs.