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.cjs CHANGED
@@ -32,7 +32,11 @@ const and = "and";
32
32
 
33
33
  /** @type {string} */
34
34
 
35
- const or = "or";
35
+ const bi = "bigint";
36
+
37
+ /** @type {BigIntConstructor} */
38
+
39
+ const BI = BigInt;
36
40
 
37
41
  /** @type {string} */
38
42
 
@@ -40,27 +44,95 @@ const bigint = "bigint";
40
44
 
41
45
  /** @type {string} */
42
46
 
47
+ const bool = "boolean";
48
+
49
+ /** @type {BooleanConstructor} */
50
+
51
+ const Bool = Boolean;
52
+
53
+ /** @type {string} */
54
+
55
+ const boolean = "boolean";
56
+
57
+ /** @type {string} */
58
+
59
+ const fn = "function";
60
+
61
+ /** @type {FunctionConstructor} */
62
+
63
+ const Fn = Function;
64
+
65
+ /** @type {string} */
66
+
67
+ const fun = "function";
68
+
69
+ /** @type {FunctionConstructor} */
70
+
71
+ const Fun = Function;
72
+
73
+ /** @type {string} */
74
+
43
75
  const func = "function";
44
76
 
77
+ /** @type {FunctionConstructor} */
78
+
79
+ const Func = Function;
80
+
81
+ /** @type {null} */
82
+
83
+ const nil = null;
84
+
85
+ /** @type {string} */
86
+
87
+ const num = "number";
88
+
89
+ /** @type {NumberConstructor} */
90
+
91
+ const Num = Number;
92
+
45
93
  /** @type {string} */
46
94
 
47
95
  const number = "number";
48
96
 
49
97
  /** @type {string} */
50
98
 
99
+ const obj = "object";
100
+
101
+ /** @type {ObjectConstructor} */
102
+
103
+ const Obj = Object;
104
+
105
+ /** @type {string} */
106
+
51
107
  const object = "object";
52
108
 
53
109
  /** @type {string} */
54
110
 
111
+ const or = "or";
112
+
113
+ /** @type {string} */
114
+
115
+ const str = "string";
116
+
117
+ /** @type {StringConstructor} */
118
+
119
+ const Str = String;
120
+
121
+ /** @type {string} */
122
+
55
123
  const string = "string";
56
124
 
57
125
  /** @type {string} */
58
126
 
59
- const symbol = "symbol";
127
+ const sym = "symbol";
128
+
129
+ /** @type {SymbolConstructor} */
130
+
131
+ const Sym = Symbol;
60
132
 
61
133
  /** @type {string} */
62
134
 
63
- const boolean = "boolean";
135
+ const symbol = "symbol";
64
136
 
65
137
  /** @type {string} */
66
138
 
@@ -82,17 +154,62 @@ const undef = "undefined";
82
154
  */
83
155
 
84
156
  function checkType(data, dataType, logic, match, strict) {
85
- // if data or dataType is Array must be nested Array
157
+ /** @type {Set<string | null | undefined>} */
158
+
159
+ let setOfTypes = new Set([
160
+ and,
161
+ bi,
162
+ bool,
163
+ fn,
164
+ null,
165
+ num,
166
+ obj,
167
+ or,
168
+ str,
169
+ sym,
170
+ undef,
171
+ undefined,
172
+ ]);
86
173
 
87
174
  if (!(dataType instanceof Array)) {
175
+ if (!setOfTypes.has(dataType)) {
176
+ throw new TypeError("type undefined !");
177
+ }
178
+
88
179
  if (!(data instanceof Array)) {
180
+ if (data === null) {
181
+ return dataType === null;
182
+ }
183
+
184
+ if (dataType === undefined) {
185
+ return data === undefined;
186
+ }
187
+
89
188
  return typeof data === dataType;
90
189
  }
91
190
 
92
- if (logic === and) {
191
+ if (data.length === 0) {
192
+ data[0] = [];
193
+ }
194
+
195
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
93
196
  for (let dt of data) {
94
197
  // 1 step directly in all cases
95
198
 
199
+ if (dt === null) {
200
+ if (dataType !== null) {
201
+ return false;
202
+ }
203
+ continue;
204
+ }
205
+
206
+ if (dataType === undefined) {
207
+ if (dt !== undefined) {
208
+ return false;
209
+ }
210
+ continue;
211
+ }
212
+
96
213
  if (!(typeof dt === dataType)) {
97
214
  return false;
98
215
  }
@@ -108,10 +225,24 @@ function checkType(data, dataType, logic, match, strict) {
108
225
  return true;
109
226
  }
110
227
 
111
- if (logic === or) {
228
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
112
229
  for (let dt of data) {
113
230
  // 1 step directly in all cases
114
231
 
232
+ if (dt === null) {
233
+ if (dataType === null) {
234
+ return true;
235
+ }
236
+ continue;
237
+ }
238
+
239
+ if (dataType === undefined) {
240
+ if (dt === undefined) {
241
+ return true;
242
+ }
243
+ continue;
244
+ }
245
+
115
246
  if (typeof dt === dataType) {
116
247
  return true;
117
248
  }
@@ -134,6 +265,24 @@ function checkType(data, dataType, logic, match, strict) {
134
265
  for (let dtype of dataType) {
135
266
  // 1 step directly in all cases
136
267
 
268
+ if (!setOfTypes.has(dtype)) {
269
+ throw new TypeError(`type ${dtype} undefined !`);
270
+ }
271
+
272
+ if (data === null) {
273
+ if (dtype === null) {
274
+ return true;
275
+ }
276
+ continue;
277
+ }
278
+
279
+ if (dtype === undefined) {
280
+ if (data === undefined) {
281
+ return true;
282
+ }
283
+ continue;
284
+ }
285
+
137
286
  if (typeof data === dtype) {
138
287
  return true;
139
288
  }
@@ -149,10 +298,32 @@ function checkType(data, dataType, logic, match, strict) {
149
298
  return false;
150
299
  }
151
300
 
152
- if (!match) {
153
- if (logic === and) {
301
+ if (data.length === 0) {
302
+ data[0] = [];
303
+ }
304
+
305
+ if (not(match)) {
306
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
154
307
  outerLoop: for (let dt of data) {
155
308
  for (let dtype of dataType) {
309
+ if (!setOfTypes.has(dtype)) {
310
+ throw new TypeError(`type ${dtype} undefined !`);
311
+ }
312
+
313
+ if (dt === null) {
314
+ if (dtype === null) {
315
+ continue outerLoop;
316
+ }
317
+ continue;
318
+ }
319
+
320
+ if (dtype === undefined) {
321
+ if (dt === undefined) {
322
+ continue outerLoop;
323
+ }
324
+ continue;
325
+ }
326
+
156
327
  if (typeof dt === dtype) {
157
328
  continue outerLoop;
158
329
  }
@@ -190,6 +361,24 @@ function checkType(data, dataType, logic, match, strict) {
190
361
 
191
362
  // // // the same as this
192
363
 
364
+ // // // if (!setOfTypes.has(dtype)) {
365
+ // // // throw new TypeError(`type ${dtype} undefined !`);
366
+ // // // }
367
+
368
+ // // // if (data[0] === null) {
369
+ // // // if (dtype === null) {
370
+ // // // return true;
371
+ // // // }
372
+ // // // continue;
373
+ // // // }
374
+
375
+ // // // if (dtype === undefined) {
376
+ // // // if (data[0] === undefined) {
377
+ // // // return true;
378
+ // // // }
379
+ // // // continue;
380
+ // // // }
381
+
193
382
  // // // if (typeof data[0] === dtype) {
194
383
  // // // return true;
195
384
  // // // }
@@ -222,6 +411,24 @@ function checkType(data, dataType, logic, match, strict) {
222
411
 
223
412
  // // // the same as this
224
413
 
414
+ // // // if (!setOfTypes.has(dataType[0])) {
415
+ // // // throw new TypeError("type undefined !");
416
+ // // // }
417
+
418
+ // // // if (dt === null) {
419
+ // // // if (dataType[0] !== null) {
420
+ // // // return false;
421
+ // // // }
422
+ // // // continue;
423
+ // // // }
424
+
425
+ // // // if (dataType[0] === undefined) {
426
+ // // // if (dt !== undefined) {
427
+ // // // return false;
428
+ // // // }
429
+ // // // continue;
430
+ // // // }
431
+
225
432
  // // // if (!(typeof dt === dataType[0])) {
226
433
  // // // return false;
227
434
  // // // }
@@ -277,9 +484,27 @@ function checkType(data, dataType, logic, match, strict) {
277
484
  // return true;
278
485
  }
279
486
 
280
- if (logic === or) {
487
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
281
488
  for (let dt of data) {
282
489
  for (let dtype of dataType) {
490
+ if (!setOfTypes.has(dtype)) {
491
+ throw new TypeError(`type ${dtype} undefined !`);
492
+ }
493
+
494
+ if (dt === null) {
495
+ if (dtype === null) {
496
+ return true;
497
+ }
498
+ continue;
499
+ }
500
+
501
+ if (dtype === undefined) {
502
+ if (dt === undefined) {
503
+ return true;
504
+ }
505
+ continue;
506
+ }
507
+
283
508
  if (typeof dt === dtype) {
284
509
  return true;
285
510
  }
@@ -313,6 +538,24 @@ function checkType(data, dataType, logic, match, strict) {
313
538
 
314
539
  // // // the same as this
315
540
 
541
+ // // // if (!setOfTypes.has(dtype)) {
542
+ // // // throw new TypeError(`type ${dtype} undefined !`);
543
+ // // // }
544
+
545
+ // // // if (data[0] === null) {
546
+ // // // if (dtype === null) {
547
+ // // // return true;
548
+ // // // }
549
+ // // // continue;
550
+ // // // }
551
+
552
+ // // // if (dtype === undefined) {
553
+ // // // if (data[0] === undefined) {
554
+ // // // return true;
555
+ // // // }
556
+ // // // continue;
557
+ // // // }
558
+
316
559
  // // // if (typeof data[0] === dtype) {
317
560
  // // // return true;
318
561
  // // // }
@@ -347,9 +590,27 @@ function checkType(data, dataType, logic, match, strict) {
347
590
 
348
591
  // // // the same as this
349
592
 
350
- // // if (typeof dt === dataType[0]) {
351
- // // return true;
352
- // // }
593
+ // // // if (!setOfTypes.has(dataType[0])) {
594
+ // // // throw new TypeError("type undefined !");
595
+ // // // }
596
+
597
+ // // // if (dt === null) {
598
+ // // // if (dataType[0] === null) {
599
+ // // // return true;
600
+ // // // }
601
+ // // // continue;
602
+ // // // }
603
+
604
+ // // // if (dataType[0] === undefined) {
605
+ // // // if (dt === undefined) {
606
+ // // // return true;
607
+ // // // }
608
+ // // // continue;
609
+ // // // }
610
+
611
+ // // // if (typeof dt === dataType[0]) {
612
+ // // // return true;
613
+ // // // }
353
614
  // // }
354
615
 
355
616
  // // shared return
@@ -458,10 +719,28 @@ function checkType(data, dataType, logic, match, strict) {
458
719
  min = dataType.length;
459
720
  }
460
721
 
461
- if (logic === and) {
722
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
462
723
  for (let i = 0; i < min; ++i) {
463
724
  // 1 step directly in all cases
464
725
 
726
+ if (!setOfTypes.has(dataType[i])) {
727
+ throw new TypeError(`type ${dataType[i]} undefined !`);
728
+ }
729
+
730
+ if (data[i] === null) {
731
+ if (dataType[i] !== null) {
732
+ return false;
733
+ }
734
+ continue;
735
+ }
736
+
737
+ if (dataType[i] === undefined) {
738
+ if (data[i] !== undefined) {
739
+ return false;
740
+ }
741
+ continue;
742
+ }
743
+
465
744
  if (!(typeof data[i] === dataType[i])) {
466
745
  return false;
467
746
  }
@@ -479,10 +758,28 @@ function checkType(data, dataType, logic, match, strict) {
479
758
  return true;
480
759
  }
481
760
 
482
- if (logic === or) {
761
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
483
762
  for (let i = 0; i < min; ++i) {
484
763
  // 1 step directly in all cases
485
764
 
765
+ if (!setOfTypes.has(dataType[i])) {
766
+ throw new TypeError(`type ${dataType[i]} undefined !`);
767
+ }
768
+
769
+ if (data[i] === null) {
770
+ if (dataType[i] === null) {
771
+ return true;
772
+ }
773
+ continue;
774
+ }
775
+
776
+ if (dataType[i] === undefined) {
777
+ if (data[i] === undefined) {
778
+ return true;
779
+ }
780
+ continue;
781
+ }
782
+
486
783
  if (typeof data[i] === dataType[i]) {
487
784
  return true;
488
785
  }
@@ -503,10 +800,28 @@ function checkType(data, dataType, logic, match, strict) {
503
800
  throw new TypeError("logic type undefined !");
504
801
  }
505
802
 
506
- if (logic === and) {
803
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
507
804
  for (let i = 0; i < data.length; ++i) {
508
805
  // 1 step directly in all cases
509
806
 
807
+ if (!setOfTypes.has(dataType[i])) {
808
+ throw new TypeError(`type ${dataType[i]} undefined !`);
809
+ }
810
+
811
+ if (data[i] === null) {
812
+ if (dataType[i] !== null) {
813
+ return false;
814
+ }
815
+ continue;
816
+ }
817
+
818
+ if (dataType[i] === undefined) {
819
+ if (data[i] !== undefined) {
820
+ return false;
821
+ }
822
+ continue;
823
+ }
824
+
510
825
  if (!(typeof data[i] === dataType[i])) {
511
826
  return false;
512
827
  }
@@ -524,10 +839,28 @@ function checkType(data, dataType, logic, match, strict) {
524
839
  return true;
525
840
  }
526
841
 
527
- if (logic === or) {
842
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
528
843
  for (let i = 0; i < data.length; ++i) {
529
844
  // 1 step directly in all cases
530
845
 
846
+ if (!setOfTypes.has(dataType[i])) {
847
+ throw new TypeError(`type ${dataType[i]} undefined !`);
848
+ }
849
+
850
+ if (data[i] === null) {
851
+ if (dataType[i] === null) {
852
+ return true;
853
+ }
854
+ continue;
855
+ }
856
+
857
+ if (dataType[i] === undefined) {
858
+ if (data[i] === undefined) {
859
+ return true;
860
+ }
861
+ continue;
862
+ }
863
+
531
864
  if (typeof data[i] === dataType[i]) {
532
865
  return true;
533
866
  }
@@ -565,7 +898,7 @@ function checkType(data, dataType, logic, match, strict) {
565
898
  * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
566
899
  */
567
900
 
568
- function isinstances(objs, type, logic, match, strict) {
901
+ function isinstancesof(objs, type, logic, match, strict) {
569
902
  if (!(type instanceof Array)) {
570
903
  // uncomment (return objs instanceof type)
571
904
  // to enable the 1/4 of (one to one)
@@ -586,7 +919,7 @@ function isinstances(objs, type, logic, match, strict) {
586
919
  );
587
920
  }
588
921
 
589
- if (logic === and) {
922
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
590
923
  for (let obj of objs) {
591
924
  // 1 step directly in all cases
592
925
 
@@ -611,7 +944,7 @@ function isinstances(objs, type, logic, match, strict) {
611
944
  return true;
612
945
  }
613
946
 
614
- if (logic === or) {
947
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
615
948
  for (let obj of objs) {
616
949
  // 1 step directly in all cases
617
950
 
@@ -680,8 +1013,12 @@ function isinstances(objs, type, logic, match, strict) {
680
1013
  );
681
1014
  }
682
1015
 
683
- if (!match) {
684
- if (logic === and) {
1016
+ if (not(match)) {
1017
+ if (objs.length === 0) {
1018
+ objs[0] = [];
1019
+ }
1020
+
1021
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
685
1022
  outerLoop: for (let obj of objs) {
686
1023
  for (let dt of type) {
687
1024
  try {
@@ -814,7 +1151,7 @@ function isinstances(objs, type, logic, match, strict) {
814
1151
  // return true;
815
1152
  }
816
1153
 
817
- if (logic === or) {
1154
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
818
1155
  for (let obj of objs) {
819
1156
  for (let dt of type) {
820
1157
  try {
@@ -1001,7 +1338,7 @@ function isinstances(objs, type, logic, match, strict) {
1001
1338
  min = type.length;
1002
1339
  }
1003
1340
 
1004
- if (logic === and) {
1341
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
1005
1342
  for (let i = 0; i < min; ++i) {
1006
1343
  // 1 step directly in all cases
1007
1344
 
@@ -1028,7 +1365,7 @@ function isinstances(objs, type, logic, match, strict) {
1028
1365
  return true;
1029
1366
  }
1030
1367
 
1031
- if (logic === or) {
1368
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
1032
1369
  for (let i = 0; i < min; ++i) {
1033
1370
  // 1 step directly in all cases
1034
1371
 
@@ -1058,7 +1395,7 @@ function isinstances(objs, type, logic, match, strict) {
1058
1395
  throw new TypeError("logic type undefined !");
1059
1396
  }
1060
1397
 
1061
- if (logic === and) {
1398
+ if (logic === and || (logic instanceof String && logic.valueOf() === and)) {
1062
1399
  for (let i = 0; i < objs.length; ++i) {
1063
1400
  // 1 step directly in all cases
1064
1401
 
@@ -1085,7 +1422,7 @@ function isinstances(objs, type, logic, match, strict) {
1085
1422
  return true;
1086
1423
  }
1087
1424
 
1088
- if (logic === or) {
1425
+ if (logic === or || (logic instanceof String && logic.valueOf() === or)) {
1089
1426
  for (let i = 0; i < objs.length; ++i) {
1090
1427
  // 1 step directly in all cases
1091
1428
 
@@ -1115,6 +1452,21 @@ function isinstances(objs, type, logic, match, strict) {
1115
1452
  throw new TypeError("logic type undefined !");
1116
1453
  }
1117
1454
 
1455
+ /**
1456
+ * Logs any number of values to the console.
1457
+ *
1458
+ * @function
1459
+ * @param {...any} data - The values to be logged.
1460
+ * @returns {void}
1461
+ */
1462
+
1463
+ function echo(data) {
1464
+ if (arguments.length > 1) {
1465
+ throw new TypeError('unexpected token ","');
1466
+ }
1467
+ process.stdout.write(data);
1468
+ }
1469
+
1118
1470
  /**
1119
1471
  * Checks whether one or more objects are instances of a given class (or classes),
1120
1472
  * similar to using the `instanceof` operator — but extended to handle arrays
@@ -1145,7 +1497,7 @@ function instancesof(
1145
1497
 
1146
1498
  if (len < 2) {
1147
1499
  throw new TypeError(
1148
- len == 1
1500
+ len === 1
1149
1501
  ? "instancesof() missing 1 required arguments: 'type'"
1150
1502
  : "instancesof() missing 2 required arguments: 'objs' and 'type'"
1151
1503
  );
@@ -1158,30 +1510,70 @@ function instancesof(
1158
1510
  }
1159
1511
 
1160
1512
  if (len === 3) {
1161
- switch (arguments[2]) {
1162
- case true:
1163
- case false:
1164
- return isinstances(objs, type, and, logic_or_match, strict);
1513
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1514
+ return isinstancesof(objs, type, and, logic_or_match, strict);
1165
1515
  }
1166
1516
  }
1167
1517
 
1168
1518
  if (len === 4) {
1169
- switch (arguments[3]) {
1170
- case true:
1171
- case false:
1172
- break;
1173
- default:
1174
- throw new TypeError("forth argument must be true or false");
1519
+ if (
1520
+ not(checkType(arguments[3], boolean)) &&
1521
+ not(arguments[3] instanceof Boolean)
1522
+ ) {
1523
+ throw new TypeError("forth argument must be true or false");
1175
1524
  }
1176
1525
 
1177
- switch (arguments[2]) {
1178
- case true:
1179
- case false:
1180
- return isinstances(objs, type, and, logic_or_match, match_or_strict);
1526
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1527
+ return isinstancesof(objs, type, and, logic_or_match, match_or_strict);
1181
1528
  }
1182
1529
  }
1183
1530
 
1184
- return isinstances(objs, type, logic_or_match, match_or_strict, strict);
1531
+ return isinstancesof(objs, type, logic_or_match, match_or_strict, strict);
1532
+ }
1533
+
1534
+ /**
1535
+ * Checks whether an object is an instance of a given class or constructor.
1536
+ *
1537
+ * @function
1538
+ * @param {any} obj - The object to check.
1539
+ * @param {Function} cls - The class or constructor to check against.
1540
+ * @returns {boolean} True if `obj` is an instance of `cls`, otherwise false.
1541
+ * @throws {TypeError} If `cls` is not a valid constructor.
1542
+ */
1543
+
1544
+ function isinstance(obj, cls) {
1545
+ try {
1546
+ return obj instanceof cls;
1547
+ } catch (error) {
1548
+ throw new TypeError("Right-hand side of 'isinstance' is not callable");
1549
+ }
1550
+ }
1551
+
1552
+ /**
1553
+ * Checks whether one or more objects are instances of a given class (or classes),
1554
+ * similar to using the `instanceof` operator — but extended to handle arrays
1555
+ * and multiple constructors with logical control.
1556
+ *
1557
+ * Works like a plural form of `instanceof`, allowing you to check several objects
1558
+ * against one or more classes, using `"and"` or `"or"` logic.
1559
+ *
1560
+ * @template T - The instance type returned by the constructor(s).
1561
+ * @param {*|Array<*>} objs - The object or array of objects to test.
1562
+ * @param {(new (...args: any[]) => T) | Array<new (...args: any[]) => T>} type - The constructor or list of constructors to test against.
1563
+ * @param {"and" | "or" | boolean} logic_or_match - Logic mode: `"and"` requires all matches, `"or"` allows any match.
1564
+ * @param {boolean} match_or_strict - Whether to compare classes names strictly or loosely.
1565
+ * @param {boolean} strict - If `true`, enables strict comparison behavior.
1566
+ * @returns {boolean} `true` if the provided object(s) match the given type(s) according to the chosen logic, otherwise `false`.
1567
+ */
1568
+
1569
+ function isinstances(
1570
+ objs,
1571
+ type,
1572
+ logic_or_match = and,
1573
+ match_or_strict = true,
1574
+ strict = true
1575
+ ) {
1576
+ return instancesof(objs, type, logic_or_match, match_or_strict, strict);
1185
1577
  }
1186
1578
 
1187
1579
  /**
@@ -1212,7 +1604,7 @@ function isType(
1212
1604
 
1213
1605
  if (len < 2) {
1214
1606
  throw new TypeError(
1215
- len == 1
1607
+ len === 1
1216
1608
  ? "isType() missing 1 required arguments: 'dataType'"
1217
1609
  : "isType() missing 2 required arguments: 'data' and 'dataType'"
1218
1610
  );
@@ -1225,32 +1617,43 @@ function isType(
1225
1617
  }
1226
1618
 
1227
1619
  if (len === 3) {
1228
- switch (arguments[2]) {
1229
- case true:
1230
- case false:
1231
- return checkType(data, dataType, and, logic_or_match, strict);
1620
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1621
+ return checkType(data, dataType, and, logic_or_match, strict);
1232
1622
  }
1233
1623
  }
1234
1624
 
1235
1625
  if (len === 4) {
1236
- switch (arguments[3]) {
1237
- case true:
1238
- case false:
1239
- break;
1240
- default:
1241
- throw new TypeError("forth argument must be true or false");
1626
+ if (
1627
+ not(checkType(arguments[3], boolean)) &&
1628
+ not(arguments[3] instanceof Boolean)
1629
+ ) {
1630
+ throw new TypeError("forth argument must be true or false");
1242
1631
  }
1243
1632
 
1244
- switch (arguments[2]) {
1245
- case true:
1246
- case false:
1247
- return checkType(data, dataType, and, logic_or_match, match_or_strict);
1633
+ if (checkType(arguments[2], boolean) || arguments[2] instanceof Boolean) {
1634
+ return checkType(data, dataType, and, logic_or_match, match_or_strict);
1248
1635
  }
1249
1636
  }
1250
1637
 
1251
1638
  return checkType(data, dataType, logic_or_match, match_or_strict, strict);
1252
1639
  }
1253
1640
 
1641
+ /**
1642
+ * Returns the length of an iterable or object that has a `length` property.
1643
+ *
1644
+ * @function
1645
+ * @param {any} iter - The value to measure. Must have a `length` property.
1646
+ * @returns {number} The length of the given value.
1647
+ * @throws {TypeError} If the value does not have a `length` property.
1648
+ */
1649
+
1650
+ function len(iter) {
1651
+ if (iter.length === undefined) {
1652
+ throw new TypeError(`type '${typeof iter}' has no len()`);
1653
+ }
1654
+ return iter.length;
1655
+ }
1656
+
1254
1657
  /**
1255
1658
  * Checks whether all provided values have the same length.
1256
1659
  * Each value must have a numeric `length` property (e.g., arrays, strings, typed arrays, etc.).
@@ -1306,6 +1709,35 @@ function lengths(...objs) {
1306
1709
  return [lens, equal];
1307
1710
  }
1308
1711
 
1712
+ /**
1713
+ * Checks whether all provided values have the same length.
1714
+ * Each value must have a numeric `length` property (e.g., arrays, strings, typed arrays, etc.).
1715
+ *
1716
+ * If all lengths are equal, returns a tuple containing that length and `true`.
1717
+ * Otherwise, returns a tuple containing an array of all detected lengths and `false`.
1718
+ *
1719
+ * @param {...{length: number}} objs - The values to compare by their length property.
1720
+ * @returns {[number | number[], boolean]} A tuple:
1721
+ * - `[length, true]` if all values have the same length.
1722
+ * - `[lengths, false]` if the lengths differ.
1723
+ */
1724
+
1725
+ function lens(...objs) {
1726
+ return lengths(...objs);
1727
+ }
1728
+
1729
+ /**
1730
+ * Logs any number of values to the console.
1731
+ *
1732
+ * @function
1733
+ * @param {...any} data - The values to be logged.
1734
+ * @returns {void}
1735
+ */
1736
+
1737
+ function log(...data) {
1738
+ console.log(...data);
1739
+ }
1740
+
1309
1741
  /**
1310
1742
  * Evaluates the truthiness of a given value.
1311
1743
  * Works like the logical NOT operator (`!`), returning `true` if the value is falsy and `false` if it is truthy.
@@ -1326,6 +1758,86 @@ function not(obj) {
1326
1758
  return obj?.length === 0 || !obj; // handling the object case
1327
1759
  }
1328
1760
 
1761
+ /**
1762
+ * Logs any number of values to the console.
1763
+ *
1764
+ * @function
1765
+ * @param {...any} data - The values to be logged.
1766
+ * @returns {void}
1767
+ */
1768
+
1769
+ function print(...data) {
1770
+ console.log(...data);
1771
+ }
1772
+
1773
+ /**
1774
+ * Logs any number of values to the console.
1775
+ *
1776
+ * @function
1777
+ * @param {...any} data - The values to be logged.
1778
+ * @returns {void}
1779
+ */
1780
+
1781
+ function printf(data) {
1782
+ if (arguments.length > 1) {
1783
+ throw new TypeError('unexpected token ","');
1784
+ }
1785
+ process.stdout.write(...data);
1786
+ }
1787
+
1788
+ /**
1789
+ * Logs any number of values to the console.
1790
+ *
1791
+ * @function
1792
+ * @param {...any} data - The values to be logged.
1793
+ * @returns {void}
1794
+ */
1795
+
1796
+ function println(...data) {
1797
+ console.log(...data);
1798
+ }
1799
+
1800
+ /**
1801
+ * Logs any number of values to the console.
1802
+ *
1803
+ * @function
1804
+ * @param {...any} data - The values to be logged.
1805
+ * @returns {void}
1806
+ */
1807
+
1808
+ function puts(...data) {
1809
+ console.log(...data);
1810
+ }
1811
+
1812
+ /**
1813
+ * Returns the JavaScript type of a value using the `typeof` operator.
1814
+ *
1815
+ * @function
1816
+ * @param {any} data - The value whose type will be determined.
1817
+ * @returns {string} The type of the value (e.g., "string", "number", "object", "undefined").
1818
+ */
1819
+
1820
+ function type(data) {
1821
+ return typeof data;
1822
+ }
1823
+
1824
+ /**
1825
+ * Checks whether all provided values are of the same type.
1826
+ * Similar to the `typeof` operator but supports multiple inputs.
1827
+ *
1828
+ * If all values share the same type, returns a tuple containing that type as a string and `true`.
1829
+ * Otherwise, returns a tuple containing an array of the detected types and `false`.
1830
+ *
1831
+ * @param {...*} objs - The values to check.
1832
+ * @returns {[string | string[], boolean]} A tuple:
1833
+ * - `[type, true]` if all values are of the same type.
1834
+ * - `[types, false]` if values have mixed types.
1835
+ */
1836
+
1837
+ function types(...objs) {
1838
+ return typesof(...objs);
1839
+ }
1840
+
1329
1841
  /**
1330
1842
  * Checks whether all provided values are of the same type.
1331
1843
  * Similar to the `typeof` operator but supports multiple inputs.
@@ -1623,19 +2135,50 @@ if (require.main === module) {
1623
2135
 
1624
2136
  module.exports = {
1625
2137
  and,
1626
- or,
2138
+ bi,
2139
+ BI,
1627
2140
  bigint,
2141
+ bool,
2142
+ Bool,
2143
+ boolean,
2144
+ fn,
2145
+ Fn,
2146
+ fun,
2147
+ Fun,
1628
2148
  func,
2149
+ Func,
2150
+ nil,
2151
+ num,
2152
+ Num,
1629
2153
  number,
2154
+ obj,
2155
+ Obj,
1630
2156
  object,
2157
+ or,
2158
+ str,
2159
+ Str,
1631
2160
  string,
2161
+ sym,
2162
+ Sym,
1632
2163
  symbol,
1633
- boolean,
1634
2164
  undef,
2165
+
2166
+ echo,
1635
2167
  instancesof,
2168
+ isinstance,
2169
+ isinstances,
1636
2170
  isType,
2171
+ len,
1637
2172
  lengths,
2173
+ lens,
2174
+ log,
1638
2175
  not,
2176
+ print,
2177
+ printf,
2178
+ println,
2179
+ puts,
2180
+ type,
2181
+ types,
1639
2182
  typesof,
1640
2183
  $,
1641
2184
  };