@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.cjs.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
@@ -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:
@@ -2515,7 +2545,7 @@ function _fmt(v, s) {
2515
2545
  this.lines = [];
2516
2546
  this.level = 0;
2517
2547
  this._needsFmt = false;
2518
- this.emit("// Generated by Flux Transpiler v3.1.0");
2548
+ this.emit("// Generated by Flux Transpiler v3.2.0");
2519
2549
  this.emit('"use strict";');
2520
2550
  this.blank();
2521
2551
  for (const node of ast.body) this.genStmt(node);
@@ -2619,17 +2649,30 @@ function _fmt(v, s) {
2619
2649
  this.out();
2620
2650
  this.emit("}");
2621
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
+ }
2622
2659
  }
2623
2660
  // ── class ──────────────────────────────────────────────────────
2624
2661
  genClass(node) {
2625
2662
  const ext = node.superClass ? ` extends ${node.superClass}` : "";
2626
2663
  this.emit(`class ${node.name}${ext} {`);
2627
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();
2628
2671
  const allFields = getAllFields(node.name, this.clsReg);
2629
- const paramFields = allFields.filter((f) => f.init == null);
2672
+ const paramFields = allFields.filter((f) => f.init == null && !isPrivate(f));
2630
2673
  const initFields = allFields.filter((f) => f.init != null);
2631
2674
  const ownInitFields = node.fields.filter((f) => f.init != null);
2632
- const needsCtor = paramFields.length > 0 || initFields.length > 0;
2675
+ const needsCtor = paramFields.length > 0 || initFields.length > 0 || privateFields.length > 0;
2633
2676
  if (needsCtor) {
2634
2677
  const params = paramFields.map((f) => f.name).join(", ");
2635
2678
  this.emit(`constructor(${params}) {`);
@@ -2640,10 +2683,10 @@ function _fmt(v, s) {
2640
2683
  if (parentParams.length > 0)
2641
2684
  this.emit(`super(${parentParams.map((f) => f.name).join(", ")});`);
2642
2685
  }
2643
- for (const f of node.fields.filter((f2) => f2.init == null))
2644
- this.emit(`this.${f.name} = ${f.name};`);
2686
+ for (const f of node.fields.filter((f2) => f2.init == null && !isPrivate(f2)))
2687
+ this.emit(`${fieldRef(f)} = ${f.name};`);
2645
2688
  for (const f of ownInitFields)
2646
- this.emit(`this.${f.name} = ${this.genExpr(f.init)};`);
2689
+ this.emit(`${fieldRef(f)} = ${this.genExpr(f.init)};`);
2647
2690
  this.out();
2648
2691
  this.emit("}");
2649
2692
  this.blank();
@@ -2668,6 +2711,13 @@ function _fmt(v, s) {
2668
2711
  }
2669
2712
  this.out();
2670
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
+ }
2671
2721
  this.blank();
2672
2722
  }
2673
2723
  // ── if / else if / else ─────────────────────────────────────────
@@ -5897,41 +5947,16 @@ var require_stdlib = __commonJS({
5897
5947
  "src/stdlib.js"(exports2, module2) {
5898
5948
  "use strict";
5899
5949
  var STDLIB_SYMBOLS2 = [
5950
+ // Sequences
5900
5951
  "range",
5901
5952
  "zip",
5902
5953
  "enumerate",
5903
- "clamp",
5904
- "sum",
5905
- "product",
5906
5954
  "flatten",
5907
5955
  "chunk",
5908
5956
  "unique",
5909
5957
  "groupBy",
5910
5958
  "sortBy",
5911
- "pick",
5912
- "omit",
5913
- "deepEqual",
5914
- "deepClone",
5915
- "sleep",
5916
- "retry",
5917
- "memoize",
5918
- "pipe",
5919
- "compose",
5920
- "partial",
5921
- "curry",
5922
- "capitalize",
5923
- "camelCase",
5924
- "snakeCase",
5925
- "kebabCase",
5926
- "truncate",
5927
- "pad",
5928
- "randInt",
5929
- "sample",
5930
- "shuffle",
5931
- "mapValues",
5932
- "filterValues",
5933
- "fromEntries",
5934
- // Array pipe helpers — standalone wrappers around Array.prototype methods
5959
+ // Array pipe helpers
5935
5960
  "map",
5936
5961
  "filter",
5937
5962
  "reduce",
@@ -5944,7 +5969,106 @@ var require_stdlib = __commonJS({
5944
5969
  "sort",
5945
5970
  "flat",
5946
5971
  "flatMap",
5947
- "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"
5948
6072
  ];
5949
6073
  function buildStdlib2(symbols) {
5950
6074
  const needed = symbols ? new Set(symbols.filter((s) => STDLIB_SYMBOLS2.includes(s))) : new Set(STDLIB_SYMBOLS2);
@@ -6068,6 +6192,148 @@ function sortBy(arr, fn) {
6068
6192
  var kb = typeof fn === 'function' ? fn(b) : b[fn];
6069
6193
  return ka < kb ? -1 : ka > kb ? 1 : 0;
6070
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;
6071
6337
  }`);
6072
6338
  }
6073
6339
  if (needed.has("clamp")) {
@@ -6087,6 +6353,69 @@ function sum(arr) {
6087
6353
  function product(arr) {
6088
6354
  return arr.reduce(function(a, b) { return a * b; }, 1);
6089
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; }`);
6090
6419
  }
6091
6420
  if (needed.has("randInt")) {
6092
6421
  parts.push(`
@@ -6148,6 +6477,43 @@ function filterValues(obj, fn) {
6148
6477
  parts.push(`
6149
6478
  function fromEntries(entries) {
6150
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;
6151
6517
  }`);
6152
6518
  }
6153
6519
  if (needed.has("deepEqual")) {
@@ -6161,6 +6527,133 @@ function deepEqual(a, b) {
6161
6527
  function deepClone(v) {
6162
6528
  return JSON.parse(JSON.stringify(v));
6163
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'; }`);
6164
6657
  }
6165
6658
  if (needed.has("sleep")) {
6166
6659
  parts.push(`
@@ -6176,9 +6669,48 @@ async function retry(fn, attempts, delay) {
6176
6669
  for (var i = 0; i < attempts; i++) {
6177
6670
  try { return await fn(); } catch(e) {
6178
6671
  if (i === attempts - 1) throw e;
6179
- await sleep(delay * Math.pow(2, i));
6672
+ await new Promise(function(r) { setTimeout(r, delay * Math.pow(2, i)); });
6180
6673
  }
6181
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
+ };
6182
6714
  }`);
6183
6715
  }
6184
6716
  if (needed.has("memoize")) {
@@ -6225,50 +6757,37 @@ function curry(fn) {
6225
6757
  };
6226
6758
  }`);
6227
6759
  }
6228
- if (needed.has("capitalize")) {
6229
- parts.push(`
6230
- function capitalize(s) {
6231
- return s ? s[0].toUpperCase() + s.slice(1) : s;
6232
- }`);
6233
- }
6234
- if (needed.has("camelCase")) {
6760
+ if (needed.has("identity")) {
6235
6761
  parts.push(`
6236
- function camelCase(s) {
6237
- return s.replace(/[-_\\s]+(.)/g, function(_, c) { return c.toUpperCase(); }).replace(/^./, function(c) { return c.toLowerCase(); });
6238
- }`);
6762
+ function identity(v) { return v; }`);
6239
6763
  }
6240
- if (needed.has("snakeCase")) {
6764
+ if (needed.has("noop")) {
6241
6765
  parts.push(`
6242
- function snakeCase(s) {
6243
- return s.replace(/([A-Z])/g, function(c) { return '_' + c.toLowerCase(); }).replace(/[-\\s]+/g, '_').replace(/^_/, '');
6244
- }`);
6766
+ function noop() {}`);
6245
6767
  }
6246
- if (needed.has("kebabCase")) {
6768
+ if (needed.has("once")) {
6247
6769
  parts.push(`
6248
- function kebabCase(s) {
6249
- 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
+ };
6250
6776
  }`);
6251
6777
  }
6252
- if (needed.has("truncate")) {
6778
+ if (needed.has("flip")) {
6253
6779
  parts.push(`
6254
- function truncate(s, len, suffix) {
6255
- suffix = suffix != null ? suffix : '...';
6256
- if (s.length <= len) return s;
6257
- // FIX: guard against suffix longer than len to avoid negative slice index
6258
- var cut = len - suffix.length;
6259
- if (cut <= 0) return suffix.slice(0, len);
6260
- 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
+ };
6261
6785
  }`);
6262
6786
  }
6263
- if (needed.has("pad")) {
6787
+ if (needed.has("complement")) {
6264
6788
  parts.push(`
6265
- function pad(s, len, char) {
6266
- char = char || ' ';
6267
- s = String(s);
6268
- var total = len - s.length;
6269
- if (total <= 0) return s;
6270
- var half = Math.floor(total / 2);
6271
- return char.repeat(half) + s + char.repeat(total - half);
6789
+ function complement(fn) {
6790
+ return function() { return !fn.apply(this, arguments); };
6272
6791
  }`);
6273
6792
  }
6274
6793
  parts.push("// \u2500\u2500 end stdlib \u2500\u2500\n");