@xnoxs/flux-lang 3.1.2 → 3.2.1

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/src/stdlib.js CHANGED
@@ -6,17 +6,44 @@
6
6
 
7
7
  // ── Detection: which stdlib symbols appear in compiled JS? ───────────────────
8
8
  const STDLIB_SYMBOLS = [
9
- 'range', 'zip', 'enumerate', 'clamp', 'sum', 'product',
10
- 'flatten', 'chunk', 'unique', 'groupBy', 'sortBy',
11
- 'pick', 'omit', 'deepEqual', 'deepClone',
12
- 'sleep', 'retry', 'memoize',
13
- 'pipe', 'compose', 'partial', 'curry',
14
- 'capitalize', 'camelCase', 'snakeCase', 'kebabCase', 'truncate', 'pad',
15
- 'randInt', 'sample', 'shuffle',
16
- 'mapValues', 'filterValues', 'fromEntries',
17
- // Array pipe helpers — standalone wrappers around Array.prototype methods
9
+ // Sequences
10
+ 'range', 'zip', 'enumerate', 'flatten', 'chunk', 'unique', 'groupBy', 'sortBy',
11
+
12
+ // Array pipe helpers
18
13
  'map', 'filter', 'reduce', 'forEach', 'find', 'findIndex',
19
14
  'some', 'every', 'join', 'sort', 'flat', 'flatMap', 'includes',
15
+
16
+ // Array extras
17
+ 'first', 'last', 'take', 'drop', 'takeWhile', 'dropWhile',
18
+ 'compact', 'intersection', 'difference', 'arrayUnion', 'unzip',
19
+ 'countBy', 'minBy', 'maxBy', 'toPairs', 'partition',
20
+ 'count', 'head', 'tail', 'nth', 'rotate', 'sliding',
21
+
22
+ // Math
23
+ 'clamp', 'sum', 'product',
24
+ 'min', 'max', 'abs', 'floor', 'ceil', 'round',
25
+ 'mean', 'median', 'stdDev', 'lerp',
26
+ 'randInt', 'sample', 'shuffle',
27
+
28
+ // Objects
29
+ 'pick', 'omit', 'deepEqual', 'deepClone',
30
+ 'mapValues', 'filterValues', 'fromEntries',
31
+ 'keys', 'values', 'entries', 'merge', 'invert', 'defaults',
32
+
33
+ // Strings
34
+ 'capitalize', 'camelCase', 'snakeCase', 'kebabCase', 'truncate', 'pad',
35
+ 'padStart', 'padEnd', 'trim', 'trimStart', 'trimEnd',
36
+ 'words', 'lines', 'startsWith', 'endsWith', 'repeat', 'replaceAll', 'reverseStr',
37
+
38
+ // Type checks
39
+ 'isNil', 'isString', 'isNumber', 'isArray', 'isObject', 'isFunction', 'isBool',
40
+
41
+ // Async
42
+ 'sleep', 'retry', 'memoize', 'timeout', 'debounce', 'throttle', 'allSettled',
43
+
44
+ // Functional
45
+ 'pipe', 'compose', 'partial', 'curry',
46
+ 'identity', 'noop', 'once', 'flip', 'complement',
20
47
  ];
21
48
 
22
49
  /**
@@ -35,7 +62,6 @@ function buildStdlib(symbols) {
35
62
  const parts = ['// ── Flux stdlib ──'];
36
63
 
37
64
  // ── Array pipe helpers ─────────────────────────────────────────────────────
38
- // Standalone wrappers so |> map(...) / |> filter(...) etc. work correctly.
39
65
 
40
66
  if (needed.has('map')) {
41
67
  parts.push(`
@@ -180,6 +206,171 @@ function sortBy(arr, fn) {
180
206
  }`);
181
207
  }
182
208
 
209
+ // ── Array extras ───────────────────────────────────────────────────────────
210
+
211
+ if (needed.has('first') || needed.has('head')) {
212
+ parts.push(`
213
+ function first(arr) { return arr[0]; }
214
+ function head(arr) { return arr[0]; }`);
215
+ }
216
+
217
+ if (needed.has('last')) {
218
+ parts.push(`
219
+ function last(arr) { return arr[arr.length - 1]; }`);
220
+ }
221
+
222
+ if (needed.has('tail')) {
223
+ parts.push(`
224
+ function tail(arr) { return arr.slice(1); }`);
225
+ }
226
+
227
+ if (needed.has('nth')) {
228
+ parts.push(`
229
+ function nth(arr, n) { return n < 0 ? arr[arr.length + n] : arr[n]; }`);
230
+ }
231
+
232
+ if (needed.has('take')) {
233
+ parts.push(`
234
+ function take(arr, n) { return arr.slice(0, n); }`);
235
+ }
236
+
237
+ if (needed.has('drop')) {
238
+ parts.push(`
239
+ function drop(arr, n) { return arr.slice(n); }`);
240
+ }
241
+
242
+ if (needed.has('takeWhile')) {
243
+ parts.push(`
244
+ function takeWhile(arr, fn) {
245
+ var i = 0;
246
+ while (i < arr.length && fn(arr[i])) i++;
247
+ return arr.slice(0, i);
248
+ }`);
249
+ }
250
+
251
+ if (needed.has('dropWhile')) {
252
+ parts.push(`
253
+ function dropWhile(arr, fn) {
254
+ var i = 0;
255
+ while (i < arr.length && fn(arr[i])) i++;
256
+ return arr.slice(i);
257
+ }`);
258
+ }
259
+
260
+ if (needed.has('compact')) {
261
+ parts.push(`
262
+ function compact(arr) {
263
+ return arr.filter(function(v) { return v != null && v !== false && v !== 0 && v !== ''; });
264
+ }`);
265
+ }
266
+
267
+ if (needed.has('intersection')) {
268
+ parts.push(`
269
+ function intersection(a, b) {
270
+ var s = new Set(b);
271
+ return a.filter(function(v) { return s.has(v); });
272
+ }`);
273
+ }
274
+
275
+ if (needed.has('difference')) {
276
+ parts.push(`
277
+ function difference(a, b) {
278
+ var s = new Set(b);
279
+ return a.filter(function(v) { return !s.has(v); });
280
+ }`);
281
+ }
282
+
283
+ if (needed.has('arrayUnion')) {
284
+ parts.push(`
285
+ function arrayUnion(a, b) {
286
+ return Array.from(new Set(a.concat(b)));
287
+ }`);
288
+ }
289
+
290
+ if (needed.has('unzip')) {
291
+ parts.push(`
292
+ function unzip(pairs) {
293
+ var a = [], b = [];
294
+ for (var i = 0; i < pairs.length; i++) { a.push(pairs[i][0]); b.push(pairs[i][1]); }
295
+ return [a, b];
296
+ }`);
297
+ }
298
+
299
+ if (needed.has('countBy')) {
300
+ parts.push(`
301
+ function countBy(arr, fn) {
302
+ return arr.reduce(function(acc, v) {
303
+ var k = typeof fn === 'function' ? fn(v) : v[fn];
304
+ acc[k] = (acc[k] || 0) + 1;
305
+ return acc;
306
+ }, {});
307
+ }`);
308
+ }
309
+
310
+ if (needed.has('minBy')) {
311
+ parts.push(`
312
+ function minBy(arr, fn) {
313
+ if (!arr.length) return undefined;
314
+ return arr.reduce(function(best, v) {
315
+ return (typeof fn === 'function' ? fn(v) : v[fn]) < (typeof fn === 'function' ? fn(best) : best[fn]) ? v : best;
316
+ });
317
+ }`);
318
+ }
319
+
320
+ if (needed.has('maxBy')) {
321
+ parts.push(`
322
+ function maxBy(arr, fn) {
323
+ if (!arr.length) return undefined;
324
+ return arr.reduce(function(best, v) {
325
+ return (typeof fn === 'function' ? fn(v) : v[fn]) > (typeof fn === 'function' ? fn(best) : best[fn]) ? v : best;
326
+ });
327
+ }`);
328
+ }
329
+
330
+ if (needed.has('toPairs')) {
331
+ parts.push(`
332
+ function toPairs(obj) {
333
+ return Object.keys(obj).map(function(k) { return [k, obj[k]]; });
334
+ }`);
335
+ }
336
+
337
+ if (needed.has('partition')) {
338
+ parts.push(`
339
+ function partition(arr, fn) {
340
+ var yes = [], no = [];
341
+ arr.forEach(function(v) { (fn(v) ? yes : no).push(v); });
342
+ return [yes, no];
343
+ }`);
344
+ }
345
+
346
+ if (needed.has('count')) {
347
+ parts.push(`
348
+ function count(arr, fn) {
349
+ if (typeof fn !== 'function') return arr.length;
350
+ return arr.reduce(function(n, v) { return fn(v) ? n + 1 : n; }, 0);
351
+ }`);
352
+ }
353
+
354
+ if (needed.has('rotate')) {
355
+ parts.push(`
356
+ function rotate(arr, n) {
357
+ var len = arr.length;
358
+ if (!len) return [];
359
+ var k = ((n % len) + len) % len;
360
+ return arr.slice(k).concat(arr.slice(0, k));
361
+ }`);
362
+ }
363
+
364
+ if (needed.has('sliding')) {
365
+ parts.push(`
366
+ function sliding(arr, size, step) {
367
+ step = step || 1;
368
+ var out = [];
369
+ for (var i = 0; i + size <= arr.length; i += step) out.push(arr.slice(i, i + size));
370
+ return out;
371
+ }`);
372
+ }
373
+
183
374
  // ── Math ───────────────────────────────────────────────────────────────────
184
375
 
185
376
  if (needed.has('clamp')) {
@@ -203,6 +394,79 @@ function product(arr) {
203
394
  }`);
204
395
  }
205
396
 
397
+ if (needed.has('min')) {
398
+ parts.push(`
399
+ function min(arr) {
400
+ if (arguments.length > 1) return Math.min.apply(null, arguments);
401
+ return Math.min.apply(null, arr);
402
+ }`);
403
+ }
404
+
405
+ if (needed.has('max')) {
406
+ parts.push(`
407
+ function max(arr) {
408
+ if (arguments.length > 1) return Math.max.apply(null, arguments);
409
+ return Math.max.apply(null, arr);
410
+ }`);
411
+ }
412
+
413
+ if (needed.has('abs')) {
414
+ parts.push(`
415
+ function abs(n) { return Math.abs(n); }`);
416
+ }
417
+
418
+ if (needed.has('floor')) {
419
+ parts.push(`
420
+ function floor(n) { return Math.floor(n); }`);
421
+ }
422
+
423
+ if (needed.has('ceil')) {
424
+ parts.push(`
425
+ function ceil(n) { return Math.ceil(n); }`);
426
+ }
427
+
428
+ if (needed.has('round')) {
429
+ parts.push(`
430
+ function round(n, decimals) {
431
+ if (decimals == null) return Math.round(n);
432
+ var f = Math.pow(10, decimals);
433
+ return Math.round(n * f) / f;
434
+ }`);
435
+ }
436
+
437
+ if (needed.has('mean')) {
438
+ parts.push(`
439
+ function mean(arr) {
440
+ if (!arr.length) return 0;
441
+ return arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
442
+ }`);
443
+ }
444
+
445
+ if (needed.has('median')) {
446
+ parts.push(`
447
+ function median(arr) {
448
+ if (!arr.length) return 0;
449
+ var s = arr.slice().sort(function(a, b) { return a - b; });
450
+ var m = Math.floor(s.length / 2);
451
+ return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
452
+ }`);
453
+ }
454
+
455
+ if (needed.has('stdDev')) {
456
+ parts.push(`
457
+ function stdDev(arr) {
458
+ if (!arr.length) return 0;
459
+ var m = arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
460
+ var variance = arr.reduce(function(acc, v) { return acc + (v - m) * (v - m); }, 0) / arr.length;
461
+ return Math.sqrt(variance);
462
+ }`);
463
+ }
464
+
465
+ if (needed.has('lerp')) {
466
+ parts.push(`
467
+ function lerp(a, b, t) { return a + (b - a) * t; }`);
468
+ }
469
+
206
470
  if (needed.has('randInt')) {
207
471
  parts.push(`
208
472
  function randInt(min, max) {
@@ -275,6 +539,49 @@ function fromEntries(entries) {
275
539
  }`);
276
540
  }
277
541
 
542
+ if (needed.has('keys')) {
543
+ parts.push(`
544
+ function keys(obj) { return Object.keys(obj); }`);
545
+ }
546
+
547
+ if (needed.has('values')) {
548
+ parts.push(`
549
+ function values(obj) { return Object.values(obj); }`);
550
+ }
551
+
552
+ if (needed.has('entries')) {
553
+ parts.push(`
554
+ function entries(obj) { return Object.entries(obj); }`);
555
+ }
556
+
557
+ if (needed.has('merge')) {
558
+ parts.push(`
559
+ function merge() {
560
+ return Object.assign.apply(Object, [{}].concat(Array.from(arguments)));
561
+ }`);
562
+ }
563
+
564
+ if (needed.has('invert')) {
565
+ parts.push(`
566
+ function invert(obj) {
567
+ var out = {};
568
+ Object.keys(obj).forEach(function(k) { out[obj[k]] = k; });
569
+ return out;
570
+ }`);
571
+ }
572
+
573
+ if (needed.has('defaults')) {
574
+ parts.push(`
575
+ function defaults(obj) {
576
+ var sources = Array.from(arguments).slice(1);
577
+ var out = Object.assign({}, obj);
578
+ sources.forEach(function(s) {
579
+ Object.keys(s).forEach(function(k) { if (out[k] == null) out[k] = s[k]; });
580
+ });
581
+ return out;
582
+ }`);
583
+ }
584
+
278
585
  if (needed.has('deepEqual')) {
279
586
  parts.push(`
280
587
  function deepEqual(a, b) {
@@ -289,6 +596,162 @@ function deepClone(v) {
289
596
  }`);
290
597
  }
291
598
 
599
+ // ── Strings ────────────────────────────────────────────────────────────────
600
+
601
+ if (needed.has('capitalize')) {
602
+ parts.push(`
603
+ function capitalize(s) {
604
+ return s ? s[0].toUpperCase() + s.slice(1) : s;
605
+ }`);
606
+ }
607
+
608
+ if (needed.has('camelCase')) {
609
+ parts.push(`
610
+ function camelCase(s) {
611
+ return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
612
+ }`);
613
+ }
614
+
615
+ if (needed.has('snakeCase')) {
616
+ parts.push(`
617
+ function snakeCase(s) {
618
+ return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
619
+ }`);
620
+ }
621
+
622
+ if (needed.has('kebabCase')) {
623
+ parts.push(`
624
+ function kebabCase(s) {
625
+ return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
626
+ }`);
627
+ }
628
+
629
+ if (needed.has('truncate')) {
630
+ parts.push(`
631
+ function truncate(s, len, suffix) {
632
+ suffix = suffix != null ? suffix : '...';
633
+ if (s.length <= len) return s;
634
+ var cut = len - suffix.length;
635
+ if (cut <= 0) return suffix.slice(0, len);
636
+ return s.slice(0, cut) + suffix;
637
+ }`);
638
+ }
639
+
640
+ if (needed.has('pad')) {
641
+ parts.push(`
642
+ function pad(s, len, char) {
643
+ char = char || ' ';
644
+ s = String(s);
645
+ var total = len - s.length;
646
+ if (total <= 0) return s;
647
+ var half = Math.floor(total / 2);
648
+ return char.repeat(half) + s + char.repeat(total - half);
649
+ }`);
650
+ }
651
+
652
+ if (needed.has('padStart')) {
653
+ parts.push(`
654
+ function padStart(s, len, char) {
655
+ return String(s).padStart(len, char || ' ');
656
+ }`);
657
+ }
658
+
659
+ if (needed.has('padEnd')) {
660
+ parts.push(`
661
+ function padEnd(s, len, char) {
662
+ return String(s).padEnd(len, char || ' ');
663
+ }`);
664
+ }
665
+
666
+ if (needed.has('trim')) {
667
+ parts.push(`
668
+ function trim(s) { return String(s).trim(); }`);
669
+ }
670
+
671
+ if (needed.has('trimStart')) {
672
+ parts.push(`
673
+ function trimStart(s) { return String(s).trimStart(); }`);
674
+ }
675
+
676
+ if (needed.has('trimEnd')) {
677
+ parts.push(`
678
+ function trimEnd(s) { return String(s).trimEnd(); }`);
679
+ }
680
+
681
+ if (needed.has('words')) {
682
+ parts.push(`
683
+ function words(s) { return String(s).trim().split(/\\s+/); }`);
684
+ }
685
+
686
+ if (needed.has('lines')) {
687
+ parts.push(`
688
+ function lines(s) { return String(s).split(/\\r?\\n/); }`);
689
+ }
690
+
691
+ if (needed.has('startsWith')) {
692
+ parts.push(`
693
+ function startsWith(s, prefix) { return String(s).startsWith(prefix); }`);
694
+ }
695
+
696
+ if (needed.has('endsWith')) {
697
+ parts.push(`
698
+ function endsWith(s, suffix) { return String(s).endsWith(suffix); }`);
699
+ }
700
+
701
+ if (needed.has('repeat')) {
702
+ parts.push(`
703
+ function repeat(s, n) { return String(s).repeat(n); }`);
704
+ }
705
+
706
+ if (needed.has('replaceAll')) {
707
+ parts.push(`
708
+ function replaceAll(s, search, replacement) {
709
+ return String(s).split(search).join(replacement);
710
+ }`);
711
+ }
712
+
713
+ if (needed.has('reverseStr')) {
714
+ parts.push(`
715
+ function reverseStr(s) { return String(s).split('').reverse().join(''); }`);
716
+ }
717
+
718
+ // ── Type checks ────────────────────────────────────────────────────────────
719
+
720
+ if (needed.has('isNil')) {
721
+ parts.push(`
722
+ function isNil(v) { return v == null; }`);
723
+ }
724
+
725
+ if (needed.has('isString')) {
726
+ parts.push(`
727
+ function isString(v) { return typeof v === 'string'; }`);
728
+ }
729
+
730
+ if (needed.has('isNumber')) {
731
+ parts.push(`
732
+ function isNumber(v) { return typeof v === 'number' && !isNaN(v); }`);
733
+ }
734
+
735
+ if (needed.has('isArray')) {
736
+ parts.push(`
737
+ function isArray(v) { return Array.isArray(v); }`);
738
+ }
739
+
740
+ if (needed.has('isObject')) {
741
+ parts.push(`
742
+ function isObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }`);
743
+ }
744
+
745
+ if (needed.has('isFunction')) {
746
+ parts.push(`
747
+ function isFunction(v) { return typeof v === 'function'; }`);
748
+ }
749
+
750
+ if (needed.has('isBool')) {
751
+ parts.push(`
752
+ function isBool(v) { return typeof v === 'boolean'; }`);
753
+ }
754
+
292
755
  // ── Async ──────────────────────────────────────────────────────────────────
293
756
 
294
757
  if (needed.has('sleep')) {
@@ -306,12 +769,55 @@ async function retry(fn, attempts, delay) {
306
769
  for (var i = 0; i < attempts; i++) {
307
770
  try { return await fn(); } catch(e) {
308
771
  if (i === attempts - 1) throw e;
309
- await sleep(delay * Math.pow(2, i));
772
+ await new Promise(function(r) { setTimeout(r, delay * Math.pow(2, i)); });
310
773
  }
311
774
  }
312
775
  }`);
313
776
  }
314
777
 
778
+ if (needed.has('timeout')) {
779
+ parts.push(`
780
+ function timeout(fn, ms) {
781
+ return Promise.race([
782
+ typeof fn === 'function' ? fn() : fn,
783
+ new Promise(function(_, reject) {
784
+ setTimeout(function() { reject(new Error('Timeout after ' + ms + 'ms')); }, ms);
785
+ })
786
+ ]);
787
+ }`);
788
+ }
789
+
790
+ if (needed.has('allSettled')) {
791
+ parts.push(`
792
+ function allSettled(promises) {
793
+ return Promise.allSettled(promises);
794
+ }`);
795
+ }
796
+
797
+ if (needed.has('debounce')) {
798
+ parts.push(`
799
+ function debounce(fn, ms) {
800
+ var timer;
801
+ return function() {
802
+ clearTimeout(timer);
803
+ var args = arguments;
804
+ var ctx = this;
805
+ timer = setTimeout(function() { fn.apply(ctx, args); }, ms);
806
+ };
807
+ }`);
808
+ }
809
+
810
+ if (needed.has('throttle')) {
811
+ parts.push(`
812
+ function throttle(fn, ms) {
813
+ var last = 0;
814
+ return function() {
815
+ var now = Date.now();
816
+ if (now - last >= ms) { last = now; return fn.apply(this, arguments); }
817
+ };
818
+ }`);
819
+ }
820
+
315
821
  if (needed.has('memoize')) {
316
822
  parts.push(`
317
823
  function memoize(fn) {
@@ -363,57 +869,41 @@ function curry(fn) {
363
869
  }`);
364
870
  }
365
871
 
366
- // ── Strings ────────────────────────────────────────────────────────────────
367
-
368
- if (needed.has('capitalize')) {
872
+ if (needed.has('identity')) {
369
873
  parts.push(`
370
- function capitalize(s) {
371
- return s ? s[0].toUpperCase() + s.slice(1) : s;
372
- }`);
874
+ function identity(v) { return v; }`);
373
875
  }
374
876
 
375
- if (needed.has('camelCase')) {
877
+ if (needed.has('noop')) {
376
878
  parts.push(`
377
- function camelCase(s) {
378
- return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
379
- }`);
879
+ function noop() {}`);
380
880
  }
381
881
 
382
- if (needed.has('snakeCase')) {
383
- parts.push(`
384
- function snakeCase(s) {
385
- return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
386
- }`);
387
- }
388
-
389
- if (needed.has('kebabCase')) {
882
+ if (needed.has('once')) {
390
883
  parts.push(`
391
- function kebabCase(s) {
392
- return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
884
+ function once(fn) {
885
+ var called = false, result;
886
+ return function() {
887
+ if (!called) { called = true; result = fn.apply(this, arguments); }
888
+ return result;
889
+ };
393
890
  }`);
394
891
  }
395
892
 
396
- if (needed.has('truncate')) {
893
+ if (needed.has('flip')) {
397
894
  parts.push(`
398
- function truncate(s, len, suffix) {
399
- suffix = suffix != null ? suffix : '...';
400
- if (s.length <= len) return s;
401
- // FIX: guard against suffix longer than len to avoid negative slice index
402
- var cut = len - suffix.length;
403
- if (cut <= 0) return suffix.slice(0, len);
404
- return s.slice(0, cut) + suffix;
895
+ function flip(fn) {
896
+ return function() {
897
+ var args = Array.from(arguments);
898
+ return fn.apply(this, [args[1], args[0]].concat(args.slice(2)));
899
+ };
405
900
  }`);
406
901
  }
407
902
 
408
- if (needed.has('pad')) {
903
+ if (needed.has('complement')) {
409
904
  parts.push(`
410
- function pad(s, len, char) {
411
- char = char || ' ';
412
- s = String(s);
413
- var total = len - s.length;
414
- if (total <= 0) return s;
415
- var half = Math.floor(total / 2);
416
- return char.repeat(half) + s + char.repeat(total - half);
905
+ function complement(fn) {
906
+ return function() { return !fn.apply(this, arguments); };
417
907
  }`);
418
908
  }
419
909