@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/dist/flux.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * flux-lang v3.1.2
2
+ * flux-lang v3.2.1
3
3
  * Flux — A modern language that transpiles to JavaScript. Python-clean syntax, TypeScript-level safety, Rust-inspired pattern matching.
4
4
  * (c) 2026 Flux Lang Contributors
5
5
  * Released under the MIT License
@@ -984,18 +984,48 @@ var require_parser = __commonJS({
984
984
  }
985
985
  return stmts;
986
986
  }
987
+ // ── Decorator parsing: @name or @name(args) ───────────────────
988
+ parseDecorators() {
989
+ const decorators = [];
990
+ while (this.check(T.AT)) {
991
+ const loc = this.skip();
992
+ const name = this.eat(T.IDENT).value;
993
+ let args = [];
994
+ if (this.check(T.LPAREN)) {
995
+ this.pos++;
996
+ while (!this.check(T.RPAREN) && !this.check(T.EOF)) {
997
+ args.push(this.parseExpr());
998
+ if (!this.maybe(T.COMMA)) break;
999
+ }
1000
+ this.eat(T.RPAREN);
1001
+ }
1002
+ decorators.push({ name, args, loc });
1003
+ this.skipNewlines();
1004
+ }
1005
+ return decorators;
1006
+ }
987
1007
  parseOneStmt() {
1008
+ const decorators = this.check(T.AT) ? this.parseDecorators() : [];
988
1009
  const tok = this.peek();
989
1010
  switch (tok.type) {
990
1011
  case T.VAR:
991
1012
  case T.VAL:
992
1013
  return this.parseVarDecl();
993
- case T.FN:
994
- return this.parseFnDecl();
995
- case T.ASYNC:
996
- return this.parseAsyncFn();
997
- case T.CLASS:
998
- return this.parseClassDecl();
1014
+ case T.FN: {
1015
+ const n = this.parseFnDecl();
1016
+ if (decorators.length) n.decorators = decorators;
1017
+ return n;
1018
+ }
1019
+ case T.ASYNC: {
1020
+ const n = this.parseAsyncFn();
1021
+ if (decorators.length) n.decorators = decorators;
1022
+ return n;
1023
+ }
1024
+ case T.CLASS: {
1025
+ const n = this.parseClassDecl();
1026
+ if (decorators.length) n.decorators = decorators;
1027
+ return n;
1028
+ }
999
1029
  case T.IF:
1000
1030
  return this.parseIf();
1001
1031
  case T.FOR:
@@ -2520,7 +2550,7 @@ function _fmt(v, s) {
2520
2550
  this.lines = [];
2521
2551
  this.level = 0;
2522
2552
  this._needsFmt = false;
2523
- this.emit("// Generated by Flux Transpiler v3.1.0");
2553
+ this.emit("// Generated by Flux Transpiler v3.2.0");
2524
2554
  this.emit('"use strict";');
2525
2555
  this.blank();
2526
2556
  for (const node of ast.body) this.genStmt(node);
@@ -2624,17 +2654,30 @@ function _fmt(v, s) {
2624
2654
  this.out();
2625
2655
  this.emit("}");
2626
2656
  }
2657
+ if (node.name && node.decorators && node.decorators.length > 0) {
2658
+ for (let i = node.decorators.length - 1; i >= 0; i--) {
2659
+ const dec = node.decorators[i];
2660
+ const decArgs = dec.args.length > 0 ? `(${dec.args.map((a) => this.genExpr(a)).join(", ")})(${node.name})` : `(${node.name})`;
2661
+ this.emit(`${node.name} = ${dec.name}${decArgs};`);
2662
+ }
2663
+ }
2627
2664
  }
2628
2665
  // ── class ──────────────────────────────────────────────────────
2629
2666
  genClass(node) {
2630
2667
  const ext = node.superClass ? ` extends ${node.superClass}` : "";
2631
2668
  this.emit(`class ${node.name}${ext} {`);
2632
2669
  this.in();
2670
+ const isPrivate = (f) => f.modifiers && f.modifiers.has("private");
2671
+ const fieldName = (f) => isPrivate(f) ? `#${f.name}` : f.name;
2672
+ const fieldRef = (f) => isPrivate(f) ? `this.#${f.name}` : `this.${f.name}`;
2673
+ const privateFields = node.fields.filter(isPrivate);
2674
+ for (const f of privateFields) this.emit(`#${f.name};`);
2675
+ if (privateFields.length > 0) this.blank();
2633
2676
  const allFields = getAllFields(node.name, this.clsReg);
2634
- const paramFields = allFields.filter((f) => f.init == null);
2677
+ const paramFields = allFields.filter((f) => f.init == null && !isPrivate(f));
2635
2678
  const initFields = allFields.filter((f) => f.init != null);
2636
2679
  const ownInitFields = node.fields.filter((f) => f.init != null);
2637
- const needsCtor = paramFields.length > 0 || initFields.length > 0;
2680
+ const needsCtor = paramFields.length > 0 || initFields.length > 0 || privateFields.length > 0;
2638
2681
  if (needsCtor) {
2639
2682
  const params = paramFields.map((f) => f.name).join(", ");
2640
2683
  this.emit(`constructor(${params}) {`);
@@ -2645,10 +2688,10 @@ function _fmt(v, s) {
2645
2688
  if (parentParams.length > 0)
2646
2689
  this.emit(`super(${parentParams.map((f) => f.name).join(", ")});`);
2647
2690
  }
2648
- for (const f of node.fields.filter((f2) => f2.init == null))
2649
- this.emit(`this.${f.name} = ${f.name};`);
2691
+ for (const f of node.fields.filter((f2) => f2.init == null && !isPrivate(f2)))
2692
+ this.emit(`${fieldRef(f)} = ${f.name};`);
2650
2693
  for (const f of ownInitFields)
2651
- this.emit(`this.${f.name} = ${this.genExpr(f.init)};`);
2694
+ this.emit(`${fieldRef(f)} = ${this.genExpr(f.init)};`);
2652
2695
  this.out();
2653
2696
  this.emit("}");
2654
2697
  this.blank();
@@ -2673,6 +2716,13 @@ function _fmt(v, s) {
2673
2716
  }
2674
2717
  this.out();
2675
2718
  this.emit("}");
2719
+ if (node.decorators && node.decorators.length > 0) {
2720
+ for (let i = node.decorators.length - 1; i >= 0; i--) {
2721
+ const dec = node.decorators[i];
2722
+ const decArgs = dec.args.length > 0 ? `(${dec.args.map((a) => this.genExpr(a)).join(", ")})(${node.name})` : `(${node.name})`;
2723
+ this.emit(`${node.name} = ${dec.name}${decArgs};`);
2724
+ }
2725
+ }
2676
2726
  this.blank();
2677
2727
  }
2678
2728
  // ── if / else if / else ─────────────────────────────────────────
@@ -5902,41 +5952,16 @@ var require_stdlib = __commonJS({
5902
5952
  "src/stdlib.js"(exports, module) {
5903
5953
  "use strict";
5904
5954
  var STDLIB_SYMBOLS = [
5955
+ // Sequences
5905
5956
  "range",
5906
5957
  "zip",
5907
5958
  "enumerate",
5908
- "clamp",
5909
- "sum",
5910
- "product",
5911
5959
  "flatten",
5912
5960
  "chunk",
5913
5961
  "unique",
5914
5962
  "groupBy",
5915
5963
  "sortBy",
5916
- "pick",
5917
- "omit",
5918
- "deepEqual",
5919
- "deepClone",
5920
- "sleep",
5921
- "retry",
5922
- "memoize",
5923
- "pipe",
5924
- "compose",
5925
- "partial",
5926
- "curry",
5927
- "capitalize",
5928
- "camelCase",
5929
- "snakeCase",
5930
- "kebabCase",
5931
- "truncate",
5932
- "pad",
5933
- "randInt",
5934
- "sample",
5935
- "shuffle",
5936
- "mapValues",
5937
- "filterValues",
5938
- "fromEntries",
5939
- // Array pipe helpers — standalone wrappers around Array.prototype methods
5964
+ // Array pipe helpers
5940
5965
  "map",
5941
5966
  "filter",
5942
5967
  "reduce",
@@ -5949,7 +5974,106 @@ var require_stdlib = __commonJS({
5949
5974
  "sort",
5950
5975
  "flat",
5951
5976
  "flatMap",
5952
- "includes"
5977
+ "includes",
5978
+ // Array extras
5979
+ "first",
5980
+ "last",
5981
+ "take",
5982
+ "drop",
5983
+ "takeWhile",
5984
+ "dropWhile",
5985
+ "compact",
5986
+ "intersection",
5987
+ "difference",
5988
+ "arrayUnion",
5989
+ "unzip",
5990
+ "countBy",
5991
+ "minBy",
5992
+ "maxBy",
5993
+ "toPairs",
5994
+ "partition",
5995
+ "count",
5996
+ "head",
5997
+ "tail",
5998
+ "nth",
5999
+ "rotate",
6000
+ "sliding",
6001
+ // Math
6002
+ "clamp",
6003
+ "sum",
6004
+ "product",
6005
+ "min",
6006
+ "max",
6007
+ "abs",
6008
+ "floor",
6009
+ "ceil",
6010
+ "round",
6011
+ "mean",
6012
+ "median",
6013
+ "stdDev",
6014
+ "lerp",
6015
+ "randInt",
6016
+ "sample",
6017
+ "shuffle",
6018
+ // Objects
6019
+ "pick",
6020
+ "omit",
6021
+ "deepEqual",
6022
+ "deepClone",
6023
+ "mapValues",
6024
+ "filterValues",
6025
+ "fromEntries",
6026
+ "keys",
6027
+ "values",
6028
+ "entries",
6029
+ "merge",
6030
+ "invert",
6031
+ "defaults",
6032
+ // Strings
6033
+ "capitalize",
6034
+ "camelCase",
6035
+ "snakeCase",
6036
+ "kebabCase",
6037
+ "truncate",
6038
+ "pad",
6039
+ "padStart",
6040
+ "padEnd",
6041
+ "trim",
6042
+ "trimStart",
6043
+ "trimEnd",
6044
+ "words",
6045
+ "lines",
6046
+ "startsWith",
6047
+ "endsWith",
6048
+ "repeat",
6049
+ "replaceAll",
6050
+ "reverseStr",
6051
+ // Type checks
6052
+ "isNil",
6053
+ "isString",
6054
+ "isNumber",
6055
+ "isArray",
6056
+ "isObject",
6057
+ "isFunction",
6058
+ "isBool",
6059
+ // Async
6060
+ "sleep",
6061
+ "retry",
6062
+ "memoize",
6063
+ "timeout",
6064
+ "debounce",
6065
+ "throttle",
6066
+ "allSettled",
6067
+ // Functional
6068
+ "pipe",
6069
+ "compose",
6070
+ "partial",
6071
+ "curry",
6072
+ "identity",
6073
+ "noop",
6074
+ "once",
6075
+ "flip",
6076
+ "complement"
5953
6077
  ];
5954
6078
  function buildStdlib(symbols) {
5955
6079
  const needed = symbols ? new Set(symbols.filter((s) => STDLIB_SYMBOLS.includes(s))) : new Set(STDLIB_SYMBOLS);
@@ -6073,6 +6197,148 @@ function sortBy(arr, fn) {
6073
6197
  var kb = typeof fn === 'function' ? fn(b) : b[fn];
6074
6198
  return ka < kb ? -1 : ka > kb ? 1 : 0;
6075
6199
  });
6200
+ }`);
6201
+ }
6202
+ if (needed.has("first") || needed.has("head")) {
6203
+ parts.push(`
6204
+ function first(arr) { return arr[0]; }
6205
+ function head(arr) { return arr[0]; }`);
6206
+ }
6207
+ if (needed.has("last")) {
6208
+ parts.push(`
6209
+ function last(arr) { return arr[arr.length - 1]; }`);
6210
+ }
6211
+ if (needed.has("tail")) {
6212
+ parts.push(`
6213
+ function tail(arr) { return arr.slice(1); }`);
6214
+ }
6215
+ if (needed.has("nth")) {
6216
+ parts.push(`
6217
+ function nth(arr, n) { return n < 0 ? arr[arr.length + n] : arr[n]; }`);
6218
+ }
6219
+ if (needed.has("take")) {
6220
+ parts.push(`
6221
+ function take(arr, n) { return arr.slice(0, n); }`);
6222
+ }
6223
+ if (needed.has("drop")) {
6224
+ parts.push(`
6225
+ function drop(arr, n) { return arr.slice(n); }`);
6226
+ }
6227
+ if (needed.has("takeWhile")) {
6228
+ parts.push(`
6229
+ function takeWhile(arr, fn) {
6230
+ var i = 0;
6231
+ while (i < arr.length && fn(arr[i])) i++;
6232
+ return arr.slice(0, i);
6233
+ }`);
6234
+ }
6235
+ if (needed.has("dropWhile")) {
6236
+ parts.push(`
6237
+ function dropWhile(arr, fn) {
6238
+ var i = 0;
6239
+ while (i < arr.length && fn(arr[i])) i++;
6240
+ return arr.slice(i);
6241
+ }`);
6242
+ }
6243
+ if (needed.has("compact")) {
6244
+ parts.push(`
6245
+ function compact(arr) {
6246
+ return arr.filter(function(v) { return v != null && v !== false && v !== 0 && v !== ''; });
6247
+ }`);
6248
+ }
6249
+ if (needed.has("intersection")) {
6250
+ parts.push(`
6251
+ function intersection(a, b) {
6252
+ var s = new Set(b);
6253
+ return a.filter(function(v) { return s.has(v); });
6254
+ }`);
6255
+ }
6256
+ if (needed.has("difference")) {
6257
+ parts.push(`
6258
+ function difference(a, b) {
6259
+ var s = new Set(b);
6260
+ return a.filter(function(v) { return !s.has(v); });
6261
+ }`);
6262
+ }
6263
+ if (needed.has("arrayUnion")) {
6264
+ parts.push(`
6265
+ function arrayUnion(a, b) {
6266
+ return Array.from(new Set(a.concat(b)));
6267
+ }`);
6268
+ }
6269
+ if (needed.has("unzip")) {
6270
+ parts.push(`
6271
+ function unzip(pairs) {
6272
+ var a = [], b = [];
6273
+ for (var i = 0; i < pairs.length; i++) { a.push(pairs[i][0]); b.push(pairs[i][1]); }
6274
+ return [a, b];
6275
+ }`);
6276
+ }
6277
+ if (needed.has("countBy")) {
6278
+ parts.push(`
6279
+ function countBy(arr, fn) {
6280
+ return arr.reduce(function(acc, v) {
6281
+ var k = typeof fn === 'function' ? fn(v) : v[fn];
6282
+ acc[k] = (acc[k] || 0) + 1;
6283
+ return acc;
6284
+ }, {});
6285
+ }`);
6286
+ }
6287
+ if (needed.has("minBy")) {
6288
+ parts.push(`
6289
+ function minBy(arr, fn) {
6290
+ if (!arr.length) return undefined;
6291
+ return arr.reduce(function(best, v) {
6292
+ return (typeof fn === 'function' ? fn(v) : v[fn]) < (typeof fn === 'function' ? fn(best) : best[fn]) ? v : best;
6293
+ });
6294
+ }`);
6295
+ }
6296
+ if (needed.has("maxBy")) {
6297
+ parts.push(`
6298
+ function maxBy(arr, fn) {
6299
+ if (!arr.length) return undefined;
6300
+ return arr.reduce(function(best, v) {
6301
+ return (typeof fn === 'function' ? fn(v) : v[fn]) > (typeof fn === 'function' ? fn(best) : best[fn]) ? v : best;
6302
+ });
6303
+ }`);
6304
+ }
6305
+ if (needed.has("toPairs")) {
6306
+ parts.push(`
6307
+ function toPairs(obj) {
6308
+ return Object.keys(obj).map(function(k) { return [k, obj[k]]; });
6309
+ }`);
6310
+ }
6311
+ if (needed.has("partition")) {
6312
+ parts.push(`
6313
+ function partition(arr, fn) {
6314
+ var yes = [], no = [];
6315
+ arr.forEach(function(v) { (fn(v) ? yes : no).push(v); });
6316
+ return [yes, no];
6317
+ }`);
6318
+ }
6319
+ if (needed.has("count")) {
6320
+ parts.push(`
6321
+ function count(arr, fn) {
6322
+ if (typeof fn !== 'function') return arr.length;
6323
+ return arr.reduce(function(n, v) { return fn(v) ? n + 1 : n; }, 0);
6324
+ }`);
6325
+ }
6326
+ if (needed.has("rotate")) {
6327
+ parts.push(`
6328
+ function rotate(arr, n) {
6329
+ var len = arr.length;
6330
+ if (!len) return [];
6331
+ var k = ((n % len) + len) % len;
6332
+ return arr.slice(k).concat(arr.slice(0, k));
6333
+ }`);
6334
+ }
6335
+ if (needed.has("sliding")) {
6336
+ parts.push(`
6337
+ function sliding(arr, size, step) {
6338
+ step = step || 1;
6339
+ var out = [];
6340
+ for (var i = 0; i + size <= arr.length; i += step) out.push(arr.slice(i, i + size));
6341
+ return out;
6076
6342
  }`);
6077
6343
  }
6078
6344
  if (needed.has("clamp")) {
@@ -6092,6 +6358,69 @@ function sum(arr) {
6092
6358
  function product(arr) {
6093
6359
  return arr.reduce(function(a, b) { return a * b; }, 1);
6094
6360
  }`);
6361
+ }
6362
+ if (needed.has("min")) {
6363
+ parts.push(`
6364
+ function min(arr) {
6365
+ if (arguments.length > 1) return Math.min.apply(null, arguments);
6366
+ return Math.min.apply(null, arr);
6367
+ }`);
6368
+ }
6369
+ if (needed.has("max")) {
6370
+ parts.push(`
6371
+ function max(arr) {
6372
+ if (arguments.length > 1) return Math.max.apply(null, arguments);
6373
+ return Math.max.apply(null, arr);
6374
+ }`);
6375
+ }
6376
+ if (needed.has("abs")) {
6377
+ parts.push(`
6378
+ function abs(n) { return Math.abs(n); }`);
6379
+ }
6380
+ if (needed.has("floor")) {
6381
+ parts.push(`
6382
+ function floor(n) { return Math.floor(n); }`);
6383
+ }
6384
+ if (needed.has("ceil")) {
6385
+ parts.push(`
6386
+ function ceil(n) { return Math.ceil(n); }`);
6387
+ }
6388
+ if (needed.has("round")) {
6389
+ parts.push(`
6390
+ function round(n, decimals) {
6391
+ if (decimals == null) return Math.round(n);
6392
+ var f = Math.pow(10, decimals);
6393
+ return Math.round(n * f) / f;
6394
+ }`);
6395
+ }
6396
+ if (needed.has("mean")) {
6397
+ parts.push(`
6398
+ function mean(arr) {
6399
+ if (!arr.length) return 0;
6400
+ return arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
6401
+ }`);
6402
+ }
6403
+ if (needed.has("median")) {
6404
+ parts.push(`
6405
+ function median(arr) {
6406
+ if (!arr.length) return 0;
6407
+ var s = arr.slice().sort(function(a, b) { return a - b; });
6408
+ var m = Math.floor(s.length / 2);
6409
+ return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
6410
+ }`);
6411
+ }
6412
+ if (needed.has("stdDev")) {
6413
+ parts.push(`
6414
+ function stdDev(arr) {
6415
+ if (!arr.length) return 0;
6416
+ var m = arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
6417
+ var variance = arr.reduce(function(acc, v) { return acc + (v - m) * (v - m); }, 0) / arr.length;
6418
+ return Math.sqrt(variance);
6419
+ }`);
6420
+ }
6421
+ if (needed.has("lerp")) {
6422
+ parts.push(`
6423
+ function lerp(a, b, t) { return a + (b - a) * t; }`);
6095
6424
  }
6096
6425
  if (needed.has("randInt")) {
6097
6426
  parts.push(`
@@ -6153,6 +6482,43 @@ function filterValues(obj, fn) {
6153
6482
  parts.push(`
6154
6483
  function fromEntries(entries) {
6155
6484
  return Object.fromEntries(entries);
6485
+ }`);
6486
+ }
6487
+ if (needed.has("keys")) {
6488
+ parts.push(`
6489
+ function keys(obj) { return Object.keys(obj); }`);
6490
+ }
6491
+ if (needed.has("values")) {
6492
+ parts.push(`
6493
+ function values(obj) { return Object.values(obj); }`);
6494
+ }
6495
+ if (needed.has("entries")) {
6496
+ parts.push(`
6497
+ function entries(obj) { return Object.entries(obj); }`);
6498
+ }
6499
+ if (needed.has("merge")) {
6500
+ parts.push(`
6501
+ function merge() {
6502
+ return Object.assign.apply(Object, [{}].concat(Array.from(arguments)));
6503
+ }`);
6504
+ }
6505
+ if (needed.has("invert")) {
6506
+ parts.push(`
6507
+ function invert(obj) {
6508
+ var out = {};
6509
+ Object.keys(obj).forEach(function(k) { out[obj[k]] = k; });
6510
+ return out;
6511
+ }`);
6512
+ }
6513
+ if (needed.has("defaults")) {
6514
+ parts.push(`
6515
+ function defaults(obj) {
6516
+ var sources = Array.from(arguments).slice(1);
6517
+ var out = Object.assign({}, obj);
6518
+ sources.forEach(function(s) {
6519
+ Object.keys(s).forEach(function(k) { if (out[k] == null) out[k] = s[k]; });
6520
+ });
6521
+ return out;
6156
6522
  }`);
6157
6523
  }
6158
6524
  if (needed.has("deepEqual")) {
@@ -6166,6 +6532,133 @@ function deepEqual(a, b) {
6166
6532
  function deepClone(v) {
6167
6533
  return JSON.parse(JSON.stringify(v));
6168
6534
  }`);
6535
+ }
6536
+ if (needed.has("capitalize")) {
6537
+ parts.push(`
6538
+ function capitalize(s) {
6539
+ return s ? s[0].toUpperCase() + s.slice(1) : s;
6540
+ }`);
6541
+ }
6542
+ if (needed.has("camelCase")) {
6543
+ parts.push(`
6544
+ function camelCase(s) {
6545
+ return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
6546
+ }`);
6547
+ }
6548
+ if (needed.has("snakeCase")) {
6549
+ parts.push(`
6550
+ function snakeCase(s) {
6551
+ return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
6552
+ }`);
6553
+ }
6554
+ if (needed.has("kebabCase")) {
6555
+ parts.push(`
6556
+ function kebabCase(s) {
6557
+ return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
6558
+ }`);
6559
+ }
6560
+ if (needed.has("truncate")) {
6561
+ parts.push(`
6562
+ function truncate(s, len, suffix) {
6563
+ suffix = suffix != null ? suffix : '...';
6564
+ if (s.length <= len) return s;
6565
+ var cut = len - suffix.length;
6566
+ if (cut <= 0) return suffix.slice(0, len);
6567
+ return s.slice(0, cut) + suffix;
6568
+ }`);
6569
+ }
6570
+ if (needed.has("pad")) {
6571
+ parts.push(`
6572
+ function pad(s, len, char) {
6573
+ char = char || ' ';
6574
+ s = String(s);
6575
+ var total = len - s.length;
6576
+ if (total <= 0) return s;
6577
+ var half = Math.floor(total / 2);
6578
+ return char.repeat(half) + s + char.repeat(total - half);
6579
+ }`);
6580
+ }
6581
+ if (needed.has("padStart")) {
6582
+ parts.push(`
6583
+ function padStart(s, len, char) {
6584
+ return String(s).padStart(len, char || ' ');
6585
+ }`);
6586
+ }
6587
+ if (needed.has("padEnd")) {
6588
+ parts.push(`
6589
+ function padEnd(s, len, char) {
6590
+ return String(s).padEnd(len, char || ' ');
6591
+ }`);
6592
+ }
6593
+ if (needed.has("trim")) {
6594
+ parts.push(`
6595
+ function trim(s) { return String(s).trim(); }`);
6596
+ }
6597
+ if (needed.has("trimStart")) {
6598
+ parts.push(`
6599
+ function trimStart(s) { return String(s).trimStart(); }`);
6600
+ }
6601
+ if (needed.has("trimEnd")) {
6602
+ parts.push(`
6603
+ function trimEnd(s) { return String(s).trimEnd(); }`);
6604
+ }
6605
+ if (needed.has("words")) {
6606
+ parts.push(`
6607
+ function words(s) { return String(s).trim().split(/\\s+/); }`);
6608
+ }
6609
+ if (needed.has("lines")) {
6610
+ parts.push(`
6611
+ function lines(s) { return String(s).split(/\\r?\\n/); }`);
6612
+ }
6613
+ if (needed.has("startsWith")) {
6614
+ parts.push(`
6615
+ function startsWith(s, prefix) { return String(s).startsWith(prefix); }`);
6616
+ }
6617
+ if (needed.has("endsWith")) {
6618
+ parts.push(`
6619
+ function endsWith(s, suffix) { return String(s).endsWith(suffix); }`);
6620
+ }
6621
+ if (needed.has("repeat")) {
6622
+ parts.push(`
6623
+ function repeat(s, n) { return String(s).repeat(n); }`);
6624
+ }
6625
+ if (needed.has("replaceAll")) {
6626
+ parts.push(`
6627
+ function replaceAll(s, search, replacement) {
6628
+ return String(s).split(search).join(replacement);
6629
+ }`);
6630
+ }
6631
+ if (needed.has("reverseStr")) {
6632
+ parts.push(`
6633
+ function reverseStr(s) { return String(s).split('').reverse().join(''); }`);
6634
+ }
6635
+ if (needed.has("isNil")) {
6636
+ parts.push(`
6637
+ function isNil(v) { return v == null; }`);
6638
+ }
6639
+ if (needed.has("isString")) {
6640
+ parts.push(`
6641
+ function isString(v) { return typeof v === 'string'; }`);
6642
+ }
6643
+ if (needed.has("isNumber")) {
6644
+ parts.push(`
6645
+ function isNumber(v) { return typeof v === 'number' && !isNaN(v); }`);
6646
+ }
6647
+ if (needed.has("isArray")) {
6648
+ parts.push(`
6649
+ function isArray(v) { return Array.isArray(v); }`);
6650
+ }
6651
+ if (needed.has("isObject")) {
6652
+ parts.push(`
6653
+ function isObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }`);
6654
+ }
6655
+ if (needed.has("isFunction")) {
6656
+ parts.push(`
6657
+ function isFunction(v) { return typeof v === 'function'; }`);
6658
+ }
6659
+ if (needed.has("isBool")) {
6660
+ parts.push(`
6661
+ function isBool(v) { return typeof v === 'boolean'; }`);
6169
6662
  }
6170
6663
  if (needed.has("sleep")) {
6171
6664
  parts.push(`
@@ -6181,9 +6674,48 @@ async function retry(fn, attempts, delay) {
6181
6674
  for (var i = 0; i < attempts; i++) {
6182
6675
  try { return await fn(); } catch(e) {
6183
6676
  if (i === attempts - 1) throw e;
6184
- await sleep(delay * Math.pow(2, i));
6677
+ await new Promise(function(r) { setTimeout(r, delay * Math.pow(2, i)); });
6185
6678
  }
6186
6679
  }
6680
+ }`);
6681
+ }
6682
+ if (needed.has("timeout")) {
6683
+ parts.push(`
6684
+ function timeout(fn, ms) {
6685
+ return Promise.race([
6686
+ typeof fn === 'function' ? fn() : fn,
6687
+ new Promise(function(_, reject) {
6688
+ setTimeout(function() { reject(new Error('Timeout after ' + ms + 'ms')); }, ms);
6689
+ })
6690
+ ]);
6691
+ }`);
6692
+ }
6693
+ if (needed.has("allSettled")) {
6694
+ parts.push(`
6695
+ function allSettled(promises) {
6696
+ return Promise.allSettled(promises);
6697
+ }`);
6698
+ }
6699
+ if (needed.has("debounce")) {
6700
+ parts.push(`
6701
+ function debounce(fn, ms) {
6702
+ var timer;
6703
+ return function() {
6704
+ clearTimeout(timer);
6705
+ var args = arguments;
6706
+ var ctx = this;
6707
+ timer = setTimeout(function() { fn.apply(ctx, args); }, ms);
6708
+ };
6709
+ }`);
6710
+ }
6711
+ if (needed.has("throttle")) {
6712
+ parts.push(`
6713
+ function throttle(fn, ms) {
6714
+ var last = 0;
6715
+ return function() {
6716
+ var now = Date.now();
6717
+ if (now - last >= ms) { last = now; return fn.apply(this, arguments); }
6718
+ };
6187
6719
  }`);
6188
6720
  }
6189
6721
  if (needed.has("memoize")) {
@@ -6230,50 +6762,37 @@ function curry(fn) {
6230
6762
  };
6231
6763
  }`);
6232
6764
  }
6233
- if (needed.has("capitalize")) {
6234
- parts.push(`
6235
- function capitalize(s) {
6236
- return s ? s[0].toUpperCase() + s.slice(1) : s;
6237
- }`);
6238
- }
6239
- if (needed.has("camelCase")) {
6765
+ if (needed.has("identity")) {
6240
6766
  parts.push(`
6241
- function camelCase(s) {
6242
- return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
6243
- }`);
6767
+ function identity(v) { return v; }`);
6244
6768
  }
6245
- if (needed.has("snakeCase")) {
6769
+ if (needed.has("noop")) {
6246
6770
  parts.push(`
6247
- function snakeCase(s) {
6248
- return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
6249
- }`);
6771
+ function noop() {}`);
6250
6772
  }
6251
- if (needed.has("kebabCase")) {
6773
+ if (needed.has("once")) {
6252
6774
  parts.push(`
6253
- function kebabCase(s) {
6254
- return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
6775
+ function once(fn) {
6776
+ var called = false, result;
6777
+ return function() {
6778
+ if (!called) { called = true; result = fn.apply(this, arguments); }
6779
+ return result;
6780
+ };
6255
6781
  }`);
6256
6782
  }
6257
- if (needed.has("truncate")) {
6783
+ if (needed.has("flip")) {
6258
6784
  parts.push(`
6259
- function truncate(s, len, suffix) {
6260
- suffix = suffix != null ? suffix : '...';
6261
- if (s.length <= len) return s;
6262
- // FIX: guard against suffix longer than len to avoid negative slice index
6263
- var cut = len - suffix.length;
6264
- if (cut <= 0) return suffix.slice(0, len);
6265
- return s.slice(0, cut) + suffix;
6785
+ function flip(fn) {
6786
+ return function() {
6787
+ var args = Array.from(arguments);
6788
+ return fn.apply(this, [args[1], args[0]].concat(args.slice(2)));
6789
+ };
6266
6790
  }`);
6267
6791
  }
6268
- if (needed.has("pad")) {
6792
+ if (needed.has("complement")) {
6269
6793
  parts.push(`
6270
- function pad(s, len, char) {
6271
- char = char || ' ';
6272
- s = String(s);
6273
- var total = len - s.length;
6274
- if (total <= 0) return s;
6275
- var half = Math.floor(total / 2);
6276
- return char.repeat(half) + s + char.repeat(total - half);
6794
+ function complement(fn) {
6795
+ return function() { return !fn.apply(this, arguments); };
6277
6796
  }`);
6278
6797
  }
6279
6798
  parts.push("// \u2500\u2500 end stdlib \u2500\u2500\n");