@xnoxs/flux-lang 3.1.1 → 3.2.0

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.cjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * flux-lang v3.1.1
2
+ * flux-lang v3.2.0
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
@@ -979,18 +979,48 @@ var require_parser = __commonJS({
979
979
  }
980
980
  return stmts;
981
981
  }
982
+ // ── Decorator parsing: @name or @name(args) ───────────────────
983
+ parseDecorators() {
984
+ const decorators = [];
985
+ while (this.check(T.AT)) {
986
+ const loc = this.skip();
987
+ const name = this.eat(T.IDENT).value;
988
+ let args = [];
989
+ if (this.check(T.LPAREN)) {
990
+ this.pos++;
991
+ while (!this.check(T.RPAREN) && !this.check(T.EOF)) {
992
+ args.push(this.parseExpr());
993
+ if (!this.maybe(T.COMMA)) break;
994
+ }
995
+ this.eat(T.RPAREN);
996
+ }
997
+ decorators.push({ name, args, loc });
998
+ this.skipNewlines();
999
+ }
1000
+ return decorators;
1001
+ }
982
1002
  parseOneStmt() {
1003
+ const decorators = this.check(T.AT) ? this.parseDecorators() : [];
983
1004
  const tok = this.peek();
984
1005
  switch (tok.type) {
985
1006
  case T.VAR:
986
1007
  case T.VAL:
987
1008
  return this.parseVarDecl();
988
- case T.FN:
989
- return this.parseFnDecl();
990
- case T.ASYNC:
991
- return this.parseAsyncFn();
992
- case T.CLASS:
993
- return this.parseClassDecl();
1009
+ case T.FN: {
1010
+ const n = this.parseFnDecl();
1011
+ if (decorators.length) n.decorators = decorators;
1012
+ return n;
1013
+ }
1014
+ case T.ASYNC: {
1015
+ const n = this.parseAsyncFn();
1016
+ if (decorators.length) n.decorators = decorators;
1017
+ return n;
1018
+ }
1019
+ case T.CLASS: {
1020
+ const n = this.parseClassDecl();
1021
+ if (decorators.length) n.decorators = decorators;
1022
+ return n;
1023
+ }
994
1024
  case T.IF:
995
1025
  return this.parseIf();
996
1026
  case T.FOR:
@@ -1571,6 +1601,26 @@ var require_parser = __commonJS({
1571
1601
  m.modifiers = mods;
1572
1602
  m.modifiers.add("static");
1573
1603
  methods.push(m);
1604
+ } else if (this.check(T.VAR) || this.check(T.VAL)) {
1605
+ const fieldKind = this.skip().type === T.VAR ? "var" : "val";
1606
+ const fname = this.eat(T.IDENT).value;
1607
+ let optional = false;
1608
+ let ftype = null;
1609
+ if (this.check(T.QUESTION)) {
1610
+ this.pos++;
1611
+ optional = true;
1612
+ }
1613
+ if (this.check(T.COLON)) {
1614
+ this.pos++;
1615
+ ftype = this.parseTypeAnn();
1616
+ }
1617
+ let init = null;
1618
+ if (this.check(T.EQ)) {
1619
+ this.pos++;
1620
+ init = this.parseExpr();
1621
+ }
1622
+ this.skipNewlines();
1623
+ fields.push({ name: fname, typeAnn: ftype, optional, modifiers: mods, init, fieldKind });
1574
1624
  } else if (this.check(T.IDENT)) {
1575
1625
  const fname = this.eat(T.IDENT).value;
1576
1626
  let optional = false;
@@ -1581,7 +1631,7 @@ var require_parser = __commonJS({
1581
1631
  this.eat(T.COLON);
1582
1632
  const ftype = this.parseTypeAnn();
1583
1633
  this.skipNewlines();
1584
- fields.push({ name: fname, typeAnn: ftype, optional, modifiers: mods });
1634
+ fields.push({ name: fname, typeAnn: ftype, optional, modifiers: mods, init: null });
1585
1635
  } else {
1586
1636
  this.skip();
1587
1637
  }
@@ -2495,7 +2545,7 @@ function _fmt(v, s) {
2495
2545
  this.lines = [];
2496
2546
  this.level = 0;
2497
2547
  this._needsFmt = false;
2498
- this.emit("// Generated by Flux Transpiler v3.1.0");
2548
+ this.emit("// Generated by Flux Transpiler v3.2.0");
2499
2549
  this.emit('"use strict";');
2500
2550
  this.blank();
2501
2551
  for (const node of ast.body) this.genStmt(node);
@@ -2599,23 +2649,44 @@ function _fmt(v, s) {
2599
2649
  this.out();
2600
2650
  this.emit("}");
2601
2651
  }
2652
+ if (node.name && node.decorators && node.decorators.length > 0) {
2653
+ for (let i = node.decorators.length - 1; i >= 0; i--) {
2654
+ const dec = node.decorators[i];
2655
+ const decArgs = dec.args.length > 0 ? `(${dec.args.map((a) => this.genExpr(a)).join(", ")})(${node.name})` : `(${node.name})`;
2656
+ this.emit(`${node.name} = ${dec.name}${decArgs};`);
2657
+ }
2658
+ }
2602
2659
  }
2603
2660
  // ── class ──────────────────────────────────────────────────────
2604
2661
  genClass(node) {
2605
2662
  const ext = node.superClass ? ` extends ${node.superClass}` : "";
2606
2663
  this.emit(`class ${node.name}${ext} {`);
2607
2664
  this.in();
2665
+ const isPrivate = (f) => f.modifiers && f.modifiers.has("private");
2666
+ const fieldName = (f) => isPrivate(f) ? `#${f.name}` : f.name;
2667
+ const fieldRef = (f) => isPrivate(f) ? `this.#${f.name}` : `this.${f.name}`;
2668
+ const privateFields = node.fields.filter(isPrivate);
2669
+ for (const f of privateFields) this.emit(`#${f.name};`);
2670
+ if (privateFields.length > 0) this.blank();
2608
2671
  const allFields = getAllFields(node.name, this.clsReg);
2609
- if (allFields.length > 0) {
2610
- const params = allFields.map((f) => f.name).join(", ");
2672
+ const paramFields = allFields.filter((f) => f.init == null && !isPrivate(f));
2673
+ const initFields = allFields.filter((f) => f.init != null);
2674
+ const ownInitFields = node.fields.filter((f) => f.init != null);
2675
+ const needsCtor = paramFields.length > 0 || initFields.length > 0 || privateFields.length > 0;
2676
+ if (needsCtor) {
2677
+ const params = paramFields.map((f) => f.name).join(", ");
2611
2678
  this.emit(`constructor(${params}) {`);
2612
2679
  this.in();
2613
2680
  if (node.superClass && this.clsReg[node.superClass]) {
2614
2681
  const parentFields = getAllFields(node.superClass, this.clsReg);
2615
- if (parentFields.length > 0)
2616
- this.emit(`super(${parentFields.map((f) => f.name).join(", ")});`);
2617
- }
2618
- for (const f of node.fields) this.emit(`this.${f.name} = ${f.name};`);
2682
+ const parentParams = parentFields.filter((f) => f.init == null);
2683
+ if (parentParams.length > 0)
2684
+ this.emit(`super(${parentParams.map((f) => f.name).join(", ")});`);
2685
+ }
2686
+ for (const f of node.fields.filter((f2) => f2.init == null && !isPrivate(f2)))
2687
+ this.emit(`${fieldRef(f)} = ${f.name};`);
2688
+ for (const f of ownInitFields)
2689
+ this.emit(`${fieldRef(f)} = ${this.genExpr(f.init)};`);
2619
2690
  this.out();
2620
2691
  this.emit("}");
2621
2692
  this.blank();
@@ -2640,6 +2711,13 @@ function _fmt(v, s) {
2640
2711
  }
2641
2712
  this.out();
2642
2713
  this.emit("}");
2714
+ if (node.decorators && node.decorators.length > 0) {
2715
+ for (let i = node.decorators.length - 1; i >= 0; i--) {
2716
+ const dec = node.decorators[i];
2717
+ const decArgs = dec.args.length > 0 ? `(${dec.args.map((a) => this.genExpr(a)).join(", ")})(${node.name})` : `(${node.name})`;
2718
+ this.emit(`${node.name} = ${dec.name}${decArgs};`);
2719
+ }
2720
+ }
2643
2721
  this.blank();
2644
2722
  }
2645
2723
  // ── if / else if / else ─────────────────────────────────────────
@@ -5869,41 +5947,16 @@ var require_stdlib = __commonJS({
5869
5947
  "src/stdlib.js"(exports2, module2) {
5870
5948
  "use strict";
5871
5949
  var STDLIB_SYMBOLS2 = [
5950
+ // Sequences
5872
5951
  "range",
5873
5952
  "zip",
5874
5953
  "enumerate",
5875
- "clamp",
5876
- "sum",
5877
- "product",
5878
5954
  "flatten",
5879
5955
  "chunk",
5880
5956
  "unique",
5881
5957
  "groupBy",
5882
5958
  "sortBy",
5883
- "pick",
5884
- "omit",
5885
- "deepEqual",
5886
- "deepClone",
5887
- "sleep",
5888
- "retry",
5889
- "memoize",
5890
- "pipe",
5891
- "compose",
5892
- "partial",
5893
- "curry",
5894
- "capitalize",
5895
- "camelCase",
5896
- "snakeCase",
5897
- "kebabCase",
5898
- "truncate",
5899
- "pad",
5900
- "randInt",
5901
- "sample",
5902
- "shuffle",
5903
- "mapValues",
5904
- "filterValues",
5905
- "fromEntries",
5906
- // Array pipe helpers — standalone wrappers around Array.prototype methods
5959
+ // Array pipe helpers
5907
5960
  "map",
5908
5961
  "filter",
5909
5962
  "reduce",
@@ -5916,7 +5969,106 @@ var require_stdlib = __commonJS({
5916
5969
  "sort",
5917
5970
  "flat",
5918
5971
  "flatMap",
5919
- "includes"
5972
+ "includes",
5973
+ // Array extras
5974
+ "first",
5975
+ "last",
5976
+ "take",
5977
+ "drop",
5978
+ "takeWhile",
5979
+ "dropWhile",
5980
+ "compact",
5981
+ "intersection",
5982
+ "difference",
5983
+ "arrayUnion",
5984
+ "unzip",
5985
+ "countBy",
5986
+ "minBy",
5987
+ "maxBy",
5988
+ "toPairs",
5989
+ "partition",
5990
+ "count",
5991
+ "head",
5992
+ "tail",
5993
+ "nth",
5994
+ "rotate",
5995
+ "sliding",
5996
+ // Math
5997
+ "clamp",
5998
+ "sum",
5999
+ "product",
6000
+ "min",
6001
+ "max",
6002
+ "abs",
6003
+ "floor",
6004
+ "ceil",
6005
+ "round",
6006
+ "mean",
6007
+ "median",
6008
+ "stdDev",
6009
+ "lerp",
6010
+ "randInt",
6011
+ "sample",
6012
+ "shuffle",
6013
+ // Objects
6014
+ "pick",
6015
+ "omit",
6016
+ "deepEqual",
6017
+ "deepClone",
6018
+ "mapValues",
6019
+ "filterValues",
6020
+ "fromEntries",
6021
+ "keys",
6022
+ "values",
6023
+ "entries",
6024
+ "merge",
6025
+ "invert",
6026
+ "defaults",
6027
+ // Strings
6028
+ "capitalize",
6029
+ "camelCase",
6030
+ "snakeCase",
6031
+ "kebabCase",
6032
+ "truncate",
6033
+ "pad",
6034
+ "padStart",
6035
+ "padEnd",
6036
+ "trim",
6037
+ "trimStart",
6038
+ "trimEnd",
6039
+ "words",
6040
+ "lines",
6041
+ "startsWith",
6042
+ "endsWith",
6043
+ "repeat",
6044
+ "replaceAll",
6045
+ "reverseStr",
6046
+ // Type checks
6047
+ "isNil",
6048
+ "isString",
6049
+ "isNumber",
6050
+ "isArray",
6051
+ "isObject",
6052
+ "isFunction",
6053
+ "isBool",
6054
+ // Async
6055
+ "sleep",
6056
+ "retry",
6057
+ "memoize",
6058
+ "timeout",
6059
+ "debounce",
6060
+ "throttle",
6061
+ "allSettled",
6062
+ // Functional
6063
+ "pipe",
6064
+ "compose",
6065
+ "partial",
6066
+ "curry",
6067
+ "identity",
6068
+ "noop",
6069
+ "once",
6070
+ "flip",
6071
+ "complement"
5920
6072
  ];
5921
6073
  function buildStdlib2(symbols) {
5922
6074
  const needed = symbols ? new Set(symbols.filter((s) => STDLIB_SYMBOLS2.includes(s))) : new Set(STDLIB_SYMBOLS2);
@@ -6040,6 +6192,148 @@ function sortBy(arr, fn) {
6040
6192
  var kb = typeof fn === 'function' ? fn(b) : b[fn];
6041
6193
  return ka < kb ? -1 : ka > kb ? 1 : 0;
6042
6194
  });
6195
+ }`);
6196
+ }
6197
+ if (needed.has("first") || needed.has("head")) {
6198
+ parts.push(`
6199
+ function first(arr) { return arr[0]; }
6200
+ function head(arr) { return arr[0]; }`);
6201
+ }
6202
+ if (needed.has("last")) {
6203
+ parts.push(`
6204
+ function last(arr) { return arr[arr.length - 1]; }`);
6205
+ }
6206
+ if (needed.has("tail")) {
6207
+ parts.push(`
6208
+ function tail(arr) { return arr.slice(1); }`);
6209
+ }
6210
+ if (needed.has("nth")) {
6211
+ parts.push(`
6212
+ function nth(arr, n) { return n < 0 ? arr[arr.length + n] : arr[n]; }`);
6213
+ }
6214
+ if (needed.has("take")) {
6215
+ parts.push(`
6216
+ function take(arr, n) { return arr.slice(0, n); }`);
6217
+ }
6218
+ if (needed.has("drop")) {
6219
+ parts.push(`
6220
+ function drop(arr, n) { return arr.slice(n); }`);
6221
+ }
6222
+ if (needed.has("takeWhile")) {
6223
+ parts.push(`
6224
+ function takeWhile(arr, fn) {
6225
+ var i = 0;
6226
+ while (i < arr.length && fn(arr[i])) i++;
6227
+ return arr.slice(0, i);
6228
+ }`);
6229
+ }
6230
+ if (needed.has("dropWhile")) {
6231
+ parts.push(`
6232
+ function dropWhile(arr, fn) {
6233
+ var i = 0;
6234
+ while (i < arr.length && fn(arr[i])) i++;
6235
+ return arr.slice(i);
6236
+ }`);
6237
+ }
6238
+ if (needed.has("compact")) {
6239
+ parts.push(`
6240
+ function compact(arr) {
6241
+ return arr.filter(function(v) { return v != null && v !== false && v !== 0 && v !== ''; });
6242
+ }`);
6243
+ }
6244
+ if (needed.has("intersection")) {
6245
+ parts.push(`
6246
+ function intersection(a, b) {
6247
+ var s = new Set(b);
6248
+ return a.filter(function(v) { return s.has(v); });
6249
+ }`);
6250
+ }
6251
+ if (needed.has("difference")) {
6252
+ parts.push(`
6253
+ function difference(a, b) {
6254
+ var s = new Set(b);
6255
+ return a.filter(function(v) { return !s.has(v); });
6256
+ }`);
6257
+ }
6258
+ if (needed.has("arrayUnion")) {
6259
+ parts.push(`
6260
+ function arrayUnion(a, b) {
6261
+ return Array.from(new Set(a.concat(b)));
6262
+ }`);
6263
+ }
6264
+ if (needed.has("unzip")) {
6265
+ parts.push(`
6266
+ function unzip(pairs) {
6267
+ var a = [], b = [];
6268
+ for (var i = 0; i < pairs.length; i++) { a.push(pairs[i][0]); b.push(pairs[i][1]); }
6269
+ return [a, b];
6270
+ }`);
6271
+ }
6272
+ if (needed.has("countBy")) {
6273
+ parts.push(`
6274
+ function countBy(arr, fn) {
6275
+ return arr.reduce(function(acc, v) {
6276
+ var k = typeof fn === 'function' ? fn(v) : v[fn];
6277
+ acc[k] = (acc[k] || 0) + 1;
6278
+ return acc;
6279
+ }, {});
6280
+ }`);
6281
+ }
6282
+ if (needed.has("minBy")) {
6283
+ parts.push(`
6284
+ function minBy(arr, fn) {
6285
+ if (!arr.length) return undefined;
6286
+ return arr.reduce(function(best, v) {
6287
+ return (typeof fn === 'function' ? fn(v) : v[fn]) < (typeof fn === 'function' ? fn(best) : best[fn]) ? v : best;
6288
+ });
6289
+ }`);
6290
+ }
6291
+ if (needed.has("maxBy")) {
6292
+ parts.push(`
6293
+ function maxBy(arr, fn) {
6294
+ if (!arr.length) return undefined;
6295
+ return arr.reduce(function(best, v) {
6296
+ return (typeof fn === 'function' ? fn(v) : v[fn]) > (typeof fn === 'function' ? fn(best) : best[fn]) ? v : best;
6297
+ });
6298
+ }`);
6299
+ }
6300
+ if (needed.has("toPairs")) {
6301
+ parts.push(`
6302
+ function toPairs(obj) {
6303
+ return Object.keys(obj).map(function(k) { return [k, obj[k]]; });
6304
+ }`);
6305
+ }
6306
+ if (needed.has("partition")) {
6307
+ parts.push(`
6308
+ function partition(arr, fn) {
6309
+ var yes = [], no = [];
6310
+ arr.forEach(function(v) { (fn(v) ? yes : no).push(v); });
6311
+ return [yes, no];
6312
+ }`);
6313
+ }
6314
+ if (needed.has("count")) {
6315
+ parts.push(`
6316
+ function count(arr, fn) {
6317
+ if (typeof fn !== 'function') return arr.length;
6318
+ return arr.reduce(function(n, v) { return fn(v) ? n + 1 : n; }, 0);
6319
+ }`);
6320
+ }
6321
+ if (needed.has("rotate")) {
6322
+ parts.push(`
6323
+ function rotate(arr, n) {
6324
+ var len = arr.length;
6325
+ if (!len) return [];
6326
+ var k = ((n % len) + len) % len;
6327
+ return arr.slice(k).concat(arr.slice(0, k));
6328
+ }`);
6329
+ }
6330
+ if (needed.has("sliding")) {
6331
+ parts.push(`
6332
+ function sliding(arr, size, step) {
6333
+ step = step || 1;
6334
+ var out = [];
6335
+ for (var i = 0; i + size <= arr.length; i += step) out.push(arr.slice(i, i + size));
6336
+ return out;
6043
6337
  }`);
6044
6338
  }
6045
6339
  if (needed.has("clamp")) {
@@ -6059,6 +6353,69 @@ function sum(arr) {
6059
6353
  function product(arr) {
6060
6354
  return arr.reduce(function(a, b) { return a * b; }, 1);
6061
6355
  }`);
6356
+ }
6357
+ if (needed.has("min")) {
6358
+ parts.push(`
6359
+ function min(arr) {
6360
+ if (arguments.length > 1) return Math.min.apply(null, arguments);
6361
+ return Math.min.apply(null, arr);
6362
+ }`);
6363
+ }
6364
+ if (needed.has("max")) {
6365
+ parts.push(`
6366
+ function max(arr) {
6367
+ if (arguments.length > 1) return Math.max.apply(null, arguments);
6368
+ return Math.max.apply(null, arr);
6369
+ }`);
6370
+ }
6371
+ if (needed.has("abs")) {
6372
+ parts.push(`
6373
+ function abs(n) { return Math.abs(n); }`);
6374
+ }
6375
+ if (needed.has("floor")) {
6376
+ parts.push(`
6377
+ function floor(n) { return Math.floor(n); }`);
6378
+ }
6379
+ if (needed.has("ceil")) {
6380
+ parts.push(`
6381
+ function ceil(n) { return Math.ceil(n); }`);
6382
+ }
6383
+ if (needed.has("round")) {
6384
+ parts.push(`
6385
+ function round(n, decimals) {
6386
+ if (decimals == null) return Math.round(n);
6387
+ var f = Math.pow(10, decimals);
6388
+ return Math.round(n * f) / f;
6389
+ }`);
6390
+ }
6391
+ if (needed.has("mean")) {
6392
+ parts.push(`
6393
+ function mean(arr) {
6394
+ if (!arr.length) return 0;
6395
+ return arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
6396
+ }`);
6397
+ }
6398
+ if (needed.has("median")) {
6399
+ parts.push(`
6400
+ function median(arr) {
6401
+ if (!arr.length) return 0;
6402
+ var s = arr.slice().sort(function(a, b) { return a - b; });
6403
+ var m = Math.floor(s.length / 2);
6404
+ return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
6405
+ }`);
6406
+ }
6407
+ if (needed.has("stdDev")) {
6408
+ parts.push(`
6409
+ function stdDev(arr) {
6410
+ if (!arr.length) return 0;
6411
+ var m = arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
6412
+ var variance = arr.reduce(function(acc, v) { return acc + (v - m) * (v - m); }, 0) / arr.length;
6413
+ return Math.sqrt(variance);
6414
+ }`);
6415
+ }
6416
+ if (needed.has("lerp")) {
6417
+ parts.push(`
6418
+ function lerp(a, b, t) { return a + (b - a) * t; }`);
6062
6419
  }
6063
6420
  if (needed.has("randInt")) {
6064
6421
  parts.push(`
@@ -6120,6 +6477,43 @@ function filterValues(obj, fn) {
6120
6477
  parts.push(`
6121
6478
  function fromEntries(entries) {
6122
6479
  return Object.fromEntries(entries);
6480
+ }`);
6481
+ }
6482
+ if (needed.has("keys")) {
6483
+ parts.push(`
6484
+ function keys(obj) { return Object.keys(obj); }`);
6485
+ }
6486
+ if (needed.has("values")) {
6487
+ parts.push(`
6488
+ function values(obj) { return Object.values(obj); }`);
6489
+ }
6490
+ if (needed.has("entries")) {
6491
+ parts.push(`
6492
+ function entries(obj) { return Object.entries(obj); }`);
6493
+ }
6494
+ if (needed.has("merge")) {
6495
+ parts.push(`
6496
+ function merge() {
6497
+ return Object.assign.apply(Object, [{}].concat(Array.from(arguments)));
6498
+ }`);
6499
+ }
6500
+ if (needed.has("invert")) {
6501
+ parts.push(`
6502
+ function invert(obj) {
6503
+ var out = {};
6504
+ Object.keys(obj).forEach(function(k) { out[obj[k]] = k; });
6505
+ return out;
6506
+ }`);
6507
+ }
6508
+ if (needed.has("defaults")) {
6509
+ parts.push(`
6510
+ function defaults(obj) {
6511
+ var sources = Array.from(arguments).slice(1);
6512
+ var out = Object.assign({}, obj);
6513
+ sources.forEach(function(s) {
6514
+ Object.keys(s).forEach(function(k) { if (out[k] == null) out[k] = s[k]; });
6515
+ });
6516
+ return out;
6123
6517
  }`);
6124
6518
  }
6125
6519
  if (needed.has("deepEqual")) {
@@ -6133,6 +6527,133 @@ function deepEqual(a, b) {
6133
6527
  function deepClone(v) {
6134
6528
  return JSON.parse(JSON.stringify(v));
6135
6529
  }`);
6530
+ }
6531
+ if (needed.has("capitalize")) {
6532
+ parts.push(`
6533
+ function capitalize(s) {
6534
+ return s ? s[0].toUpperCase() + s.slice(1) : s;
6535
+ }`);
6536
+ }
6537
+ if (needed.has("camelCase")) {
6538
+ parts.push(`
6539
+ function camelCase(s) {
6540
+ return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
6541
+ }`);
6542
+ }
6543
+ if (needed.has("snakeCase")) {
6544
+ parts.push(`
6545
+ function snakeCase(s) {
6546
+ return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
6547
+ }`);
6548
+ }
6549
+ if (needed.has("kebabCase")) {
6550
+ parts.push(`
6551
+ function kebabCase(s) {
6552
+ return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
6553
+ }`);
6554
+ }
6555
+ if (needed.has("truncate")) {
6556
+ parts.push(`
6557
+ function truncate(s, len, suffix) {
6558
+ suffix = suffix != null ? suffix : '...';
6559
+ if (s.length <= len) return s;
6560
+ var cut = len - suffix.length;
6561
+ if (cut <= 0) return suffix.slice(0, len);
6562
+ return s.slice(0, cut) + suffix;
6563
+ }`);
6564
+ }
6565
+ if (needed.has("pad")) {
6566
+ parts.push(`
6567
+ function pad(s, len, char) {
6568
+ char = char || ' ';
6569
+ s = String(s);
6570
+ var total = len - s.length;
6571
+ if (total <= 0) return s;
6572
+ var half = Math.floor(total / 2);
6573
+ return char.repeat(half) + s + char.repeat(total - half);
6574
+ }`);
6575
+ }
6576
+ if (needed.has("padStart")) {
6577
+ parts.push(`
6578
+ function padStart(s, len, char) {
6579
+ return String(s).padStart(len, char || ' ');
6580
+ }`);
6581
+ }
6582
+ if (needed.has("padEnd")) {
6583
+ parts.push(`
6584
+ function padEnd(s, len, char) {
6585
+ return String(s).padEnd(len, char || ' ');
6586
+ }`);
6587
+ }
6588
+ if (needed.has("trim")) {
6589
+ parts.push(`
6590
+ function trim(s) { return String(s).trim(); }`);
6591
+ }
6592
+ if (needed.has("trimStart")) {
6593
+ parts.push(`
6594
+ function trimStart(s) { return String(s).trimStart(); }`);
6595
+ }
6596
+ if (needed.has("trimEnd")) {
6597
+ parts.push(`
6598
+ function trimEnd(s) { return String(s).trimEnd(); }`);
6599
+ }
6600
+ if (needed.has("words")) {
6601
+ parts.push(`
6602
+ function words(s) { return String(s).trim().split(/\\s+/); }`);
6603
+ }
6604
+ if (needed.has("lines")) {
6605
+ parts.push(`
6606
+ function lines(s) { return String(s).split(/\\r?\\n/); }`);
6607
+ }
6608
+ if (needed.has("startsWith")) {
6609
+ parts.push(`
6610
+ function startsWith(s, prefix) { return String(s).startsWith(prefix); }`);
6611
+ }
6612
+ if (needed.has("endsWith")) {
6613
+ parts.push(`
6614
+ function endsWith(s, suffix) { return String(s).endsWith(suffix); }`);
6615
+ }
6616
+ if (needed.has("repeat")) {
6617
+ parts.push(`
6618
+ function repeat(s, n) { return String(s).repeat(n); }`);
6619
+ }
6620
+ if (needed.has("replaceAll")) {
6621
+ parts.push(`
6622
+ function replaceAll(s, search, replacement) {
6623
+ return String(s).split(search).join(replacement);
6624
+ }`);
6625
+ }
6626
+ if (needed.has("reverseStr")) {
6627
+ parts.push(`
6628
+ function reverseStr(s) { return String(s).split('').reverse().join(''); }`);
6629
+ }
6630
+ if (needed.has("isNil")) {
6631
+ parts.push(`
6632
+ function isNil(v) { return v == null; }`);
6633
+ }
6634
+ if (needed.has("isString")) {
6635
+ parts.push(`
6636
+ function isString(v) { return typeof v === 'string'; }`);
6637
+ }
6638
+ if (needed.has("isNumber")) {
6639
+ parts.push(`
6640
+ function isNumber(v) { return typeof v === 'number' && !isNaN(v); }`);
6641
+ }
6642
+ if (needed.has("isArray")) {
6643
+ parts.push(`
6644
+ function isArray(v) { return Array.isArray(v); }`);
6645
+ }
6646
+ if (needed.has("isObject")) {
6647
+ parts.push(`
6648
+ function isObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }`);
6649
+ }
6650
+ if (needed.has("isFunction")) {
6651
+ parts.push(`
6652
+ function isFunction(v) { return typeof v === 'function'; }`);
6653
+ }
6654
+ if (needed.has("isBool")) {
6655
+ parts.push(`
6656
+ function isBool(v) { return typeof v === 'boolean'; }`);
6136
6657
  }
6137
6658
  if (needed.has("sleep")) {
6138
6659
  parts.push(`
@@ -6148,9 +6669,48 @@ async function retry(fn, attempts, delay) {
6148
6669
  for (var i = 0; i < attempts; i++) {
6149
6670
  try { return await fn(); } catch(e) {
6150
6671
  if (i === attempts - 1) throw e;
6151
- await sleep(delay * Math.pow(2, i));
6672
+ await new Promise(function(r) { setTimeout(r, delay * Math.pow(2, i)); });
6152
6673
  }
6153
6674
  }
6675
+ }`);
6676
+ }
6677
+ if (needed.has("timeout")) {
6678
+ parts.push(`
6679
+ function timeout(fn, ms) {
6680
+ return Promise.race([
6681
+ typeof fn === 'function' ? fn() : fn,
6682
+ new Promise(function(_, reject) {
6683
+ setTimeout(function() { reject(new Error('Timeout after ' + ms + 'ms')); }, ms);
6684
+ })
6685
+ ]);
6686
+ }`);
6687
+ }
6688
+ if (needed.has("allSettled")) {
6689
+ parts.push(`
6690
+ function allSettled(promises) {
6691
+ return Promise.allSettled(promises);
6692
+ }`);
6693
+ }
6694
+ if (needed.has("debounce")) {
6695
+ parts.push(`
6696
+ function debounce(fn, ms) {
6697
+ var timer;
6698
+ return function() {
6699
+ clearTimeout(timer);
6700
+ var args = arguments;
6701
+ var ctx = this;
6702
+ timer = setTimeout(function() { fn.apply(ctx, args); }, ms);
6703
+ };
6704
+ }`);
6705
+ }
6706
+ if (needed.has("throttle")) {
6707
+ parts.push(`
6708
+ function throttle(fn, ms) {
6709
+ var last = 0;
6710
+ return function() {
6711
+ var now = Date.now();
6712
+ if (now - last >= ms) { last = now; return fn.apply(this, arguments); }
6713
+ };
6154
6714
  }`);
6155
6715
  }
6156
6716
  if (needed.has("memoize")) {
@@ -6197,50 +6757,37 @@ function curry(fn) {
6197
6757
  };
6198
6758
  }`);
6199
6759
  }
6200
- if (needed.has("capitalize")) {
6760
+ if (needed.has("identity")) {
6201
6761
  parts.push(`
6202
- function capitalize(s) {
6203
- return s ? s[0].toUpperCase() + s.slice(1) : s;
6204
- }`);
6762
+ function identity(v) { return v; }`);
6205
6763
  }
6206
- if (needed.has("camelCase")) {
6764
+ if (needed.has("noop")) {
6207
6765
  parts.push(`
6208
- function camelCase(s) {
6209
- return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
6210
- }`);
6766
+ function noop() {}`);
6211
6767
  }
6212
- if (needed.has("snakeCase")) {
6213
- parts.push(`
6214
- function snakeCase(s) {
6215
- return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
6216
- }`);
6217
- }
6218
- if (needed.has("kebabCase")) {
6768
+ if (needed.has("once")) {
6219
6769
  parts.push(`
6220
- function kebabCase(s) {
6221
- return s.replace(/([A-Z])/g, function(c) { return '-' + c.toLowerCase(); }).replace(/[_\\s]+/g, '-').replace(/^-/, '');
6770
+ function once(fn) {
6771
+ var called = false, result;
6772
+ return function() {
6773
+ if (!called) { called = true; result = fn.apply(this, arguments); }
6774
+ return result;
6775
+ };
6222
6776
  }`);
6223
6777
  }
6224
- if (needed.has("truncate")) {
6778
+ if (needed.has("flip")) {
6225
6779
  parts.push(`
6226
- function truncate(s, len, suffix) {
6227
- suffix = suffix != null ? suffix : '...';
6228
- if (s.length <= len) return s;
6229
- // FIX: guard against suffix longer than len to avoid negative slice index
6230
- var cut = len - suffix.length;
6231
- if (cut <= 0) return suffix.slice(0, len);
6232
- return s.slice(0, cut) + suffix;
6780
+ function flip(fn) {
6781
+ return function() {
6782
+ var args = Array.from(arguments);
6783
+ return fn.apply(this, [args[1], args[0]].concat(args.slice(2)));
6784
+ };
6233
6785
  }`);
6234
6786
  }
6235
- if (needed.has("pad")) {
6787
+ if (needed.has("complement")) {
6236
6788
  parts.push(`
6237
- function pad(s, len, char) {
6238
- char = char || ' ';
6239
- s = String(s);
6240
- var total = len - s.length;
6241
- if (total <= 0) return s;
6242
- var half = Math.floor(total / 2);
6243
- return char.repeat(half) + s + char.repeat(total - half);
6789
+ function complement(fn) {
6790
+ return function() { return !fn.apply(this, arguments); };
6244
6791
  }`);
6245
6792
  }
6246
6793
  parts.push("// \u2500\u2500 end stdlib \u2500\u2500\n");