bonsai-js 1.0.0 → 1.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +24 -4
  3. package/dist/artifact.d.mts +47 -0
  4. package/dist/artifact.mjs +139 -0
  5. package/dist/artifact.mjs.map +1 -0
  6. package/dist/builtins/index.d.mts +91 -0
  7. package/dist/builtins/index.mjs +93 -0
  8. package/dist/builtins/index.mjs.map +1 -0
  9. package/dist/check/bind.mjs +117 -0
  10. package/dist/check/bind.mjs.map +1 -0
  11. package/dist/check/checker.mjs +34 -120
  12. package/dist/check/checker.mjs.map +1 -1
  13. package/dist/compile/compiler.mjs +2 -3
  14. package/dist/compile/compiler.mjs.map +1 -1
  15. package/dist/declared.mjs +8 -1
  16. package/dist/declared.mjs.map +1 -1
  17. package/dist/digest.mjs +109 -0
  18. package/dist/digest.mjs.map +1 -0
  19. package/dist/environment.d.mts +14 -1
  20. package/dist/environment.mjs +65 -315
  21. package/dist/environment.mjs.map +1 -1
  22. package/dist/errors.d.mts +21 -2
  23. package/dist/errors.mjs +17 -1
  24. package/dist/errors.mjs.map +1 -1
  25. package/dist/features.mjs +3 -3
  26. package/dist/features.mjs.map +1 -1
  27. package/dist/functions/builtins.mjs +551 -474
  28. package/dist/functions/builtins.mjs.map +1 -1
  29. package/dist/functions/define.mjs +53 -11
  30. package/dist/functions/define.mjs.map +1 -1
  31. package/dist/functions/descriptions.mjs +110 -0
  32. package/dist/functions/descriptions.mjs.map +1 -0
  33. package/dist/index.d.mts +4 -3
  34. package/dist/index.mjs +3 -2
  35. package/dist/lite/index.d.mts +4 -3
  36. package/dist/lite/index.mjs +3 -2
  37. package/dist/lite/index.mjs.map +1 -1
  38. package/dist/load.mjs +307 -0
  39. package/dist/load.mjs.map +1 -0
  40. package/dist/program.mjs +321 -0
  41. package/dist/program.mjs.map +1 -0
  42. package/dist/query/index.mjs +1 -1
  43. package/dist/runtime/core.d.mts +18 -0
  44. package/dist/runtime/core.mjs +31 -0
  45. package/dist/runtime/core.mjs.map +1 -0
  46. package/dist/runtime/create.d.mts +61 -0
  47. package/dist/runtime/create.mjs +76 -0
  48. package/dist/runtime/create.mjs.map +1 -0
  49. package/dist/runtime/index.d.mts +24 -0
  50. package/dist/runtime/index.mjs +34 -0
  51. package/dist/runtime/index.mjs.map +1 -0
  52. package/dist/service/index.mjs +12 -8
  53. package/dist/service/index.mjs.map +1 -1
  54. package/dist/syntax/parser.mjs +1 -1
  55. package/dist/syntax/printer.mjs +1 -1
  56. package/dist/types.mjs +103 -23
  57. package/dist/types.mjs.map +1 -1
  58. package/dist/version.mjs +7 -0
  59. package/dist/version.mjs.map +1 -0
  60. package/package.json +26 -2
@@ -1,9 +1,9 @@
1
1
  import { BLOCKED_NAMES } from "../syntax/lexer.mjs";
2
- import { RegexSyntaxError, compileRegex, searchRegex } from "../runtime/regex.mjs";
3
2
  import { Duration, MS_PER_DAY, MS_PER_HOUR, MS_PER_MINUTE, MS_PER_SECOND, MS_PER_WEEK, chargeIndexKey, chargeKey, chargeSearch, contains, dateTime, describeKind, durationOf, equals, errorText, holdsKey, isMap, isTimestamp, isValidDuration, keyListCost, kindOf, mapBuildCost, order, shown, sortOrder, timeOf, toText, track } from "../runtime/values.mjs";
4
- import { addDays, addMonths, checkDatePattern, checked, formatTimestamp, fromWallClock, isoWeekday, parseTimestamp, wallClock } from "../runtime/time.mjs";
5
3
  import { isExact, t, unionOf, widen } from "../types.mjs";
6
4
  import { K, Out, T, U, define, fnType, overload } from "./define.mjs";
5
+ import { RegexSyntaxError, compileRegex, searchRegex } from "../runtime/regex.mjs";
6
+ import { addDays as addDays$1, addMonths as addMonths$1, checkDatePattern, checked, formatTimestamp, fromWallClock, isoWeekday, parseTimestamp, wallClock, warmZone } from "../runtime/time.mjs";
7
7
  //#region src/functions/builtins.ts
8
8
  /** What toNumber accepts: an optional sign, digits with an optional fraction, and an optional exponent. */
9
9
  const DECIMAL_TEXT = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/u;
@@ -14,17 +14,17 @@ const MAX_EXACT_INTEGER = Number.MAX_SAFE_INTEGER + 1;
14
14
  /** Where Number#toFixed switches to exponential notation. */
15
15
  const FIXED_NOTATION_LIMIT = 1e21;
16
16
  const MONTHS_PER_YEAR = 12;
17
- const any = t.any();
18
- const num = t.number();
19
- const str = t.string();
20
- const bool = t.boolean();
21
- const ts = t.timestamp();
22
- const dur = t.duration();
23
- const listT = t.list(T);
24
- const optT = t.optional(T);
25
- const optStr = t.optional(str);
26
- const predicate = fnType([T, num], bool);
27
- const primitiveText = t.union(str, num, bool, t.null());
17
+ const any = /* @__PURE__ */ t.any();
18
+ const num = /* @__PURE__ */ t.number();
19
+ const str = /* @__PURE__ */ t.string();
20
+ const bool = /* @__PURE__ */ t.boolean();
21
+ const ts = /* @__PURE__ */ t.timestamp();
22
+ const dur = /* @__PURE__ */ t.duration();
23
+ const listT = /* @__PURE__ */ t.list(T);
24
+ const optT = /* @__PURE__ */ t.optional(T);
25
+ const optStr = /* @__PURE__ */ t.optional(str);
26
+ const predicate = /* @__PURE__ */ fnType([T, num], bool);
27
+ const primitiveText = /* @__PURE__ */ t.union(str, num, bool, t.null());
28
28
  function integer(value, what, site) {
29
29
  if (typeof value !== "number" || !Number.isInteger(value)) throw site.state.error("INVALID_ARGUMENT", `${what} must be an integer, not ${typeof value === "number" ? String(value) : describeKind(value)}`, site.span);
30
30
  return value;
@@ -532,16 +532,18 @@ function extreme(items, sign, site) {
532
532
  return best;
533
533
  }
534
534
  /**
535
- * min and max of their arguments, one overload per kind a list can order, so
536
- * `max(a, b)` takes what `[a, b].max()` does (and, unlike the list, no nulls).
535
+ * The overloads of min and max: of a list, then of their arguments, one
536
+ * overload per kind a list can order, so `max(a, b)` takes what `[a, b].max()`
537
+ * does (and, unlike the list, no nulls). Built in one call, not spread into a
538
+ * literal, so an unused min or max stays a pure call that bundlers drop.
537
539
  */
538
- function spreadExtremes(sign) {
539
- return [
540
+ function extremes(sign) {
541
+ return [overload([listT], optT, ([l], site) => extreme(list(l), sign, site), { ordered: ["T"] }), ...[
540
542
  num,
541
543
  str,
542
544
  ts,
543
545
  dur
544
- ].map((kind) => overload([kind], kind, (args, site) => extreme(args, sign, site), { rest: kind }));
546
+ ].map((kind) => overload([kind], kind, (args, site) => extreme(args, sign, site), { rest: kind }))];
545
547
  }
546
548
  function entryList(map, site) {
547
549
  const listed = Object.keys(map);
@@ -558,203 +560,199 @@ function valueTypeOf(type) {
558
560
  if (type.rest !== void 0) members.push(type.rest);
559
561
  return members.length === 0 ? any : unionOf(members.map(widen));
560
562
  }
561
- const STRING_FUNCTIONS = [
562
- define("toUpperCase", "Upper-cases text.", [overload([str], str, ([s]) => s.toUpperCase())]),
563
- define("toLowerCase", "Lower-cases text.", [overload([str], str, ([s]) => s.toLowerCase())]),
564
- define("trim", "Removes leading and trailing whitespace.", [overload([str], str, ([s]) => s.trim())]),
565
- define("trimStart", "Removes leading whitespace.", [overload([str], str, ([s]) => s.trimStart())]),
566
- define("trimEnd", "Removes trailing whitespace.", [overload([str], str, ([s]) => s.trimEnd())]),
567
- define("startsWith", "Whether text starts with a prefix.", [overload([str, str], bool, ([s, p]) => s.startsWith(p))]),
568
- define("endsWith", "Whether text ends with a suffix.", [overload([str, str], bool, ([s, p]) => s.endsWith(p))]),
569
- define("includes", "Whether text contains a substring, or a list contains a value.", [overload([str, str], bool, ([s, p], site) => {
570
- chargeSearch(site.state, s.length, p.length);
571
- return s.includes(p);
572
- }), overload([listT, any], bool, ([l, v], site) => contains(l, v, site.state, site.span))]),
573
- define("indexOf", "Position of the first match, or -1.", [overload([str, str], num, ([s, p], site) => {
574
- chargeSearch(site.state, s.length, p.length);
575
- return s.indexOf(p);
576
- }), overload([listT, any], num, ([l, v], site) => {
577
- const items = list(l);
578
- site.state.charge(items.length);
579
- for (let i = 0; i < items.length; i++) if (equals(items[i], v, site.state, 0, site.span)) return i;
580
- return -1;
581
- })]),
582
- define("lastIndexOf", "Position of the last match, or -1.", [overload([str, str], num, ([s, p], site) => {
583
- chargeSearch(site.state, s.length, p.length);
584
- return s.lastIndexOf(p);
585
- }), overload([listT, any], num, ([l, v], site) => {
586
- const items = list(l);
587
- site.state.charge(items.length);
588
- for (let i = items.length - 1; i >= 0; i--) if (equals(items[i], v, site.state, 0, site.span)) return i;
589
- return -1;
590
- })]),
591
- define("slice", "A section of text or a list; negative positions count from the end.", [overload([
592
- str,
593
- num,
594
- num
595
- ], str, ([s, a, b], site) => s.slice(integer(a, "Start", site), b === void 0 || b === null ? void 0 : integer(b, "End", site)), { required: 2 }), overload([
596
- listT,
597
- num,
598
- num
599
- ], listT, ([l, a, b], site) => {
600
- const items = list(l);
601
- const [from, to] = slicePositions(items.length, integer(a, "Start", site), b === void 0 || b === null ? void 0 : integer(b, "End", site));
602
- site.state.charge(to - from);
603
- site.state.listLimit(to - from, site.span);
604
- return made(copyOf(items, from, to), site);
605
- }, { required: 2 })]),
606
- define("split", "Splits text on a separator.", [overload([
607
- str,
608
- str,
609
- num
610
- ], t.list(str), ([s, sep, limit], site) => {
611
- const text = s;
612
- site.state.charge(1 + (text.length >>> 4));
613
- chargeSearch(site.state, text.length, sep.length);
614
- const max = limit === void 0 || limit === null ? void 0 : nonNegativeInteger(limit, "Limit", site);
615
- const cap = site.state.limits.maxListLength + 1;
616
- const parts = text.split(sep, max === void 0 ? cap : Math.min(max, cap));
617
- site.state.listLimit(parts.length, site.span);
618
- site.state.charge(parts.length);
619
- return parts;
620
- }, { required: 2 })]),
621
- define("replace", "Replaces the first occurrence of some text (no patterns).", [overload([
622
- str,
623
- str,
624
- str
625
- ], str, ([s, f, r], site) => replaceText(s, f, r, false, site))]),
626
- define("replaceAll", "Replaces every occurrence of some text (no patterns).", [overload([
627
- str,
628
- str,
629
- str
630
- ], str, ([s, f, r], site) => replaceText(s, f, r, true, site))]),
631
- define("padStart", "Pads text at the start to a length.", [overload([
632
- str,
633
- num,
634
- str
635
- ], str, ([s, n, f], site) => pad(s, n, f, true, site), { required: 2 })]),
636
- define("padEnd", "Pads text at the end to a length.", [overload([
637
- str,
638
- num,
639
- str
640
- ], str, ([s, n, f], site) => pad(s, n, f, false, site), { required: 2 })]),
641
- define("repeat", "Repeats text a number of times.", [overload([str, num], str, ([s, n], site) => {
642
- const count = nonNegativeInteger(n, "Count", site);
643
- const text = s;
644
- site.state.stringLimit(text.length * count, site.span);
645
- site.state.charge(1 + (text.length * count >>> 6));
646
- return text.repeat(count);
647
- })]),
648
- define("at", "The item or character at a position; negative positions count from the end.", [overload([str, num], optStr, ([s, i], site) => s.at(integer(i, "Index", site)) ?? null), overload([listT, num], optT, ([l, i], site) => {
649
- const items = list(l);
650
- const index = integer(i, "Index", site);
651
- const position = index < 0 ? items.length + index : index;
652
- return position < 0 || position >= items.length ? null : items[position] ?? null;
653
- })]),
654
- define("matches", "Whether text contains a match for a regular expression (JavaScript syntax without backreferences or lookaround, linear time; anchor with ^ and $; prefix (?i) to ignore case).", [overload([str, str], bool, ([s, p], site) => {
655
- const program = regexFor(p, site);
656
- return searchRegex(program, s, (n) => {
657
- site.state.charge(n);
658
- });
659
- }, { literals: ([, pattern]) => {
660
- if (typeof pattern !== "string") return void 0;
661
- try {
662
- cachedRegex(pattern);
663
- return;
664
- } catch (error) {
665
- return error instanceof Error ? error.message : String(error);
666
- }
667
- } })]),
668
- define("toString", "Renders a value as text, as a template would.", [overload([t.union(primitiveText, ts, dur)], str, ([v], site) => textOf(v, site))]),
669
- define("toNumber", "Parses decimal text as a number, e.g. \"-12.5\" or \"1e3\" (surrounding whitespace is ignored; 0x and other bases are not accepted).", [overload([t.union(str, num)], num, ([v], site) => {
670
- if (typeof v === "number") return v;
671
- const text = v.trim();
672
- const value = DECIMAL_TEXT.test(text) ? Number(text) : NaN;
673
- if (!Number.isFinite(value)) throw site.state.error("INVALID_ARGUMENT", `Cannot convert ${shown(v)} to a number`, site.span);
674
- return value;
675
- })])
676
- ];
563
+ const toUpperCase = /* @__PURE__ */ define("toUpperCase", [/* @__PURE__ */ overload([str], str, ([s]) => s.toUpperCase())]);
564
+ const toLowerCase = /* @__PURE__ */ define("toLowerCase", [/* @__PURE__ */ overload([str], str, ([s]) => s.toLowerCase())]);
565
+ const trim = /* @__PURE__ */ define("trim", [/* @__PURE__ */ overload([str], str, ([s]) => s.trim())]);
566
+ const trimStart = /* @__PURE__ */ define("trimStart", [/* @__PURE__ */ overload([str], str, ([s]) => s.trimStart())]);
567
+ const trimEnd = /* @__PURE__ */ define("trimEnd", [/* @__PURE__ */ overload([str], str, ([s]) => s.trimEnd())]);
568
+ const startsWith = /* @__PURE__ */ define("startsWith", [/* @__PURE__ */ overload([str, str], bool, ([s, p]) => s.startsWith(p))]);
569
+ const endsWith = /* @__PURE__ */ define("endsWith", [/* @__PURE__ */ overload([str, str], bool, ([s, p]) => s.endsWith(p))]);
570
+ const includes = /* @__PURE__ */ define("includes", [/* @__PURE__ */ overload([str, str], bool, ([s, p], site) => {
571
+ chargeSearch(site.state, s.length, p.length);
572
+ return s.includes(p);
573
+ }), /* @__PURE__ */ overload([listT, any], bool, ([l, v], site) => contains(l, v, site.state, site.span))]);
574
+ const indexOf = /* @__PURE__ */ define("indexOf", [/* @__PURE__ */ overload([str, str], num, ([s, p], site) => {
575
+ chargeSearch(site.state, s.length, p.length);
576
+ return s.indexOf(p);
577
+ }), /* @__PURE__ */ overload([listT, any], num, ([l, v], site) => {
578
+ const items = list(l);
579
+ site.state.charge(items.length);
580
+ for (let i = 0; i < items.length; i++) if (equals(items[i], v, site.state, 0, site.span)) return i;
581
+ return -1;
582
+ })]);
583
+ const lastIndexOf = /* @__PURE__ */ define("lastIndexOf", [/* @__PURE__ */ overload([str, str], num, ([s, p], site) => {
584
+ chargeSearch(site.state, s.length, p.length);
585
+ return s.lastIndexOf(p);
586
+ }), /* @__PURE__ */ overload([listT, any], num, ([l, v], site) => {
587
+ const items = list(l);
588
+ site.state.charge(items.length);
589
+ for (let i = items.length - 1; i >= 0; i--) if (equals(items[i], v, site.state, 0, site.span)) return i;
590
+ return -1;
591
+ })]);
592
+ const slice = /* @__PURE__ */ define("slice", [/* @__PURE__ */ overload([
593
+ str,
594
+ num,
595
+ num
596
+ ], str, ([s, a, b], site) => s.slice(integer(a, "Start", site), b === void 0 || b === null ? void 0 : integer(b, "End", site)), { required: 2 }), /* @__PURE__ */ overload([
597
+ listT,
598
+ num,
599
+ num
600
+ ], listT, ([l, a, b], site) => {
601
+ const items = list(l);
602
+ const [from, to] = slicePositions(items.length, integer(a, "Start", site), b === void 0 || b === null ? void 0 : integer(b, "End", site));
603
+ site.state.charge(to - from);
604
+ site.state.listLimit(to - from, site.span);
605
+ return made(copyOf(items, from, to), site);
606
+ }, { required: 2 })]);
607
+ const split = /* @__PURE__ */ define("split", [/* @__PURE__ */ overload([
608
+ str,
609
+ str,
610
+ num
611
+ ], /* @__PURE__ */ t.list(str), ([s, sep, limit], site) => {
612
+ const text = s;
613
+ site.state.charge(1 + (text.length >>> 4));
614
+ chargeSearch(site.state, text.length, sep.length);
615
+ const max = limit === void 0 || limit === null ? void 0 : nonNegativeInteger(limit, "Limit", site);
616
+ const cap = site.state.limits.maxListLength + 1;
617
+ const parts = text.split(sep, max === void 0 ? cap : Math.min(max, cap));
618
+ site.state.listLimit(parts.length, site.span);
619
+ site.state.charge(parts.length);
620
+ return parts;
621
+ }, { required: 2 })]);
622
+ const replace = /* @__PURE__ */ define("replace", [/* @__PURE__ */ overload([
623
+ str,
624
+ str,
625
+ str
626
+ ], str, ([s, f, r], site) => replaceText(s, f, r, false, site))]);
627
+ const replaceAll = /* @__PURE__ */ define("replaceAll", [/* @__PURE__ */ overload([
628
+ str,
629
+ str,
630
+ str
631
+ ], str, ([s, f, r], site) => replaceText(s, f, r, true, site))]);
632
+ const padStart = /* @__PURE__ */ define("padStart", [/* @__PURE__ */ overload([
633
+ str,
634
+ num,
635
+ str
636
+ ], str, ([s, n, f], site) => pad(s, n, f, true, site), { required: 2 })]);
637
+ const padEnd = /* @__PURE__ */ define("padEnd", [/* @__PURE__ */ overload([
638
+ str,
639
+ num,
640
+ str
641
+ ], str, ([s, n, f], site) => pad(s, n, f, false, site), { required: 2 })]);
642
+ const repeat = /* @__PURE__ */ define("repeat", [/* @__PURE__ */ overload([str, num], str, ([s, n], site) => {
643
+ const count = nonNegativeInteger(n, "Count", site);
644
+ const text = s;
645
+ site.state.stringLimit(text.length * count, site.span);
646
+ site.state.charge(1 + (text.length * count >>> 6));
647
+ return text.repeat(count);
648
+ })]);
649
+ const at = /* @__PURE__ */ define("at", [/* @__PURE__ */ overload([str, num], optStr, ([s, i], site) => s.at(integer(i, "Index", site)) ?? null), /* @__PURE__ */ overload([listT, num], optT, ([l, i], site) => {
650
+ const items = list(l);
651
+ const index = integer(i, "Index", site);
652
+ const position = index < 0 ? items.length + index : index;
653
+ return position < 0 || position >= items.length ? null : items[position] ?? null;
654
+ })]);
655
+ const matches = /* @__PURE__ */ define("matches", [/* @__PURE__ */ overload([str, str], bool, ([s, p], site) => {
656
+ const program = regexFor(p, site);
657
+ return searchRegex(program, s, (n) => {
658
+ site.state.charge(n);
659
+ });
660
+ }, { literals: ([, pattern]) => {
661
+ if (typeof pattern !== "string") return void 0;
662
+ try {
663
+ cachedRegex(pattern);
664
+ return;
665
+ } catch (error) {
666
+ return error instanceof Error ? error.message : String(error);
667
+ }
668
+ } })]);
669
+ const toString = /* @__PURE__ */ define("toString", [/* @__PURE__ */ overload([/* @__PURE__ */ t.union(primitiveText, ts, dur)], str, ([v], site) => textOf(v, site))]);
670
+ const toNumber = /* @__PURE__ */ define("toNumber", [/* @__PURE__ */ overload([/* @__PURE__ */ t.union(str, num)], num, ([v], site) => {
671
+ if (typeof v === "number") return v;
672
+ const text = v.trim();
673
+ const value = DECIMAL_TEXT.test(text) ? Number(text) : NaN;
674
+ if (!Number.isFinite(value)) throw site.state.error("INVALID_ARGUMENT", `Cannot convert ${shown(v)} to a number`, site.span);
675
+ return value;
676
+ })]);
677
677
  /** A built-in applying a number function whose result must be finite. */
678
- function math(name, description, apply) {
679
- return define(name, description, [overload([num], num, ([n], site) => finite(apply(n), site))]);
678
+ function math(name, apply) {
679
+ return define(name, [overload([num], num, ([n], site) => finite(apply(n), site))]);
680
680
  }
681
- const NUMBER_FUNCTIONS = [
682
- define("round", "Rounds half away from zero, optionally to a number of decimal digits.", [overload([num, num], num, ([n, d], site) => roundTo(n, d === void 0 || d === null ? 0 : d, site), { required: 1 })]),
683
- math("floor", "Rounds down.", Math.floor),
684
- math("ceil", "Rounds up.", Math.ceil),
685
- math("trunc", "Drops the fractional part.", Math.trunc),
686
- define("abs", "Absolute value.", [overload([num], num, ([n], site) => finite(Math.abs(n), site)), overload([dur], dur, ([d]) => new Duration(Math.abs(d.ms)))]),
687
- math("sqrt", "Square root.", Math.sqrt),
688
- define("clamp", "Limits a number to a range.", [overload([
689
- num,
690
- num,
691
- num
692
- ], num, ([n, lo, hi], site) => {
693
- if (lo > hi) throw site.state.error("INVALID_ARGUMENT", "clamp: min is greater than max", site.span);
694
- finite(n, site);
695
- finite(lo, site);
696
- finite(hi, site);
697
- return finite(Math.min(Math.max(n, lo), hi), site);
698
- })]),
699
- define("toFixed", "Formats a number with a fixed number of decimals.", [overload([num, num], str, ([n, d], site) => {
700
- const digits = nonNegativeInteger(d, "Digits", site);
701
- if (digits > MAX_FIXED_DIGITS) throw site.state.error("INVALID_ARGUMENT", "Digits must be at most 100", site.span);
702
- site.state.charge(digits >>> 2);
703
- finite(n, site);
704
- const value = digits <= MAX_ROUND_DIGITS ? roundTo(n, digits, site) : n;
705
- if (Math.abs(value) >= FIXED_NOTATION_LIMIT) return `${BigInt(value).toString()}${digits > 0 ? `.${"0".repeat(digits)}` : ""}`;
706
- return value.toFixed(digits);
707
- })]),
708
- define("formatNumber", "Formats a number with grouping, e.g. 1,234.5, with optional decimals and locale (default \"en-US\"; an unsupported locale is an error).", [overload([
709
- num,
710
- t.optional(num),
711
- t.optional(str)
712
- ], str, ([n, d, locale], site) => {
713
- const digits = d === void 0 || d === null ? void 0 : nonNegativeInteger(d, "Decimals", site);
714
- if (digits !== void 0 && digits > MAX_INTL_DIGITS) throw site.state.error("INVALID_ARGUMENT", `Decimals must be at most ${MAX_INTL_DIGITS}`, site.span);
715
- const options = digits === void 0 ? { maximumFractionDigits: MAX_INTL_DIGITS } : {
716
- minimumFractionDigits: digits,
717
- maximumFractionDigits: digits
718
- };
719
- finite(n, site);
720
- const value = digits === void 0 || digits > MAX_ROUND_DIGITS ? n : roundTo(n, digits, site);
721
- return numberFormat(typeof locale === "string" ? locale : "en-US", options, site).format(value);
722
- }, {
723
- required: 1,
724
- literals: ([, , locale]) => formatProblem(locale, void 0)
725
- })]),
726
- define("formatCurrency", "Formats an amount in a currency (ISO 4217 code such as \"EUR\"; a code without a known symbol prints as the code), with an optional locale (default \"en-US\"; an unsupported locale is an error).", [overload([
727
- num,
728
- str,
729
- t.optional(str)
730
- ], str, ([n, currency, locale], site) => numberFormat(typeof locale === "string" ? locale : "en-US", {
731
- style: "currency",
732
- currency
733
- }, site).format(finite(n, site)), {
734
- required: 2,
735
- literals: ([, currency, locale]) => formatProblem(locale, currency)
736
- })]),
737
- define("min", "The smallest value (nulls are skipped); null for an empty list.", [overload([listT], optT, ([l], site) => extreme(list(l), -1, site), { ordered: ["T"] }), ...spreadExtremes(-1)]),
738
- define("max", "The largest value (nulls are skipped); null for an empty list.", [overload([listT], optT, ([l], site) => extreme(list(l), 1, site), { ordered: ["T"] }), ...spreadExtremes(1)]),
739
- define("sum", "The sum of the numbers in a list (nulls are skipped), added left to right as a + b + c is.", [overload([t.list(t.optional(num))], num, ([l], site) => {
740
- const items = list(l);
741
- if (isValidDuration(firstPresent(items))) return sumDurations(items, site);
742
- let total = 0;
743
- for (const n of numbersOf(items, "sum", site)) total += n;
744
- return finite(total, site);
745
- }), overload([t.list(t.optional(dur))], dur, ([l], site) => sumDurations(list(l), site))]),
746
- define("avg", "The mean of the numbers or durations in a list (nulls are skipped, summed as sum does); null for an empty list.", [overload([t.list(t.optional(num))], t.optional(num), ([l], site) => {
747
- const items = list(l);
748
- if (isValidDuration(firstPresent(items))) return averageDuration(items, site);
749
- const values = numbersOf(items, "avg", site);
750
- if (values.length === 0) return null;
751
- let total = 0;
752
- for (const n of values) total += n;
753
- return finite(total / values.length, site);
754
- }), overload([t.list(t.optional(dur))], t.optional(dur), ([l], site) => averageDuration(list(l), site))])
755
- ];
756
- function hof(name, description, result, run, runAsync, { lambda = predicate, extraParams = [], ordered = [] } = {}) {
757
- return define(name, description, [overload([
681
+ const round = /* @__PURE__ */ define("round", [/* @__PURE__ */ overload([num, num], num, ([n, d], site) => roundTo(n, d === void 0 || d === null ? 0 : d, site), { required: 1 })]);
682
+ const floor = /* @__PURE__ */ math("floor", Math.floor);
683
+ const ceil = /* @__PURE__ */ math("ceil", Math.ceil);
684
+ const trunc = /* @__PURE__ */ math("trunc", Math.trunc);
685
+ const abs = /* @__PURE__ */ define("abs", [/* @__PURE__ */ overload([num], num, ([n], site) => finite(Math.abs(n), site)), /* @__PURE__ */ overload([dur], dur, ([d]) => new Duration(Math.abs(d.ms)))]);
686
+ const sqrt = /* @__PURE__ */ math("sqrt", Math.sqrt);
687
+ const clamp = /* @__PURE__ */ define("clamp", [/* @__PURE__ */ overload([
688
+ num,
689
+ num,
690
+ num
691
+ ], num, ([n, lo, hi], site) => {
692
+ if (lo > hi) throw site.state.error("INVALID_ARGUMENT", "clamp: min is greater than max", site.span);
693
+ finite(n, site);
694
+ finite(lo, site);
695
+ finite(hi, site);
696
+ return finite(Math.min(Math.max(n, lo), hi), site);
697
+ })]);
698
+ const toFixed = /* @__PURE__ */ define("toFixed", [/* @__PURE__ */ overload([num, num], str, ([n, d], site) => {
699
+ const digits = nonNegativeInteger(d, "Digits", site);
700
+ if (digits > MAX_FIXED_DIGITS) throw site.state.error("INVALID_ARGUMENT", "Digits must be at most 100", site.span);
701
+ site.state.charge(digits >>> 2);
702
+ finite(n, site);
703
+ const value = digits <= MAX_ROUND_DIGITS ? roundTo(n, digits, site) : n;
704
+ if (Math.abs(value) >= FIXED_NOTATION_LIMIT) return `${BigInt(value).toString()}${digits > 0 ? `.${"0".repeat(digits)}` : ""}`;
705
+ return value.toFixed(digits);
706
+ })]);
707
+ const formatNumber = /* @__PURE__ */ define("formatNumber", [/* @__PURE__ */ overload([
708
+ num,
709
+ /* @__PURE__ */ t.optional(num),
710
+ /* @__PURE__ */ t.optional(str)
711
+ ], str, ([n, d, locale], site) => {
712
+ const digits = d === void 0 || d === null ? void 0 : nonNegativeInteger(d, "Decimals", site);
713
+ if (digits !== void 0 && digits > MAX_INTL_DIGITS) throw site.state.error("INVALID_ARGUMENT", `Decimals must be at most ${MAX_INTL_DIGITS}`, site.span);
714
+ const options = digits === void 0 ? { maximumFractionDigits: MAX_INTL_DIGITS } : {
715
+ minimumFractionDigits: digits,
716
+ maximumFractionDigits: digits
717
+ };
718
+ finite(n, site);
719
+ const value = digits === void 0 || digits > MAX_ROUND_DIGITS ? n : roundTo(n, digits, site);
720
+ return numberFormat(typeof locale === "string" ? locale : "en-US", options, site).format(value);
721
+ }, {
722
+ required: 1,
723
+ literals: ([, , locale]) => formatProblem(locale, void 0)
724
+ })]);
725
+ const formatCurrency = /* @__PURE__ */ define("formatCurrency", [/* @__PURE__ */ overload([
726
+ num,
727
+ str,
728
+ /* @__PURE__ */ t.optional(str)
729
+ ], str, ([n, currency, locale], site) => numberFormat(typeof locale === "string" ? locale : "en-US", {
730
+ style: "currency",
731
+ currency
732
+ }, site).format(finite(n, site)), {
733
+ required: 2,
734
+ literals: ([, currency, locale]) => formatProblem(locale, currency)
735
+ })]);
736
+ const min = /* @__PURE__ */ define("min", /* @__PURE__ */ extremes(-1));
737
+ const max = /* @__PURE__ */ define("max", /* @__PURE__ */ extremes(1));
738
+ const sum = /* @__PURE__ */ define("sum", [/* @__PURE__ */ overload([/* @__PURE__ */ t.list(/* @__PURE__ */ t.optional(num))], num, ([l], site) => {
739
+ const items = list(l);
740
+ if (isValidDuration(firstPresent(items))) return sumDurations(items, site);
741
+ let total = 0;
742
+ for (const n of numbersOf(items, "sum", site)) total += n;
743
+ return finite(total, site);
744
+ }), /* @__PURE__ */ overload([/* @__PURE__ */ t.list(/* @__PURE__ */ t.optional(dur))], dur, ([l], site) => sumDurations(list(l), site))]);
745
+ const avg = /* @__PURE__ */ define("avg", [/* @__PURE__ */ overload([/* @__PURE__ */ t.list(/* @__PURE__ */ t.optional(num))], /* @__PURE__ */ t.optional(num), ([l], site) => {
746
+ const items = list(l);
747
+ if (isValidDuration(firstPresent(items))) return averageDuration(items, site);
748
+ const values = numbersOf(items, "avg", site);
749
+ if (values.length === 0) return null;
750
+ let total = 0;
751
+ for (const n of values) total += n;
752
+ return finite(total / values.length, site);
753
+ }), /* @__PURE__ */ overload([/* @__PURE__ */ t.list(/* @__PURE__ */ t.optional(dur))], /* @__PURE__ */ t.optional(dur), ([l], site) => averageDuration(list(l), site))]);
754
+ function hof(name, result, run, runAsync, { lambda = predicate, extraParams = [], ordered = [] } = {}) {
755
+ return define(name, [overload([
758
756
  listT,
759
757
  lambda,
760
758
  ...extraParams
@@ -764,186 +762,180 @@ function hof(name, description, result, run, runAsync, { lambda = predicate, ext
764
762
  ...ordered.length === 0 ? {} : { ordered }
765
763
  })]);
766
764
  }
767
- const LIST_FUNCTIONS = [
768
- hof("map", "Transforms each item.", t.list(U), (items, fn, site) => {
769
- const out = newList(items.length, site);
770
- for (let i = 0; i < items.length; i++) out[i] = fn(items[i], i);
771
- return made(out, site);
772
- }, async (items, fn, site) => {
773
- const out = newList(items.length, site);
774
- for (let i = 0; i < items.length; i++) out[i] = ran(await fn(items[i], i));
775
- return new Out(made(out, site));
776
- }, { lambda: fnType([T, num], U) }),
777
- hof("filter", "Keeps the items for which the lambda is true.", listT, (items, fn, site) => {
778
- const out = [];
779
- for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) push(out, items[i], site);
780
- return made(out, site);
781
- }, async (items, fn, site) => {
782
- const out = [];
783
- for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) push(out, items[i], site);
784
- return new Out(made(out, site));
785
- }),
786
- hof("find", "The first item for which the lambda is true, or null.", optT, (items, fn, site) => {
787
- for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return items[i] ?? null;
788
- return null;
789
- }, async (items, fn, site) => {
790
- for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(items[i] ?? null);
791
- return new Out(null);
792
- }),
793
- hof("findIndex", "The position of the first item for which the lambda is true, or -1.", num, (items, fn, site) => {
794
- for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return i;
795
- return -1;
796
- }, async (items, fn, site) => {
797
- for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(i);
798
- return new Out(-1);
799
- }),
800
- hof("some", "Whether the lambda is true for at least one item.", bool, (items, fn, site) => {
801
- for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return true;
802
- return false;
803
- }, async (items, fn, site) => {
804
- for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(true);
805
- return new Out(false);
806
- }),
807
- hof("every", "Whether the lambda is true for every item.", bool, (items, fn, site) => {
808
- for (let i = 0; i < items.length; i++) if (!truthy(fn(items[i], i), site)) return false;
809
- return true;
810
- }, async (items, fn, site) => {
811
- for (let i = 0; i < items.length; i++) if (!truthy(ran(await fn(items[i], i)), site)) return new Out(false);
812
- return new Out(true);
813
- }),
814
- hof("none", "Whether the lambda is false for every item.", bool, (items, fn, site) => {
815
- for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return false;
816
- return true;
817
- }, async (items, fn, site) => {
818
- for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(false);
819
- return new Out(true);
820
- }),
821
- hof("flatMap", "Transforms each item and flattens list results one level.", t.list(U), (items, fn, site) => {
822
- const out = [];
823
- for (let i = 0; i < items.length; i++) appendFlat(out, fn(items[i], i), site);
824
- return made(out, site);
825
- }, async (items, fn, site) => {
826
- const out = [];
827
- for (let i = 0; i < items.length; i++) appendFlat(out, ran(await fn(items[i], i)), site);
828
- return new Out(made(out, site));
829
- }, { lambda: fnType([T, num], t.union(t.list(U), U)) }),
830
- hof("sortBy", "Sorts by a key; pass \"desc\" to reverse. Nulls sort first (\"asc\") or last (\"desc\").", listT, (items, fn, site, [direction]) => {
831
- const keys = newList(items.length, site);
832
- for (let i = 0; i < items.length; i++) keys[i] = fn(items[i], i);
833
- return sortKeyed(items, keys, direction, site);
834
- }, async (items, fn, site, [direction]) => {
835
- const keys = newList(items.length, site);
836
- for (let i = 0; i < items.length; i++) keys[i] = ran(await fn(items[i], i));
837
- return new Out(sortKeyed(items, keys, direction, site));
838
- }, {
839
- lambda: fnType([T, num], K),
840
- extraParams: [t.enum("asc", "desc")],
841
- ordered: ["K"]
842
- }),
843
- hof("groupBy", "Groups items into a map of lists by a key. Map keys are text, so a key is its text form: 1 and \"1\", or true and \"true\", share a group. A key must be a string, number, or boolean (null is an error). Keys are listed integer-like first, ascending, then in first-seen order.", t.record(listT), (items, fn, site) => {
844
- const out = {};
845
- for (let i = 0; i < items.length; i++) push(bucket(out, groupKey(fn(items[i], i), site)), items[i], site);
846
- return madeGroups(out, site);
847
- }, async (items, fn, site) => {
848
- const out = {};
849
- for (let i = 0; i < items.length; i++) push(bucket(out, groupKey(ran(await fn(items[i], i)), site)), items[i], site);
850
- return new Out(madeGroups(out, site));
851
- }, { lambda: fnType([T, num], t.union(str, num, bool)) }),
852
- define("count", "The number of items, or of items for which the lambda is true.", [overload([listT], num, ([l]) => list(l).length), overload([listT, predicate], num, ([l, f], site) => {
853
- const items = list(l);
854
- const fn = asLambda(f);
855
- let n = 0;
856
- for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) n++;
857
- return n;
858
- }, { runAsync: async ([l, f], site) => {
859
- const items = list(l);
860
- const fn = asLambda(f);
861
- let n = 0;
862
- for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) n++;
863
- return new Out(n);
864
- } })]),
865
- define("reduce", "Folds a list into one value: reduce(list, (acc, item) => ..., initial). Name both parameters; \".\" is not allowed, since the first one is the accumulator.", [overload([
866
- listT,
867
- fnType([U, T], U),
868
- U
869
- ], U, ([l, f, initial]) => {
870
- const items = list(l);
871
- const fn = f;
872
- let acc = initial;
873
- for (let i = 0; i < items.length; i++) acc = fn(acc, items[i], i);
874
- return acc;
875
- }, { runAsync: async ([l, f, initial]) => {
876
- const items = list(l);
877
- const fn = f;
878
- let acc = initial;
879
- for (let i = 0; i < items.length; i++) acc = ran(await fn(acc, items[i], i));
880
- return new Out(acc);
881
- } })]),
882
- define("sort", "Sorts numbers, text, timestamps, or durations; pass \"desc\" to reverse.", [overload([listT, t.enum("asc", "desc")], listT, ([l, d], site) => sortKeyed(list(l), list(l), d, site), {
883
- required: 1,
884
- ordered: ["T"]
885
- })]),
886
- define("reverse", "The items in reverse order.", [overload([listT], listT, ([l], site) => {
887
- const items = list(l);
888
- site.state.charge(items.length);
889
- const out = newList(items.length, site);
890
- for (let i = 0; i < items.length; i++) out[i] = items[items.length - 1 - i] ?? null;
891
- return made(out, site);
892
- })]),
893
- define("unique", "The items without duplicates (by value), in first-seen order.", [overload([listT], listT, ([l], site) => uniqueOf(list(l), site))]),
894
- define("flat", "Flattens nested lists one level.", [overload([t.list(any)], t.list(any), ([l], site) => flatten(list(l), site))]),
895
- define("first", "The first item, or null.", [overload([listT], optT, ([l]) => list(l)[0] ?? null)]),
896
- define("last", "The last item, or null.", [overload([listT], optT, ([l]) => {
897
- const items = list(l);
898
- return items.length === 0 ? null : items[items.length - 1] ?? null;
899
- })]),
900
- define("join", "Joins items into text with a separator (default \",\").", [overload([t.list(t.union(primitiveText, ts, dur)), str], str, ([l, sep], site) => joinText(list(l), sep, site), { required: 1 })]),
901
- define("isEmpty", "Whether a list, text, or map has no items; null is empty.", [overload([t.union(t.list(any), str, t.record(any), t.null())], bool, ([v], site) => {
902
- if (v === null || v === void 0) return true;
903
- if (Array.isArray(v) || typeof v === "string") return v.length === 0;
904
- const map = v;
905
- const keys = Object.keys(map);
906
- site.state.charge(keyListCost(keys.length));
907
- return !keys.some((key) => holdsKey(map, key));
908
- })])
909
- ];
910
- const MAP_FUNCTIONS = [
911
- define("keys", "The keys of a map.", [overload([t.record(any)], t.list(str), ([m], site) => entryList(m, site))]),
912
- define("values", "The values of a map.", [overload([t.record(T)], listT, ([m], site) => {
913
- const map = m;
914
- return made(entryList(map, site).map((key) => map[key] ?? null), site);
915
- })]),
916
- define("entries", "The entries of a map, as a list of { key, value } maps (not [key, value] pairs as in JavaScript), e.g. m.entries().map(.key + \"=\" + .value).", [overload([t.record(T)], t.list(t.object({
917
- key: str,
918
- value: T
919
- })), ([m], site) => {
920
- const map = m;
921
- const keys = entryList(map, site);
922
- site.state.charge(keys.length);
923
- return made(keys.map((key) => made({
924
- key,
925
- value: map[key] ?? null
926
- }, site)), site);
927
- })]),
928
- define("type", "The kind of a value: \"null\", \"boolean\", \"number\", \"string\", \"list\", \"map\", \"timestamp\", \"duration\", or \"opaque\".", [overload([any], str, ([v]) => kindOf(v))])
929
- ];
930
- const optZone = t.optional(str);
931
- /** The position of a built-in's time zone parameter, if it takes one. */
932
- function zoneParameter(def) {
933
- for (const candidate of def.overloads) {
934
- const index = candidate.params.indexOf(optZone);
935
- if (index >= 0) return index;
936
- }
937
- }
765
+ const map = /* @__PURE__ */ hof("map", /* @__PURE__ */ t.list(U), (items, fn, site) => {
766
+ const out = newList(items.length, site);
767
+ for (let i = 0; i < items.length; i++) out[i] = fn(items[i], i);
768
+ return made(out, site);
769
+ }, async (items, fn, site) => {
770
+ const out = newList(items.length, site);
771
+ for (let i = 0; i < items.length; i++) out[i] = ran(await fn(items[i], i));
772
+ return new Out(made(out, site));
773
+ }, { lambda: /* @__PURE__ */ fnType([T, num], U) });
774
+ const filter = /* @__PURE__ */ hof("filter", listT, (items, fn, site) => {
775
+ const out = [];
776
+ for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) push(out, items[i], site);
777
+ return made(out, site);
778
+ }, async (items, fn, site) => {
779
+ const out = [];
780
+ for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) push(out, items[i], site);
781
+ return new Out(made(out, site));
782
+ });
783
+ const find = /* @__PURE__ */ hof("find", optT, (items, fn, site) => {
784
+ for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return items[i] ?? null;
785
+ return null;
786
+ }, async (items, fn, site) => {
787
+ for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(items[i] ?? null);
788
+ return new Out(null);
789
+ });
790
+ const findIndex = /* @__PURE__ */ hof("findIndex", num, (items, fn, site) => {
791
+ for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return i;
792
+ return -1;
793
+ }, async (items, fn, site) => {
794
+ for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(i);
795
+ return new Out(-1);
796
+ });
797
+ const some = /* @__PURE__ */ hof("some", bool, (items, fn, site) => {
798
+ for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return true;
799
+ return false;
800
+ }, async (items, fn, site) => {
801
+ for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(true);
802
+ return new Out(false);
803
+ });
804
+ const every = /* @__PURE__ */ hof("every", bool, (items, fn, site) => {
805
+ for (let i = 0; i < items.length; i++) if (!truthy(fn(items[i], i), site)) return false;
806
+ return true;
807
+ }, async (items, fn, site) => {
808
+ for (let i = 0; i < items.length; i++) if (!truthy(ran(await fn(items[i], i)), site)) return new Out(false);
809
+ return new Out(true);
810
+ });
811
+ const none = /* @__PURE__ */ hof("none", bool, (items, fn, site) => {
812
+ for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) return false;
813
+ return true;
814
+ }, async (items, fn, site) => {
815
+ for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) return new Out(false);
816
+ return new Out(true);
817
+ });
818
+ const flatMap = /* @__PURE__ */ hof("flatMap", /* @__PURE__ */ t.list(U), (items, fn, site) => {
819
+ const out = [];
820
+ for (let i = 0; i < items.length; i++) appendFlat(out, fn(items[i], i), site);
821
+ return made(out, site);
822
+ }, async (items, fn, site) => {
823
+ const out = [];
824
+ for (let i = 0; i < items.length; i++) appendFlat(out, ran(await fn(items[i], i)), site);
825
+ return new Out(made(out, site));
826
+ }, { lambda: /* @__PURE__ */ fnType([T, num], /* @__PURE__ */ t.union(/* @__PURE__ */ t.list(U), U)) });
827
+ const sortBy = /* @__PURE__ */ hof("sortBy", listT, (items, fn, site, [direction]) => {
828
+ const keys = newList(items.length, site);
829
+ for (let i = 0; i < items.length; i++) keys[i] = fn(items[i], i);
830
+ return sortKeyed(items, keys, direction, site);
831
+ }, async (items, fn, site, [direction]) => {
832
+ const keys = newList(items.length, site);
833
+ for (let i = 0; i < items.length; i++) keys[i] = ran(await fn(items[i], i));
834
+ return new Out(sortKeyed(items, keys, direction, site));
835
+ }, {
836
+ lambda: /* @__PURE__ */ fnType([T, num], K),
837
+ extraParams: [/* @__PURE__ */ t.enum("asc", "desc")],
838
+ ordered: ["K"]
839
+ });
840
+ const groupBy = /* @__PURE__ */ hof("groupBy", /* @__PURE__ */ t.record(listT), (items, fn, site) => {
841
+ const out = {};
842
+ for (let i = 0; i < items.length; i++) push(bucket(out, groupKey(fn(items[i], i), site)), items[i], site);
843
+ return madeGroups(out, site);
844
+ }, async (items, fn, site) => {
845
+ const out = {};
846
+ for (let i = 0; i < items.length; i++) push(bucket(out, groupKey(ran(await fn(items[i], i)), site)), items[i], site);
847
+ return new Out(madeGroups(out, site));
848
+ }, { lambda: /* @__PURE__ */ fnType([T, num], /* @__PURE__ */ t.union(str, num, bool)) });
849
+ const count = /* @__PURE__ */ define("count", [/* @__PURE__ */ overload([listT], num, ([l]) => list(l).length), /* @__PURE__ */ overload([listT, predicate], num, ([l, f], site) => {
850
+ const items = list(l);
851
+ const fn = asLambda(f);
852
+ let n = 0;
853
+ for (let i = 0; i < items.length; i++) if (truthy(fn(items[i], i), site)) n++;
854
+ return n;
855
+ }, { runAsync: async ([l, f], site) => {
856
+ const items = list(l);
857
+ const fn = asLambda(f);
858
+ let n = 0;
859
+ for (let i = 0; i < items.length; i++) if (truthy(ran(await fn(items[i], i)), site)) n++;
860
+ return new Out(n);
861
+ } })]);
862
+ const reduce = /* @__PURE__ */ define("reduce", [/* @__PURE__ */ overload([
863
+ listT,
864
+ /* @__PURE__ */ fnType([U, T], U),
865
+ U
866
+ ], U, ([l, f, initial]) => {
867
+ const items = list(l);
868
+ const fn = f;
869
+ let acc = initial;
870
+ for (let i = 0; i < items.length; i++) acc = fn(acc, items[i], i);
871
+ return acc;
872
+ }, { runAsync: async ([l, f, initial]) => {
873
+ const items = list(l);
874
+ const fn = f;
875
+ let acc = initial;
876
+ for (let i = 0; i < items.length; i++) acc = ran(await fn(acc, items[i], i));
877
+ return new Out(acc);
878
+ } })]);
879
+ const sort = /* @__PURE__ */ define("sort", [/* @__PURE__ */ overload([listT, /* @__PURE__ */ t.enum("asc", "desc")], listT, ([l, d], site) => sortKeyed(list(l), list(l), d, site), {
880
+ required: 1,
881
+ ordered: ["T"]
882
+ })]);
883
+ const reverse = /* @__PURE__ */ define("reverse", [/* @__PURE__ */ overload([listT], listT, ([l], site) => {
884
+ const items = list(l);
885
+ site.state.charge(items.length);
886
+ const out = newList(items.length, site);
887
+ for (let i = 0; i < items.length; i++) out[i] = items[items.length - 1 - i] ?? null;
888
+ return made(out, site);
889
+ })]);
890
+ const unique = /* @__PURE__ */ define("unique", [/* @__PURE__ */ overload([listT], listT, ([l], site) => uniqueOf(list(l), site))]);
891
+ const flat = /* @__PURE__ */ define("flat", [/* @__PURE__ */ overload([/* @__PURE__ */ t.list(any)], /* @__PURE__ */ t.list(any), ([l], site) => flatten(list(l), site))]);
892
+ const first = /* @__PURE__ */ define("first", [/* @__PURE__ */ overload([listT], optT, ([l]) => list(l)[0] ?? null)]);
893
+ const last = /* @__PURE__ */ define("last", [/* @__PURE__ */ overload([listT], optT, ([l]) => {
894
+ const items = list(l);
895
+ return items.length === 0 ? null : items[items.length - 1] ?? null;
896
+ })]);
897
+ const join = /* @__PURE__ */ define("join", [/* @__PURE__ */ overload([/* @__PURE__ */ t.list(/* @__PURE__ */ t.union(primitiveText, ts, dur)), str], str, ([l, sep], site) => joinText(list(l), sep, site), { required: 1 })]);
898
+ const isEmpty = /* @__PURE__ */ define("isEmpty", [/* @__PURE__ */ overload([/* @__PURE__ */ t.union(/* @__PURE__ */ t.list(any), str, /* @__PURE__ */ t.record(any), /* @__PURE__ */ t.null())], bool, ([v], site) => {
899
+ if (v === null || v === void 0) return true;
900
+ if (Array.isArray(v) || typeof v === "string") return v.length === 0;
901
+ const record = v;
902
+ const names = Object.keys(record);
903
+ site.state.charge(keyListCost(names.length));
904
+ return !names.some((key) => holdsKey(record, key));
905
+ })]);
906
+ const keys = /* @__PURE__ */ define("keys", [/* @__PURE__ */ overload([/* @__PURE__ */ t.record(any)], /* @__PURE__ */ t.list(str), ([m], site) => entryList(m, site))]);
907
+ const values = /* @__PURE__ */ define("values", [/* @__PURE__ */ overload([/* @__PURE__ */ t.record(T)], listT, ([m], site) => {
908
+ const record = m;
909
+ return made(entryList(record, site).map((key) => record[key] ?? null), site);
910
+ })]);
911
+ const entries = /* @__PURE__ */ define("entries", [/* @__PURE__ */ overload([/* @__PURE__ */ t.record(T)], /* @__PURE__ */ t.list(/* @__PURE__ */ t.object({
912
+ key: str,
913
+ value: T
914
+ })), ([m], site) => {
915
+ const record = m;
916
+ const names = entryList(record, site);
917
+ site.state.charge(names.length);
918
+ return made(names.map((key) => made({
919
+ key,
920
+ value: record[key] ?? null
921
+ }, site)), site);
922
+ })]);
923
+ const type = /* @__PURE__ */ define("type", [/* @__PURE__ */ overload([any], str, ([v]) => kindOf(v))]);
924
+ const optZone = /* @__PURE__ */ t.optional(str);
925
+ /** Where a built-in's time zone parameter is (see FunctionDef.zone). */
926
+ const zoneAt = (position) => ({
927
+ at: position,
928
+ warm: warmZone
929
+ });
938
930
  function zoneArg(value) {
939
931
  return value === void 0 || value === null ? null : value;
940
932
  }
941
- function field(name, description, pick) {
942
- return define(name, description, [overload([ts, optZone], num, ([d, z], site) => pick(wallClock(d, zoneArg(z), site)), { required: 1 })]);
933
+ function field(name, pick) {
934
+ return define(name, [overload([ts, optZone], num, ([d, z], site) => pick(wallClock(d, zoneArg(z), site)), { required: 1 })], zoneAt(1));
943
935
  }
944
936
  /** Midnight at the start of the day, with `reset` fields of the wall clock set too. */
945
- function startOf(name, what, reset) {
946
- return define(name, `${what}, in a time zone (default UTC).`, [overload([ts, optZone], ts, ([d, z], site) => {
937
+ function startOf(name, reset) {
938
+ return define(name, [overload([ts, optZone], ts, ([d, z], site) => {
947
939
  const midnight = {
948
940
  ...wallClock(d, zoneArg(z), site),
949
941
  ...reset,
@@ -953,7 +945,7 @@ function startOf(name, what, reset) {
953
945
  millisecond: 0
954
946
  };
955
947
  return fromWallClock(midnight, zoneArg(z), site);
956
- }, { required: 1 })]);
948
+ }, { required: 1 })], zoneAt(1));
957
949
  }
958
950
  /** Longest duration text duration() reads; longer text is never a valid duration in range. */
959
951
  const MAX_DURATION_TEXT = 64;
@@ -974,87 +966,85 @@ function isoDurationMs(text) {
974
966
  const ms = part(weeks) * MS_PER_WEEK + part(days) * MS_PER_DAY + part(hours) * MS_PER_HOUR + part(minutes) * MS_PER_MINUTE + part(seconds) * MS_PER_SECOND + (fraction === void 0 ? 0 : Number(fraction.padEnd(3, "0")));
975
967
  return sign === "-" ? -ms : ms;
976
968
  }
977
- function durationUnit(name, unitMs, description) {
978
- return define(name, description, [overload([num], dur, ([n], site) => durationOf(n * unitMs, site.state, site.span))]);
969
+ function durationUnit(name, unitMs) {
970
+ return define(name, [overload([num], dur, ([n], site) => durationOf(n * unitMs, site.state, site.span))]);
979
971
  }
980
- function durationIn(name, unitMs, description) {
981
- return define(name, description, [overload([dur], num, ([d]) => d.ms / unitMs)]);
972
+ function durationIn(name, unitMs) {
973
+ return define(name, [overload([dur], num, ([d]) => d.ms / unitMs)]);
982
974
  }
983
- const TIME_FUNCTIONS = [
984
- define("now", "The current time, fixed for one evaluation.", [overload([], ts, (_, site) => site.state.now())]),
985
- define("timestamp", "Parses ISO-8601 text (years 0000-9999, or six digits with a sign such as +012345, as a timestamp renders) or epoch milliseconds (a fraction is dropped toward zero, as Date does) into a timestamp.", [
986
- overload([str], ts, ([s], site) => {
987
- site.state.charge(PARSE_COST);
988
- return parseTimestamp(s, site);
989
- }),
990
- overload([num], ts, ([n], site) => checked(n, site)),
991
- overload([ts], ts, ([d], site) => {
992
- timeOf(d, site.state, site.span);
993
- return d;
994
- })
995
- ]),
996
- define("duration", "Parses ISO-8601 duration text in weeks, days, hours, minutes, and seconds (e.g. \"PT1H30M\", \"-P2DT0.5S\"), the text a duration renders as.", [overload([str], dur, ([s], site) => {
975
+ const now = /* @__PURE__ */ define("now", [/* @__PURE__ */ overload([], ts, (_, site) => site.state.now())]);
976
+ const timestamp = /* @__PURE__ */ define("timestamp", [
977
+ /* @__PURE__ */ overload([str], ts, ([s], site) => {
997
978
  site.state.charge(PARSE_COST);
998
- const ms = isoDurationMs(s);
999
- if (typeof ms === "string") throw site.state.error("INVALID_ARGUMENT", ms, site.span);
1000
- return durationOf(ms, site.state, site.span);
1001
- }, { literals: ([text]) => {
1002
- if (typeof text !== "string") return void 0;
1003
- const ms = isoDurationMs(text);
1004
- return typeof ms === "string" ? ms : void 0;
1005
- } }), overload([dur], dur, ([d]) => d)]),
1006
- durationUnit("weeks", MS_PER_WEEK, "A duration of n weeks."),
1007
- durationUnit("days", MS_PER_DAY, "A duration of n days (24 hours each)."),
1008
- durationUnit("hours", MS_PER_HOUR, "A duration of n hours."),
1009
- durationUnit("minutes", MS_PER_MINUTE, "A duration of n minutes."),
1010
- durationUnit("seconds", MS_PER_SECOND, "A duration of n seconds."),
1011
- durationUnit("milliseconds", 1, "A duration of n milliseconds. Durations are whole milliseconds: a fraction rounds to the nearest one, halves away from zero."),
1012
- durationIn("inDays", MS_PER_DAY, "A duration as a (fractional) number of days."),
1013
- durationIn("inHours", MS_PER_HOUR, "A duration as a number of hours."),
1014
- durationIn("inMinutes", MS_PER_MINUTE, "A duration as a number of minutes."),
1015
- durationIn("inSeconds", MS_PER_SECOND, "A duration as a number of seconds."),
1016
- durationIn("inMilliseconds", 1, "A duration as a number of milliseconds."),
1017
- field("year", "The calendar year, in a time zone (default UTC).", (c) => c.year),
1018
- field("month", "The month 1-12, in a time zone (default UTC).", (c) => c.month),
1019
- field("day", "The day of the month, in a time zone (default UTC).", (c) => c.day),
1020
- field("hour", "The hour 0-23, in a time zone (default UTC).", (c) => c.hour),
1021
- field("minute", "The minute, in a time zone (default UTC).", (c) => c.minute),
1022
- field("second", "The second, in a time zone (default UTC).", (c) => c.second),
1023
- field("dayOfWeek", "The ISO weekday (Monday 1 to Sunday 7), in a time zone (default UTC).", isoWeekday),
1024
- startOf("startOfDay", "Midnight at the start of the day", {}),
1025
- startOf("startOfMonth", "Midnight on the first of the month", { day: 1 }),
1026
- startOf("startOfYear", "Midnight on January 1", {
1027
- month: 1,
1028
- day: 1
979
+ return parseTimestamp(s, site);
1029
980
  }),
1030
- define("addDays", "Adds calendar days (keeps the wall-clock time across DST), in a time zone.", [overload([
1031
- ts,
1032
- num,
1033
- optZone
1034
- ], ts, ([d, n, z], site) => addDays(d, n, zoneArg(z), site), { required: 2 })]),
1035
- define("addMonths", "Adds calendar months, clamping the day to the month length.", [overload([
1036
- ts,
1037
- num,
1038
- optZone
1039
- ], ts, ([d, n, z], site) => addMonths(d, n, zoneArg(z), site), { required: 2 })]),
1040
- define("addYears", "Adds calendar years (Feb 29 becomes Feb 28).", [overload([
1041
- ts,
1042
- num,
1043
- optZone
1044
- ], ts, ([d, n, z], site) => addMonths(d, integer(n, "Years", site) * MONTHS_PER_YEAR, zoneArg(z), site), { required: 2 })]),
1045
- define("formatDate", "Formats a timestamp in a time zone (default UTC). Tokens: yyyy yy MMMM MMM MM M dd d EEEE EEE HH H hh h a mm m ss s SSS; quote literal text ('at'), and write '' for a quote ('it''s').", [overload([
1046
- ts,
1047
- str,
1048
- optZone
1049
- ], str, ([d, p, z], site) => {
1050
- const text = formatTimestamp(d, p, zoneArg(z), site);
1051
- site.state.stringLimit(text.length, site.span);
1052
- return text;
1053
- }, {
1054
- required: 2,
1055
- literals: ([, pattern]) => typeof pattern === "string" ? checkDatePattern(pattern) : void 0
1056
- })])
1057
- ];
981
+ /* @__PURE__ */ overload([num], ts, ([n], site) => checked(n, site)),
982
+ /* @__PURE__ */ overload([ts], ts, ([d], site) => {
983
+ timeOf(d, site.state, site.span);
984
+ return d;
985
+ })
986
+ ]);
987
+ const duration = /* @__PURE__ */ define("duration", [/* @__PURE__ */ overload([str], dur, ([s], site) => {
988
+ site.state.charge(PARSE_COST);
989
+ const ms = isoDurationMs(s);
990
+ if (typeof ms === "string") throw site.state.error("INVALID_ARGUMENT", ms, site.span);
991
+ return durationOf(ms, site.state, site.span);
992
+ }, { literals: ([text]) => {
993
+ if (typeof text !== "string") return void 0;
994
+ const ms = isoDurationMs(text);
995
+ return typeof ms === "string" ? ms : void 0;
996
+ } }), /* @__PURE__ */ overload([dur], dur, ([d]) => d)]);
997
+ const weeks = /* @__PURE__ */ durationUnit("weeks", MS_PER_WEEK);
998
+ const days = /* @__PURE__ */ durationUnit("days", MS_PER_DAY);
999
+ const hours = /* @__PURE__ */ durationUnit("hours", MS_PER_HOUR);
1000
+ const minutes = /* @__PURE__ */ durationUnit("minutes", MS_PER_MINUTE);
1001
+ const seconds = /* @__PURE__ */ durationUnit("seconds", MS_PER_SECOND);
1002
+ const milliseconds = /* @__PURE__ */ durationUnit("milliseconds", 1);
1003
+ const inDays = /* @__PURE__ */ durationIn("inDays", MS_PER_DAY);
1004
+ const inHours = /* @__PURE__ */ durationIn("inHours", MS_PER_HOUR);
1005
+ const inMinutes = /* @__PURE__ */ durationIn("inMinutes", MS_PER_MINUTE);
1006
+ const inSeconds = /* @__PURE__ */ durationIn("inSeconds", MS_PER_SECOND);
1007
+ const inMilliseconds = /* @__PURE__ */ durationIn("inMilliseconds", 1);
1008
+ const year = /* @__PURE__ */ field("year", (c) => c.year);
1009
+ const month = /* @__PURE__ */ field("month", (c) => c.month);
1010
+ const day = /* @__PURE__ */ field("day", (c) => c.day);
1011
+ const hour = /* @__PURE__ */ field("hour", (c) => c.hour);
1012
+ const minute = /* @__PURE__ */ field("minute", (c) => c.minute);
1013
+ const second = /* @__PURE__ */ field("second", (c) => c.second);
1014
+ const dayOfWeek = /* @__PURE__ */ field("dayOfWeek", isoWeekday);
1015
+ const startOfDay = /* @__PURE__ */ startOf("startOfDay", {});
1016
+ const startOfMonth = /* @__PURE__ */ startOf("startOfMonth", { day: 1 });
1017
+ const startOfYear = /* @__PURE__ */ startOf("startOfYear", {
1018
+ month: 1,
1019
+ day: 1
1020
+ });
1021
+ const addDays = /* @__PURE__ */ define("addDays", [/* @__PURE__ */ overload([
1022
+ ts,
1023
+ num,
1024
+ optZone
1025
+ ], ts, ([d, n, z], site) => addDays$1(d, n, zoneArg(z), site), { required: 2 })], /* @__PURE__ */ zoneAt(2));
1026
+ const addMonths = /* @__PURE__ */ define("addMonths", [/* @__PURE__ */ overload([
1027
+ ts,
1028
+ num,
1029
+ optZone
1030
+ ], ts, ([d, n, z], site) => addMonths$1(d, n, zoneArg(z), site), { required: 2 })], /* @__PURE__ */ zoneAt(2));
1031
+ const addYears = /* @__PURE__ */ define("addYears", [/* @__PURE__ */ overload([
1032
+ ts,
1033
+ num,
1034
+ optZone
1035
+ ], ts, ([d, n, z], site) => addMonths$1(d, integer(n, "Years", site) * MONTHS_PER_YEAR, zoneArg(z), site), { required: 2 })], /* @__PURE__ */ zoneAt(2));
1036
+ const formatDate = /* @__PURE__ */ define("formatDate", [/* @__PURE__ */ overload([
1037
+ ts,
1038
+ str,
1039
+ optZone
1040
+ ], str, ([d, p, z], site) => {
1041
+ const text = formatTimestamp(d, p, zoneArg(z), site);
1042
+ site.state.stringLimit(text.length, site.span);
1043
+ return text;
1044
+ }, {
1045
+ required: 2,
1046
+ literals: ([, pattern]) => typeof pattern === "string" ? checkDatePattern(pattern) : void 0
1047
+ })], /* @__PURE__ */ zoneAt(2));
1058
1048
  /** Result types that depend on argument types beyond simple type variables. */
1059
1049
  const RESULT_REFINERS = {
1060
1050
  values: (args) => t.list(valueTypeOf(args[0])),
@@ -1070,14 +1060,101 @@ const RESULT_REFINERS = {
1070
1060
  return t.list(unionOf(members.map((member) => member.kind === "list" ? member.element : member)));
1071
1061
  }
1072
1062
  };
1073
- const BUILTINS = new Map([
1074
- ...STRING_FUNCTIONS,
1075
- ...NUMBER_FUNCTIONS,
1076
- ...LIST_FUNCTIONS,
1077
- ...MAP_FUNCTIONS,
1078
- ...TIME_FUNCTIONS
1079
- ].map((def) => [def.name, def]));
1063
+ /**
1064
+ * Every built-in by name, in the order descriptions.ts lists them. Each
1065
+ * built-in is also its own export, so a bundle that never reads this map
1066
+ * keeps only the built-ins it imports.
1067
+ */
1068
+ const BUILTINS = /* @__PURE__ */ (() => new Map([
1069
+ toUpperCase,
1070
+ toLowerCase,
1071
+ trim,
1072
+ trimStart,
1073
+ trimEnd,
1074
+ startsWith,
1075
+ endsWith,
1076
+ includes,
1077
+ indexOf,
1078
+ lastIndexOf,
1079
+ slice,
1080
+ split,
1081
+ replace,
1082
+ replaceAll,
1083
+ padStart,
1084
+ padEnd,
1085
+ repeat,
1086
+ at,
1087
+ matches,
1088
+ toString,
1089
+ toNumber,
1090
+ round,
1091
+ floor,
1092
+ ceil,
1093
+ trunc,
1094
+ abs,
1095
+ sqrt,
1096
+ clamp,
1097
+ toFixed,
1098
+ formatNumber,
1099
+ formatCurrency,
1100
+ min,
1101
+ max,
1102
+ sum,
1103
+ avg,
1104
+ map,
1105
+ filter,
1106
+ find,
1107
+ findIndex,
1108
+ some,
1109
+ every,
1110
+ none,
1111
+ flatMap,
1112
+ sortBy,
1113
+ groupBy,
1114
+ count,
1115
+ reduce,
1116
+ sort,
1117
+ reverse,
1118
+ unique,
1119
+ flat,
1120
+ first,
1121
+ last,
1122
+ join,
1123
+ isEmpty,
1124
+ keys,
1125
+ values,
1126
+ entries,
1127
+ type,
1128
+ now,
1129
+ timestamp,
1130
+ duration,
1131
+ weeks,
1132
+ days,
1133
+ hours,
1134
+ minutes,
1135
+ seconds,
1136
+ milliseconds,
1137
+ inDays,
1138
+ inHours,
1139
+ inMinutes,
1140
+ inSeconds,
1141
+ inMilliseconds,
1142
+ year,
1143
+ month,
1144
+ day,
1145
+ hour,
1146
+ minute,
1147
+ second,
1148
+ dayOfWeek,
1149
+ startOfDay,
1150
+ startOfMonth,
1151
+ startOfYear,
1152
+ addDays,
1153
+ addMonths,
1154
+ addYears,
1155
+ formatDate
1156
+ ].map((def) => [def.name, def])))();
1080
1157
  //#endregion
1081
- export { BUILTINS, RESULT_REFINERS, zoneParameter };
1158
+ export { BUILTINS, RESULT_REFINERS, abs, addDays, addMonths, addYears, at, avg, ceil, clamp, count, day, dayOfWeek, days, duration, endsWith, entries, every, filter, find, findIndex, first, flat, flatMap, floor, formatCurrency, formatDate, formatNumber, groupBy, hour, hours, inDays, inHours, inMilliseconds, inMinutes, inSeconds, includes, indexOf, isEmpty, join, keys, last, lastIndexOf, map, matches, max, milliseconds, min, minute, minutes, month, none, now, padEnd, padStart, reduce, repeat, replace, replaceAll, reverse, round, second, seconds, slice, some, sort, sortBy, split, sqrt, startOfDay, startOfMonth, startOfYear, startsWith, sum, timestamp, toFixed, toLowerCase, toNumber, toString, toUpperCase, trim, trimEnd, trimStart, trunc, type, unique, values, weeks, year };
1082
1159
 
1083
1160
  //# sourceMappingURL=builtins.mjs.map