@xnoxs/flux-lang 4.0.9 → 4.1.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
@@ -1,33 +1,137 @@
1
- /* compiled from src/self/stdlib.flux by Flux Lang */
2
1
  'use strict';
3
- // ── Flux stdlib ──
4
2
 
5
- function map(arr, fn) { return arr.map(fn); }
3
+ // ── Flux Standard Library ─────────────────────────────────────────────────────
4
+ // Runtime helpers injected into compiled Flux programs.
5
+ // Each function is self-contained so tree-shaking can work later.
6
+
7
+ // ── Detection: which stdlib symbols appear in compiled JS? ───────────────────
8
+ const STDLIB_SYMBOLS = [
9
+ // Sequences
10
+ 'range', 'zip', 'enumerate', 'flatten', 'chunk', 'unique', 'groupBy', 'sortBy',
11
+
12
+ // Array pipe helpers
13
+ 'map', 'filter', 'reduce', 'forEach', 'find', 'findIndex',
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',
47
+ ];
48
+
49
+ /**
50
+ * Build the stdlib preamble JavaScript string.
51
+ * If `symbols` is provided, only include helpers that are used.
52
+ * @param {string[]} [symbols] - list of stdlib names actually used in the output
53
+ * @returns {string}
54
+ */
55
+ function buildStdlib(symbols) {
56
+ const needed = symbols
57
+ ? new Set(symbols.filter(s => STDLIB_SYMBOLS.includes(s)))
58
+ : new Set(STDLIB_SYMBOLS);
6
59
 
7
- function filter(arr, fn) { return arr.filter(fn); }
60
+ if (needed.size === 0) return '';
8
61
 
9
- function reduce(arr, fn, init) { return arguments.length >= 3 ? arr.reduce(fn, init) : arr.reduce(fn); }
62
+ const parts = ['// ── Flux stdlib ──'];
10
63
 
11
- function forEach(arr, fn) { arr.forEach(fn); return arr; }
64
+ // ── Array pipe helpers ─────────────────────────────────────────────────────
12
65
 
13
- function find(arr, fn) { return arr.find(fn); }
66
+ if (needed.has('map')) {
67
+ parts.push(`
68
+ function map(arr, fn) { return arr.map(fn); }`);
69
+ }
14
70
 
15
- function findIndex(arr, fn) { return arr.findIndex(fn); }
71
+ if (needed.has('filter')) {
72
+ parts.push(`
73
+ function filter(arr, fn) { return arr.filter(fn); }`);
74
+ }
75
+
76
+ if (needed.has('reduce')) {
77
+ parts.push(`
78
+ function reduce(arr, fn, init) { return arguments.length >= 3 ? arr.reduce(fn, init) : arr.reduce(fn); }`);
79
+ }
16
80
 
17
- function some(arr, fn) { return arr.some(fn); }
81
+ if (needed.has('forEach')) {
82
+ parts.push(`
83
+ function forEach(arr, fn) { arr.forEach(fn); return arr; }`);
84
+ }
18
85
 
19
- function every(arr, fn) { return arr.every(fn); }
86
+ if (needed.has('find')) {
87
+ parts.push(`
88
+ function find(arr, fn) { return arr.find(fn); }`);
89
+ }
20
90
 
21
- function join(arr, sep) { return arr.join(sep != null ? sep : ','); }
91
+ if (needed.has('findIndex')) {
92
+ parts.push(`
93
+ function findIndex(arr, fn) { return arr.findIndex(fn); }`);
94
+ }
22
95
 
23
- function sort(arr, fn) { return arr.slice().sort(fn); }
96
+ if (needed.has('some')) {
97
+ parts.push(`
98
+ function some(arr, fn) { return arr.some(fn); }`);
99
+ }
24
100
 
25
- function flat(arr, depth) { return arr.flat(depth != null ? depth : 1); }
101
+ if (needed.has('every')) {
102
+ parts.push(`
103
+ function every(arr, fn) { return arr.every(fn); }`);
104
+ }
26
105
 
27
- function flatMap(arr, fn) { return arr.flatMap(fn); }
106
+ if (needed.has('join')) {
107
+ parts.push(`
108
+ function join(arr, sep) { return arr.join(sep != null ? sep : ','); }`);
109
+ }
110
+
111
+ if (needed.has('sort')) {
112
+ parts.push(`
113
+ function sort(arr, fn) { return arr.slice().sort(fn); }`);
114
+ }
115
+
116
+ if (needed.has('flat')) {
117
+ parts.push(`
118
+ function flat(arr, depth) { return arr.flat(depth != null ? depth : 1); }`);
119
+ }
120
+
121
+ if (needed.has('flatMap')) {
122
+ parts.push(`
123
+ function flatMap(arr, fn) { return arr.flatMap(fn); }`);
124
+ }
125
+
126
+ if (needed.has('includes')) {
127
+ parts.push(`
128
+ function includes(arr, val) { return arr.includes(val); }`);
129
+ }
28
130
 
29
- function includes(arr, val) { return arr.includes(val); }
131
+ // ── Sequences ──────────────────────────────────────────────────────────────
30
132
 
133
+ if (needed.has('range')) {
134
+ parts.push(`
31
135
  function range(start, end, step) {
32
136
  if (arguments.length === 1) { end = start; start = 0; }
33
137
  step = step || (end >= start ? 1 : -1);
@@ -35,83 +139,350 @@ function range(start, end, step) {
35
139
  if (step > 0) { for (let i = start; i < end; i += step) out.push(i); }
36
140
  else { for (let i = start; i > end; i += step) out.push(i); }
37
141
  return out;
38
- }
142
+ }`);
143
+ }
39
144
 
145
+ if (needed.has('zip')) {
146
+ parts.push(`
40
147
  function zip() {
41
148
  const arrays = Array.from(arguments);
42
149
  const len = Math.min.apply(null, arrays.map(function(a) { return a.length; }));
43
150
  const out = [];
44
151
  for (let i = 0; i < len; i++) out.push(arrays.map(function(a) { return a[i]; }));
45
152
  return out;
46
- }
153
+ }`);
154
+ }
47
155
 
156
+ if (needed.has('enumerate')) {
157
+ parts.push(`
48
158
  function enumerate(arr, start) {
49
159
  start = start || 0;
50
160
  return arr.map(function(v, i) { return [i + start, v]; });
51
- }
161
+ }`);
162
+ }
52
163
 
164
+ if (needed.has('flatten')) {
165
+ parts.push(`
53
166
  function flatten(arr, depth) {
54
167
  return depth == null ? arr.flat(Infinity) : arr.flat(depth);
55
- }
168
+ }`);
169
+ }
56
170
 
171
+ if (needed.has('chunk')) {
172
+ parts.push(`
57
173
  function chunk(arr, size) {
58
174
  const out = [];
59
175
  for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
60
176
  return out;
61
- }
177
+ }`);
178
+ }
62
179
 
180
+ if (needed.has('unique')) {
181
+ parts.push(`
63
182
  function unique(arr) {
64
183
  return Array.from(new Set(arr));
65
- }
184
+ }`);
185
+ }
66
186
 
187
+ if (needed.has('groupBy')) {
188
+ parts.push(`
67
189
  function groupBy(arr, fn) {
68
190
  return arr.reduce(function(acc, v) {
69
191
  var k = typeof fn === 'function' ? fn(v) : v[fn];
70
192
  (acc[k] = acc[k] || []).push(v);
71
193
  return acc;
72
194
  }, {});
73
- }
195
+ }`);
196
+ }
74
197
 
198
+ if (needed.has('sortBy')) {
199
+ parts.push(`
75
200
  function sortBy(arr, fn) {
76
201
  return arr.slice().sort(function(a, b) {
77
202
  var ka = typeof fn === 'function' ? fn(a) : a[fn];
78
203
  var kb = typeof fn === 'function' ? fn(b) : b[fn];
79
204
  return ka < kb ? -1 : ka > kb ? 1 : 0;
80
205
  });
81
- }
206
+ }`);
207
+ }
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
+ }
82
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
+
374
+ // ── Math ───────────────────────────────────────────────────────────────────
375
+
376
+ if (needed.has('clamp')) {
377
+ parts.push(`
83
378
  function clamp(val, min, max) {
84
379
  return Math.min(Math.max(val, min), max);
85
- }
380
+ }`);
381
+ }
86
382
 
383
+ if (needed.has('sum')) {
384
+ parts.push(`
87
385
  function sum(arr) {
88
386
  return arr.reduce(function(a, b) { return a + b; }, 0);
89
- }
387
+ }`);
388
+ }
90
389
 
390
+ if (needed.has('product')) {
391
+ parts.push(`
91
392
  function product(arr) {
92
393
  return arr.reduce(function(a, b) { return a * b; }, 1);
93
- }
394
+ }`);
395
+ }
94
396
 
397
+ if (needed.has('min')) {
398
+ parts.push(`
95
399
  function min(arr) {
96
400
  if (arguments.length > 1) return Math.min.apply(null, arguments);
97
401
  return Math.min.apply(null, arr);
98
- }
402
+ }`);
403
+ }
99
404
 
405
+ if (needed.has('max')) {
406
+ parts.push(`
100
407
  function max(arr) {
101
408
  if (arguments.length > 1) return Math.max.apply(null, arguments);
102
409
  return Math.max.apply(null, arr);
103
- }
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
+ }
104
427
 
105
- function floor(n) { return Math.floor(n); }
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
+ }
106
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
+
470
+ if (needed.has('randInt')) {
471
+ parts.push(`
107
472
  function randInt(min, max) {
108
473
  return Math.floor(Math.random() * (max - min + 1)) + min;
109
- }
474
+ }`);
475
+ }
110
476
 
477
+ if (needed.has('sample')) {
478
+ parts.push(`
111
479
  function sample(arr) {
112
480
  return arr[Math.floor(Math.random() * arr.length)];
113
- }
481
+ }`);
482
+ }
114
483
 
484
+ if (needed.has('shuffle')) {
485
+ parts.push(`
115
486
  function shuffle(arr) {
116
487
  var a = arr.slice();
117
488
  for (var i = a.length - 1; i > 0; i--) {
@@ -119,71 +490,155 @@ function shuffle(arr) {
119
490
  var tmp = a[i]; a[i] = a[j]; a[j] = tmp;
120
491
  }
121
492
  return a;
122
- }
493
+ }`);
494
+ }
123
495
 
496
+ // ── Objects ────────────────────────────────────────────────────────────────
497
+
498
+ if (needed.has('pick')) {
499
+ parts.push(`
124
500
  function pick(obj, keys) {
125
501
  var out = {};
126
502
  keys.forEach(function(k) { if (Object.prototype.hasOwnProperty.call(obj, k)) out[k] = obj[k]; });
127
503
  return out;
128
- }
504
+ }`);
505
+ }
129
506
 
507
+ if (needed.has('omit')) {
508
+ parts.push(`
130
509
  function omit(obj, keys) {
131
510
  var ks = new Set(keys);
132
511
  var out = {};
133
512
  Object.keys(obj).forEach(function(k) { if (!ks.has(k)) out[k] = obj[k]; });
134
513
  return out;
135
- }
514
+ }`);
515
+ }
136
516
 
517
+ if (needed.has('mapValues')) {
518
+ parts.push(`
137
519
  function mapValues(obj, fn) {
138
520
  var out = {};
139
521
  Object.keys(obj).forEach(function(k) { out[k] = fn(obj[k], k); });
140
522
  return out;
141
- }
523
+ }`);
524
+ }
142
525
 
526
+ if (needed.has('filterValues')) {
527
+ parts.push(`
143
528
  function filterValues(obj, fn) {
144
529
  var out = {};
145
530
  Object.keys(obj).forEach(function(k) { if (fn(obj[k], k)) out[k] = obj[k]; });
146
531
  return out;
147
- }
532
+ }`);
533
+ }
148
534
 
535
+ if (needed.has('fromEntries')) {
536
+ parts.push(`
149
537
  function fromEntries(entries) {
150
538
  return Object.fromEntries(entries);
151
- }
539
+ }`);
540
+ }
152
541
 
153
- function keys(obj) { return Object.keys(obj); }
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
+ }
154
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
+
585
+ if (needed.has('deepEqual')) {
586
+ parts.push(`
155
587
  function deepEqual(a, b) {
156
588
  return JSON.stringify(a) === JSON.stringify(b);
157
- }
589
+ }`);
590
+ }
158
591
 
592
+ if (needed.has('deepClone')) {
593
+ parts.push(`
159
594
  function deepClone(v) {
160
595
  return JSON.parse(JSON.stringify(v));
161
- }
596
+ }`);
597
+ }
598
+
599
+ // ── Strings ────────────────────────────────────────────────────────────────
162
600
 
601
+ if (needed.has('capitalize')) {
602
+ parts.push(`
163
603
  function capitalize(s) {
164
604
  return s ? s[0].toUpperCase() + s.slice(1) : s;
165
- }
605
+ }`);
606
+ }
166
607
 
608
+ if (needed.has('camelCase')) {
609
+ parts.push(`
167
610
  function camelCase(s) {
168
- return s.replace(/[-_\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
169
- }
611
+ return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
612
+ }`);
613
+ }
170
614
 
615
+ if (needed.has('snakeCase')) {
616
+ parts.push(`
171
617
  function snakeCase(s) {
172
- return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\s]+/g, '_').replace(/^_/, '');
173
- }
618
+ return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
619
+ }`);
620
+ }
174
621
 
622
+ if (needed.has('kebabCase')) {
623
+ parts.push(`
175
624
  function kebabCase(s) {
176
- return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\s]+/g, '-').replace(/^-/, '');
177
- }
625
+ return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
626
+ }`);
627
+ }
178
628
 
629
+ if (needed.has('truncate')) {
630
+ parts.push(`
179
631
  function truncate(s, len, suffix) {
180
632
  suffix = suffix != null ? suffix : '...';
181
633
  if (s.length <= len) return s;
182
634
  var cut = len - suffix.length;
183
635
  if (cut <= 0) return suffix.slice(0, len);
184
636
  return s.slice(0, cut) + suffix;
185
- }
637
+ }`);
638
+ }
186
639
 
640
+ if (needed.has('pad')) {
641
+ parts.push(`
187
642
  function pad(s, len, char) {
188
643
  char = char || ' ';
189
644
  s = String(s);
@@ -191,14 +646,123 @@ function pad(s, len, char) {
191
646
  if (total <= 0) return s;
192
647
  var half = Math.floor(total / 2);
193
648
  return char.repeat(half) + s + char.repeat(total - half);
194
- }
649
+ }`);
650
+ }
195
651
 
196
- function repeat(s, n) { return String(s).repeat(n); }
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
+ }
197
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
+
755
+ // ── Async ──────────────────────────────────────────────────────────────────
756
+
757
+ if (needed.has('sleep')) {
758
+ parts.push(`
198
759
  function sleep(ms) {
199
760
  return new Promise(function(resolve) { setTimeout(resolve, ms); });
200
- }
761
+ }`);
762
+ }
201
763
 
764
+ if (needed.has('retry')) {
765
+ parts.push(`
202
766
  async function retry(fn, attempts, delay) {
203
767
  attempts = attempts || 3;
204
768
  delay = delay || 300;
@@ -208,8 +772,54 @@ async function retry(fn, attempts, delay) {
208
772
  await new Promise(function(r) { setTimeout(r, delay * Math.pow(2, i)); });
209
773
  }
210
774
  }
211
- }
775
+ }`);
776
+ }
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
+ }
212
820
 
821
+ if (needed.has('memoize')) {
822
+ parts.push(`
213
823
  function memoize(fn) {
214
824
  var cache = new Map();
215
825
  return function() {
@@ -219,195 +829,98 @@ function memoize(fn) {
219
829
  cache.set(key, result);
220
830
  return result;
221
831
  };
222
- }
832
+ }`);
833
+ }
223
834
 
835
+ // ── Functional ─────────────────────────────────────────────────────────────
836
+
837
+ if (needed.has('pipe')) {
838
+ parts.push(`
224
839
  function pipe() {
225
840
  var fns = Array.from(arguments);
226
841
  return function(x) { return fns.reduce(function(v, f) { return f(v); }, x); };
227
- }
842
+ }`);
843
+ }
228
844
 
845
+ if (needed.has('compose')) {
846
+ parts.push(`
229
847
  function compose() {
230
848
  var fns = Array.from(arguments);
231
849
  return function(x) { return fns.reduceRight(function(v, f) { return f(v); }, x); };
232
- }
850
+ }`);
851
+ }
233
852
 
853
+ if (needed.has('partial')) {
854
+ parts.push(`
234
855
  function partial(fn) {
235
856
  var args = Array.from(arguments).slice(1);
236
857
  return function() { return fn.apply(this, args.concat(Array.from(arguments))); };
237
- }
858
+ }`);
859
+ }
238
860
 
861
+ if (needed.has('curry')) {
862
+ parts.push(`
239
863
  function curry(fn) {
240
864
  return function curried() {
241
865
  var args = Array.from(arguments);
242
866
  if (args.length >= fn.length) return fn.apply(this, args);
243
867
  return function() { return curried.apply(this, args.concat(Array.from(arguments))); };
244
868
  };
245
- }
246
- // ── end stdlib ──
247
-
248
- // Generated by Flux Transpiler v3.2.0
249
- "use strict";
250
-
251
- const STDLIB_SYMBOLS = ["range", "zip", "enumerate", "clamp", "sum", "product", "flatten", "chunk", "unique", "groupBy", "sortBy", "pick", "omit", "deepEqual", "deepClone", "sleep", "retry", "memoize", "pipe", "compose", "partial", "curry", "capitalize", "camelCase", "snakeCase", "kebabCase", "truncate", "pad", "randInt", "sample", "shuffle", "mapValues", "filterValues", "fromEntries", "map", "filter", "reduce", "forEach", "find", "findIndex", "some", "every", "join", "sort", "flat", "flatMap", "includes"];
252
- module.exports.STDLIB_SYMBOLS = STDLIB_SYMBOLS;
253
- function makeSymbolRe(sym) {
254
- return new RegExp((("\\b" + sym) + "\\s*\\("), "g");
255
- }
256
- function detectUsedSymbols(jsCode) {
257
- return STDLIB_SYMBOLS.filter((sym) => makeSymbolRe(sym).test(jsCode));
258
- }
259
- module.exports.detectUsedSymbols = detectUsedSymbols;
260
- function buildStdlib(symbols) {
261
- let needed = new Set(STDLIB_SYMBOLS);
262
- if (symbols) {
263
- needed = new Set(symbols.filter((s) => STDLIB_SYMBOLS.includes(s)));
264
- }
265
- if ((needed.size == 0)) {
266
- return "";
267
- }
268
- const parts = ["// ── Flux stdlib ──"];
269
- if (needed.has("map")) {
270
- parts.push("function map(arr, fn) { return arr.map(fn); }");
271
- }
272
- if (needed.has("filter")) {
273
- parts.push("function filter(arr, fn) { return arr.filter(fn); }");
274
- }
275
- if (needed.has("reduce")) {
276
- parts.push("function reduce(arr, fn, init) { return arguments.length >= 3 ? arr.reduce(fn, init) : arr.reduce(fn); }");
277
- }
278
- if (needed.has("forEach")) {
279
- parts.push("function forEach(arr, fn) { arr.forEach(fn); return arr; }");
280
- }
281
- if (needed.has("find")) {
282
- parts.push("function find(arr, fn) { return arr.find(fn); }");
283
- }
284
- if (needed.has("findIndex")) {
285
- parts.push("function findIndex(arr, fn) { return arr.findIndex(fn); }");
286
- }
287
- if (needed.has("some")) {
288
- parts.push("function some(arr, fn) { return arr.some(fn); }");
289
- }
290
- if (needed.has("every")) {
291
- parts.push("function every(arr, fn) { return arr.every(fn); }");
292
- }
293
- if (needed.has("join")) {
294
- parts.push("function join(arr, sep) { return arr.join(sep != null ? sep : ','); }");
295
- }
296
- if (needed.has("sort")) {
297
- parts.push("function sort(arr, fn) { return arr.slice().sort(fn); }");
298
- }
299
- if (needed.has("flat")) {
300
- parts.push("function flat(arr, depth) { return arr.flat(depth != null ? depth : 1); }");
301
- }
302
- if (needed.has("flatMap")) {
303
- parts.push("function flatMap(arr, fn) { return arr.flatMap(fn); }");
304
- }
305
- if (needed.has("includes")) {
306
- parts.push("function includes(arr, val) { return arr.includes(val); }");
307
- }
308
- if (needed.has("range")) {
309
- parts.push("function range(start, end, step) {\n if (arguments.length === 1) { end = start; start = 0; }\n step = step || (end >= start ? 1 : -1);\n const out = [];\n if (step > 0) { for (let i = start; i < end; i += step) out.push(i); }\n else { for (let i = start; i > end; i += step) out.push(i); }\n return out;\n}");
310
- }
311
- if (needed.has("zip")) {
312
- parts.push("function zip() {\n const arrays = Array.from(arguments);\n const len = Math.min.apply(null, arrays.map(function(a) { return a.length; }));\n const out = [];\n for (let i = 0; i < len; i++) out.push(arrays.map(function(a) { return a[i]; }));\n return out;\n}");
313
- }
314
- if (needed.has("enumerate")) {
315
- parts.push("function enumerate(arr, start) {\n start = start || 0;\n return arr.map(function(v, i) { return [i + start, v]; });\n}");
316
- }
317
- if (needed.has("flatten")) {
318
- parts.push("function flatten(arr, depth) {\n return depth == null ? arr.flat(Infinity) : arr.flat(depth);\n}");
319
- }
320
- if (needed.has("chunk")) {
321
- parts.push("function chunk(arr, size) {\n const out = [];\n for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));\n return out;\n}");
322
- }
323
- if (needed.has("unique")) {
324
- parts.push("function unique(arr) {\n return Array.from(new Set(arr));\n}");
325
- }
326
- if (needed.has("groupBy")) {
327
- parts.push("function groupBy(arr, fn) {\n return arr.reduce(function(acc, v) {\n var k = typeof fn === 'function' ? fn(v) : v[fn];\n (acc[k] = acc[k] || []).push(v);\n return acc;\n }, {});\n}");
328
- }
329
- if (needed.has("sortBy")) {
330
- parts.push("function sortBy(arr, fn) {\n return arr.slice().sort(function(a, b) {\n var ka = typeof fn === 'function' ? fn(a) : a[fn];\n var kb = typeof fn === 'function' ? fn(b) : b[fn];\n return ka < kb ? -1 : ka > kb ? 1 : 0;\n });\n}");
331
- }
332
- if (needed.has("clamp")) {
333
- parts.push("function clamp(val, min, max) {\n return Math.min(Math.max(val, min), max);\n}");
334
- }
335
- if (needed.has("sum")) {
336
- parts.push("function sum(arr) {\n return arr.reduce(function(a, b) { return a + b; }, 0);\n}");
869
+ }`);
337
870
  }
338
- if (needed.has("product")) {
339
- parts.push("function product(arr) {\n return arr.reduce(function(a, b) { return a * b; }, 1);\n}");
340
- }
341
- if (needed.has("randInt")) {
342
- parts.push("function randInt(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}");
343
- }
344
- if (needed.has("sample")) {
345
- parts.push("function sample(arr) {\n return arr[Math.floor(Math.random() * arr.length)];\n}");
346
- }
347
- if (needed.has("shuffle")) {
348
- parts.push("function shuffle(arr) {\n var a = arr.slice();\n for (var i = a.length - 1; i > 0; i--) {\n var j = Math.floor(Math.random() * (i + 1));\n var tmp = a[i]; a[i] = a[j]; a[j] = tmp;\n }\n return a;\n}");
349
- }
350
- if (needed.has("pick")) {
351
- parts.push("function pick(obj, keys) {\n var out = {};\n keys.forEach(function(k) { if (Object.prototype.hasOwnProperty.call(obj, k)) out[k] = obj[k]; });\n return out;\n}");
352
- }
353
- if (needed.has("omit")) {
354
- parts.push("function omit(obj, keys) {\n var ks = new Set(keys);\n var out = {};\n Object.keys(obj).forEach(function(k) { if (!ks.has(k)) out[k] = obj[k]; });\n return out;\n}");
355
- }
356
- if (needed.has("mapValues")) {
357
- parts.push("function mapValues(obj, fn) {\n var out = {};\n Object.keys(obj).forEach(function(k) { out[k] = fn(obj[k], k); });\n return out;\n}");
358
- }
359
- if (needed.has("filterValues")) {
360
- parts.push("function filterValues(obj, fn) {\n var out = {};\n Object.keys(obj).forEach(function(k) { if (fn(obj[k], k)) out[k] = obj[k]; });\n return out;\n}");
361
- }
362
- if (needed.has("fromEntries")) {
363
- parts.push("function fromEntries(entries) {\n return Object.fromEntries(entries);\n}");
364
- }
365
- if (needed.has("deepEqual")) {
366
- parts.push("function deepEqual(a, b) {\n return JSON.stringify(a) === JSON.stringify(b);\n}");
367
- }
368
- if (needed.has("deepClone")) {
369
- parts.push("function deepClone(v) {\n return JSON.parse(JSON.stringify(v));\n}");
370
- }
371
- if (needed.has("sleep")) {
372
- parts.push("function sleep(ms) {\n return new Promise(function(resolve) { setTimeout(resolve, ms); });\n}");
373
- }
374
- if (needed.has("retry")) {
375
- parts.push("async function retry(fn, attempts, delay) {\n attempts = attempts || 3;\n delay = delay || 300;\n for (var i = 0; i < attempts; i++) {\n try { return await fn(); } catch(e) {\n if (i === attempts - 1) throw e;\n await sleep(delay * Math.pow(2, i));\n }\n }\n}");
376
- }
377
- if (needed.has("memoize")) {
378
- parts.push("function memoize(fn) {\n var cache = new Map();\n return function() {\n var key = JSON.stringify(arguments);\n if (cache.has(key)) return cache.get(key);\n var result = fn.apply(this, arguments);\n cache.set(key, result);\n return result;\n };\n}");
379
- }
380
- if (needed.has("pipe")) {
381
- parts.push("function pipe() {\n var fns = Array.from(arguments);\n return function(x) { return fns.reduce(function(v, f) { return f(v); }, x); };\n}");
382
- }
383
- if (needed.has("compose")) {
384
- parts.push("function compose() {\n var fns = Array.from(arguments);\n return function(x) { return fns.reduceRight(function(v, f) { return f(v); }, x); };\n}");
385
- }
386
- if (needed.has("partial")) {
387
- parts.push("function partial(fn) {\n var args = Array.from(arguments).slice(1);\n return function() { return fn.apply(this, args.concat(Array.from(arguments))); };\n}");
388
- }
389
- if (needed.has("curry")) {
390
- parts.push("function curry(fn) {\n return function curried() {\n var args = Array.from(arguments);\n if (args.length >= fn.length) return fn.apply(this, args);\n return function() { return curried.apply(this, args.concat(Array.from(arguments))); };\n };\n}");
391
- }
392
- if (needed.has("capitalize")) {
393
- parts.push("function capitalize(s) {\n return s ? s[0].toUpperCase() + s.slice(1) : s;\n}");
394
- }
395
- if (needed.has("camelCase")) {
396
- parts.push("function camelCase(s) {\n return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });\n}");
871
+
872
+ if (needed.has('identity')) {
873
+ parts.push(`
874
+ function identity(v) { return v; }`);
397
875
  }
398
- if (needed.has("snakeCase")) {
399
- parts.push("function snakeCase(s) {\n return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');\n}");
876
+
877
+ if (needed.has('noop')) {
878
+ parts.push(`
879
+ function noop() {}`);
400
880
  }
401
- if (needed.has("kebabCase")) {
402
- parts.push("function kebabCase(s) {\n return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');\n}");
881
+
882
+ if (needed.has('once')) {
883
+ parts.push(`
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
+ };
890
+ }`);
403
891
  }
404
- if (needed.has("truncate")) {
405
- parts.push("function truncate(s, len, suffix) {\n suffix = suffix != null ? suffix : '...';\n if (s.length <= len) return s;\n var cut = len - suffix.length;\n if (cut <= 0) return suffix.slice(0, len);\n return s.slice(0, cut) + suffix;\n}");
892
+
893
+ if (needed.has('flip')) {
894
+ parts.push(`
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
+ };
900
+ }`);
406
901
  }
407
- if (needed.has("pad")) {
408
- parts.push("function pad(s, len, char) {\n char = char || ' ';\n s = String(s);\n var total = len - s.length;\n if (total <= 0) return s;\n var half = Math.floor(total / 2);\n return char.repeat(half) + s + char.repeat(total - half);\n}");
902
+
903
+ if (needed.has('complement')) {
904
+ parts.push(`
905
+ function complement(fn) {
906
+ return function() { return !fn.apply(this, arguments); };
907
+ }`);
409
908
  }
410
- parts.push("// ── end stdlib ──\n");
411
- return parts.join("\n");
909
+
910
+ parts.push('// ── end stdlib ──\n');
911
+ return parts.join('\n');
412
912
  }
413
- module.exports.buildStdlib = buildStdlib;
913
+
914
+ /**
915
+ * Detect which stdlib symbols are referenced in a JS string.
916
+ * @param {string} jsCode
917
+ * @returns {string[]}
918
+ */
919
+ function detectUsedSymbols(jsCode) {
920
+ return STDLIB_SYMBOLS.filter(sym => {
921
+ const re = new RegExp(`\\b${sym}\\s*\\(`, 'g');
922
+ return re.test(jsCode);
923
+ });
924
+ }
925
+
926
+ module.exports = { buildStdlib, detectUsedSymbols, STDLIB_SYMBOLS };