@jalvin/runtime 2.0.19 → 2.0.20

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/utils.js DELETED
@@ -1,1180 +0,0 @@
1
- "use strict";
2
- // ─────────────────────────────────────────────────────────────────────────────
3
- // Runtime utility helpers — used by codegen emitted code
4
- // ─────────────────────────────────────────────────────────────────────────────
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Default = exports.Random = exports.JalvinRegex = exports.Regex = exports.RegexResult = exports.Result = exports.StringBuilder = exports.IntRange = exports.E = exports.PI = exports.truncate = exports.hypot = exports.sign = exports.atan2 = exports.atan = exports.acos = exports.asin = exports.tan = exports.cos = exports.sin = exports.log10 = exports.log2 = exports.ln = exports.exp = exports.pow = exports.sqrt = exports.round = exports.floor = exports.ceil = exports.abs = exports.Triple = exports.Pair = exports.Long = exports.Int = exports.NoSuchElementException = exports.IndexOutOfBoundsException = exports.UnsupportedOperationException = exports.IllegalStateException = exports.IllegalArgumentException = exports.Delegates = exports.ObservableDelegate = exports.LazyDelegate = exports.NullPointerException = void 0;
7
- exports.notNull = notNull;
8
- exports.safeCast = safeCast;
9
- exports.range = range;
10
- exports.delegate = delegate;
11
- exports.lazy = lazy;
12
- exports.println = println;
13
- exports.print = print;
14
- exports.listOf = listOf;
15
- exports.mutableListOf = mutableListOf;
16
- exports.setOf = setOf;
17
- exports.mutableSetOf = mutableSetOf;
18
- exports.mapOf = mapOf;
19
- exports.mutableMapOf = mutableMapOf;
20
- exports.pairOf = pairOf;
21
- exports.tripleOf = tripleOf;
22
- exports.checkNotNull = checkNotNull;
23
- exports.requireNotNull = requireNotNull;
24
- exports.requireCondition = requireCondition;
25
- exports.check = check;
26
- exports.error = error;
27
- exports.let_ = let_;
28
- exports.run_ = run_;
29
- exports.apply = apply;
30
- exports.also = also;
31
- exports.with_ = with_;
32
- exports.takeIf = takeIf;
33
- exports.takeUnless = takeUnless;
34
- exports.map = map;
35
- exports.filter = filter;
36
- exports.filterNotNull = filterNotNull;
37
- exports.forEach = forEach;
38
- exports.fold = fold;
39
- exports.reduce = reduce;
40
- exports.sumOf = sumOf;
41
- exports.any = any;
42
- exports.all = all;
43
- exports.none = none;
44
- exports.count = count;
45
- exports.first = first;
46
- exports.firstOrNull = firstOrNull;
47
- exports.last = last;
48
- exports.lastOrNull = lastOrNull;
49
- exports.find = find;
50
- exports.findLast = findLast;
51
- exports.flatMap = flatMap;
52
- exports.flatten = flatten;
53
- exports.groupBy = groupBy;
54
- exports.associate = associate;
55
- exports.zip = zip;
56
- exports.distinct = distinct;
57
- exports.distinctBy = distinctBy;
58
- exports.sortedBy = sortedBy;
59
- exports.sortedByDescending = sortedByDescending;
60
- exports.reversed = reversed;
61
- exports.chunked = chunked;
62
- exports.windowed = windowed;
63
- exports.partition = partition;
64
- exports.withIndex = withIndex;
65
- exports.minOf = minOf;
66
- exports.maxOf = maxOf;
67
- exports.minOrNull = minOrNull;
68
- exports.maxOrNull = maxOrNull;
69
- exports.joinToString = joinToString;
70
- exports.take = take;
71
- exports.takeWhile = takeWhile;
72
- exports.drop = drop;
73
- exports.dropWhile = dropWhile;
74
- exports.coerceAtLeast = coerceAtLeast;
75
- exports.coerceAtMost = coerceAtMost;
76
- exports.coerceIn = coerceIn;
77
- exports.trimIndent = trimIndent;
78
- exports.repeat_ = repeat_;
79
- exports.isBlank = isBlank;
80
- exports.isNotBlank = isNotBlank;
81
- exports.isNullOrBlank = isNullOrBlank;
82
- exports.toIntOrNull = toIntOrNull;
83
- exports.toDoubleOrNull = toDoubleOrNull;
84
- exports.toBooleanOrNull = toBooleanOrNull;
85
- exports.padStart = padStart;
86
- exports.padEnd = padEnd;
87
- exports.clamp = clamp;
88
- exports.truncDiv = truncDiv;
89
- exports.capitalize = capitalize;
90
- exports.decapitalize = decapitalize;
91
- exports.substringBefore = substringBefore;
92
- exports.substringAfter = substringAfter;
93
- exports.substringBeforeLast = substringBeforeLast;
94
- exports.substringAfterLast = substringAfterLast;
95
- exports.removePrefix = removePrefix;
96
- exports.removeSuffix = removeSuffix;
97
- exports.lines = lines;
98
- exports.lineSequence = lineSequence;
99
- exports.ifEmpty = ifEmpty;
100
- exports.ifBlank = ifBlank;
101
- exports.toInt = toInt;
102
- exports.toLong = toLong;
103
- exports.toFloat = toFloat;
104
- exports.toDouble = toDouble;
105
- exports.toChar = toChar;
106
- exports.charCodeOf = charCodeOf;
107
- exports.toString = toString;
108
- exports.downTo = downTo;
109
- exports.step = step;
110
- exports.buildString = buildString;
111
- exports.buildList = buildList;
112
- exports.buildSet = buildSet;
113
- exports.buildMap = buildMap;
114
- exports.runCatching = runCatching;
115
- exports.runCatchingAsync = runCatchingAsync;
116
- exports.measureTimeMillis = measureTimeMillis;
117
- exports.measureTimeMillisAsync = measureTimeMillisAsync;
118
- exports.measureTimedValue = measureTimedValue;
119
- exports.randomUUID = randomUUID;
120
- exports.jalvinEquals = jalvinEquals;
121
- /**
122
- * `notNull(value)` — emitted for Jalvin's `!!` operator.
123
- * Throws if value is null/undefined, otherwise returns the value.
124
- */
125
- function notNull(value) {
126
- if (value === null || value === undefined) {
127
- throw new NullPointerException("!! operator invoked on null or undefined value");
128
- }
129
- return value;
130
- }
131
- class NullPointerException extends Error {
132
- constructor(message = "Value was null") {
133
- super(message);
134
- this.name = "NullPointerException";
135
- }
136
- }
137
- exports.NullPointerException = NullPointerException;
138
- /**
139
- * `safeCast<T>(value, Type)` — emitted for Jalvin's `as?` operator.
140
- * Returns the value if it's an instanceof Type, otherwise returns null.
141
- */
142
- function safeCast(value,
143
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
- Type) {
145
- return value instanceof Type ? value : null;
146
- }
147
- /**
148
- * `range(from, to, inclusive)` — emitted for `..` and `..<` range operators.
149
- * Returns an iterable of numbers.
150
- */
151
- function* range(from, to, inclusive) {
152
- for (let i = from; inclusive ? i <= to : i < to; i++) {
153
- yield i;
154
- }
155
- }
156
- function delegate(impl, _name, _receiver) {
157
- return impl;
158
- }
159
- // ─────────────────────────────────────────────────────────────────────────────
160
- // Built-in Delegates
161
- // ─────────────────────────────────────────────────────────────────────────────
162
- class LazyDelegate {
163
- _init;
164
- _value;
165
- _initialized = false;
166
- constructor(_init) {
167
- this._init = _init;
168
- }
169
- getValue() {
170
- if (!this._initialized) {
171
- this._value = this._init();
172
- this._initialized = true;
173
- }
174
- return this._value;
175
- }
176
- setValue(_v) {
177
- throw new Error("Cannot set a lazy property");
178
- }
179
- }
180
- exports.LazyDelegate = LazyDelegate;
181
- function lazy(init) {
182
- return new LazyDelegate(init);
183
- }
184
- class ObservableDelegate {
185
- _value;
186
- _onChange;
187
- _name;
188
- constructor(_value, _onChange, _name = "") {
189
- this._value = _value;
190
- this._onChange = _onChange;
191
- this._name = _name;
192
- }
193
- getValue() { return this._value; }
194
- setValue(value) {
195
- const old = this._value;
196
- this._value = value;
197
- this._onChange(this._name, old, value);
198
- }
199
- }
200
- exports.ObservableDelegate = ObservableDelegate;
201
- exports.Delegates = {
202
- observable(initial, onChange) {
203
- return new ObservableDelegate(initial, onChange);
204
- },
205
- notNull() {
206
- let _v;
207
- return {
208
- getValue() {
209
- if (_v === undefined)
210
- throw new NullPointerException("Delegated property was not initialised");
211
- return _v;
212
- },
213
- setValue(v) { _v = v; },
214
- };
215
- },
216
- };
217
- // ─────────────────────────────────────────────────────────────────────────────
218
- // Standard library shims
219
- // ─────────────────────────────────────────────────────────────────────────────
220
- function println(...args) {
221
- console.log(...args);
222
- }
223
- function print(...args) {
224
- process.stdout?.write(args.map(String).join(""));
225
- }
226
- function listOf(...items) {
227
- return Object.freeze([...items]);
228
- }
229
- function mutableListOf(...items) {
230
- return [...items];
231
- }
232
- function setOf(...items) {
233
- return Object.freeze(new Set(items));
234
- }
235
- function mutableSetOf(...items) {
236
- return new Set(items);
237
- }
238
- function mapOf(...entries) {
239
- return Object.freeze(new Map(entries));
240
- }
241
- function mutableMapOf(...entries) {
242
- return new Map(entries);
243
- }
244
- function pairOf(first, second) {
245
- return [first, second];
246
- }
247
- function tripleOf(first, second, third) {
248
- return [first, second, third];
249
- }
250
- function checkNotNull(value, message = "Value must not be null") {
251
- return notNull(value) ?? (() => { throw new NullPointerException(message); })();
252
- }
253
- function requireNotNull(value, message = "Required value was null") {
254
- return notNull(value);
255
- }
256
- function requireCondition(condition, message = "Requirement failed") {
257
- if (!condition) {
258
- throw new IllegalArgumentException(typeof message === "function" ? message() : message);
259
- }
260
- }
261
- function check(condition, message = "Check failed") {
262
- if (!condition) {
263
- throw new IllegalStateException(typeof message === "function" ? message() : message);
264
- }
265
- }
266
- function error(message) {
267
- throw new IllegalStateException(message);
268
- }
269
- class IllegalArgumentException extends Error {
270
- constructor(message) { super(message); this.name = "IllegalArgumentException"; }
271
- }
272
- exports.IllegalArgumentException = IllegalArgumentException;
273
- class IllegalStateException extends Error {
274
- constructor(message) { super(message); this.name = "IllegalStateException"; }
275
- }
276
- exports.IllegalStateException = IllegalStateException;
277
- class UnsupportedOperationException extends Error {
278
- constructor(message = "Operation is not supported") { super(message); this.name = "UnsupportedOperationException"; }
279
- }
280
- exports.UnsupportedOperationException = UnsupportedOperationException;
281
- class IndexOutOfBoundsException extends Error {
282
- constructor(message = "Index out of bounds") { super(message); this.name = "IndexOutOfBoundsException"; }
283
- }
284
- exports.IndexOutOfBoundsException = IndexOutOfBoundsException;
285
- class NoSuchElementException extends Error {
286
- constructor(message = "No such element") { super(message); this.name = "NoSuchElementException"; }
287
- }
288
- exports.NoSuchElementException = NoSuchElementException;
289
- // ─────────────────────────────────────────────────────────────────────────────
290
- // Scope functions
291
- // ─────────────────────────────────────────────────────────────────────────────
292
- /**
293
- * `let` — calls `block` with `this` as argument, returns the block result.
294
- * Usage: `value.let { v -> transform(v) }`
295
- */
296
- function let_(value, block) {
297
- return block(value);
298
- }
299
- /**
300
- * `run` — calls `block` with `this` as receiver, returns the block result.
301
- * Usage: `obj.run { doSomething() }`
302
- */
303
- function run_(value, block) {
304
- return block.call(value);
305
- }
306
- /**
307
- * `apply` — calls `block` with `this` as receiver, returns the original value.
308
- * Usage: `obj.apply { configure() }`
309
- */
310
- function apply(value, block) {
311
- block.call(value);
312
- return value;
313
- }
314
- /**
315
- * `also` — calls `block` with `this` as argument, returns the original value.
316
- * Usage: `value.also { v -> sideEffect(v) }`
317
- */
318
- function also(value, block) {
319
- block(value);
320
- return value;
321
- }
322
- /**
323
- * `with` — calls `block` with `receiver` as receiver, returns block result.
324
- * Usage: `with(obj) { doSomething() }`
325
- */
326
- function with_(receiver, block) {
327
- return block.call(receiver);
328
- }
329
- /**
330
- * `takeIf` — returns `this` if `predicate` is true, otherwise null.
331
- */
332
- function takeIf(value, predicate) {
333
- return predicate(value) ? value : null;
334
- }
335
- /**
336
- * `takeUnless` — returns `this` if `predicate` is false, otherwise null.
337
- */
338
- function takeUnless(value, predicate) {
339
- return predicate(value) ? null : value;
340
- }
341
- // ─────────────────────────────────────────────────────────────────────────────
342
- // Standard library collection extensions
343
- // ─────────────────────────────────────────────────────────────────────────────
344
- function map(iterable, transform) {
345
- const result = [];
346
- for (const item of iterable)
347
- result.push(transform(item));
348
- return result;
349
- }
350
- function filter(iterable, predicate) {
351
- const result = [];
352
- for (const item of iterable)
353
- if (predicate(item))
354
- result.push(item);
355
- return result;
356
- }
357
- function filterNotNull(iterable) {
358
- const result = [];
359
- for (const item of iterable)
360
- if (item != null)
361
- result.push(item);
362
- return result;
363
- }
364
- function forEach(iterable, action) {
365
- for (const item of iterable)
366
- action(item);
367
- }
368
- function fold(iterable, initial, operation) {
369
- let acc = initial;
370
- for (const item of iterable)
371
- acc = operation(acc, item);
372
- return acc;
373
- }
374
- function reduce(iterable, operation) {
375
- let first = true;
376
- let acc;
377
- for (const item of iterable) {
378
- if (first) {
379
- acc = item;
380
- first = false;
381
- }
382
- else
383
- acc = operation(acc, item);
384
- }
385
- if (first)
386
- throw new NoSuchElementException("Collection is empty");
387
- return acc;
388
- }
389
- function sumOf(iterable, selector) {
390
- let sum = 0;
391
- for (const item of iterable)
392
- sum += selector(item);
393
- return sum;
394
- }
395
- function any(iterable, predicate) {
396
- for (const item of iterable)
397
- if (predicate(item))
398
- return true;
399
- return false;
400
- }
401
- function all(iterable, predicate) {
402
- for (const item of iterable)
403
- if (!predicate(item))
404
- return false;
405
- return true;
406
- }
407
- function none(iterable, predicate) {
408
- for (const item of iterable)
409
- if (predicate(item))
410
- return false;
411
- return true;
412
- }
413
- function count(iterable, predicate) {
414
- let n = 0;
415
- for (const item of iterable)
416
- if (!predicate || predicate(item))
417
- n++;
418
- return n;
419
- }
420
- function first(iterable, predicate) {
421
- for (const item of iterable)
422
- if (!predicate || predicate(item))
423
- return item;
424
- throw new NoSuchElementException("No element matching predicate");
425
- }
426
- function firstOrNull(iterable, predicate) {
427
- for (const item of iterable)
428
- if (!predicate || predicate(item))
429
- return item;
430
- return null;
431
- }
432
- function last(arr, predicate) {
433
- for (let i = arr.length - 1; i >= 0; i--) {
434
- if (!predicate || predicate(arr[i]))
435
- return arr[i];
436
- }
437
- throw new NoSuchElementException("No element matching predicate");
438
- }
439
- function lastOrNull(arr, predicate) {
440
- for (let i = arr.length - 1; i >= 0; i--) {
441
- if (!predicate || predicate(arr[i]))
442
- return arr[i];
443
- }
444
- return null;
445
- }
446
- function find(iterable, predicate) {
447
- return firstOrNull(iterable, predicate);
448
- }
449
- function findLast(arr, predicate) {
450
- return lastOrNull(arr, predicate);
451
- }
452
- function flatMap(iterable, transform) {
453
- const result = [];
454
- for (const item of iterable)
455
- for (const inner of transform(item))
456
- result.push(inner);
457
- return result;
458
- }
459
- function flatten(iterable) {
460
- const result = [];
461
- for (const inner of iterable)
462
- for (const item of inner)
463
- result.push(item);
464
- return result;
465
- }
466
- function groupBy(iterable, keySelector) {
467
- const map = new Map();
468
- for (const item of iterable) {
469
- const key = keySelector(item);
470
- const group = map.get(key);
471
- if (group)
472
- group.push(item);
473
- else
474
- map.set(key, [item]);
475
- }
476
- return map;
477
- }
478
- function associate(iterable, transform) {
479
- const map = new Map();
480
- for (const item of iterable) {
481
- const [k, v] = transform(item);
482
- map.set(k, v);
483
- }
484
- return map;
485
- }
486
- function zip(a, b) {
487
- const len = Math.min(a.length, b.length);
488
- const result = [];
489
- for (let i = 0; i < len; i++)
490
- result.push([a[i], b[i]]);
491
- return result;
492
- }
493
- function distinct(iterable) {
494
- return [...new Set(iterable)];
495
- }
496
- function distinctBy(iterable, selector) {
497
- const seen = new Set();
498
- const result = [];
499
- for (const item of iterable) {
500
- const key = selector(item);
501
- if (!seen.has(key)) {
502
- seen.add(key);
503
- result.push(item);
504
- }
505
- }
506
- return result;
507
- }
508
- function sortedBy(arr, selector) {
509
- return [...arr].sort((a, b) => {
510
- const ka = selector(a), kb = selector(b);
511
- return ka < kb ? -1 : ka > kb ? 1 : 0;
512
- });
513
- }
514
- function sortedByDescending(arr, selector) {
515
- return [...arr].sort((a, b) => {
516
- const ka = selector(a), kb = selector(b);
517
- return ka > kb ? -1 : ka < kb ? 1 : 0;
518
- });
519
- }
520
- function reversed(arr) {
521
- return [...arr].reverse();
522
- }
523
- function chunked(arr, size) {
524
- const result = [];
525
- for (let i = 0; i < arr.length; i += size)
526
- result.push(arr.slice(i, i + size));
527
- return result;
528
- }
529
- function windowed(arr, size, step = 1) {
530
- const result = [];
531
- for (let i = 0; i <= arr.length - size; i += step)
532
- result.push(arr.slice(i, i + size));
533
- return result;
534
- }
535
- function partition(iterable, predicate) {
536
- const yes = [], no = [];
537
- for (const item of iterable)
538
- (predicate(item) ? yes : no).push(item);
539
- return [yes, no];
540
- }
541
- function withIndex(iterable) {
542
- const result = [];
543
- let i = 0;
544
- for (const value of iterable)
545
- result.push({ index: i++, value });
546
- return result;
547
- }
548
- function minOf(iterable, selector) {
549
- let min = Infinity;
550
- for (const item of iterable) {
551
- const v = selector(item);
552
- if (v < min)
553
- min = v;
554
- }
555
- return min;
556
- }
557
- function maxOf(iterable, selector) {
558
- let max = -Infinity;
559
- for (const item of iterable) {
560
- const v = selector(item);
561
- if (v > max)
562
- max = v;
563
- }
564
- return max;
565
- }
566
- function minOrNull(arr, selector) {
567
- if (arr.length === 0)
568
- return null;
569
- let minItem = arr[0];
570
- let minVal = selector(minItem);
571
- for (let i = 1; i < arr.length; i++) {
572
- const v = selector(arr[i]);
573
- if (v < minVal) {
574
- minVal = v;
575
- minItem = arr[i];
576
- }
577
- }
578
- return minItem;
579
- }
580
- function maxOrNull(arr, selector) {
581
- if (arr.length === 0)
582
- return null;
583
- let maxItem = arr[0];
584
- let maxVal = selector(maxItem);
585
- for (let i = 1; i < arr.length; i++) {
586
- const v = selector(arr[i]);
587
- if (v > maxVal) {
588
- maxVal = v;
589
- maxItem = arr[i];
590
- }
591
- }
592
- return maxItem;
593
- }
594
- function joinToString(iterable, separator = ", ", prefix = "", suffix = "", transform) {
595
- const parts = [];
596
- for (const item of iterable)
597
- parts.push(transform ? transform(item) : String(item));
598
- return prefix + parts.join(separator) + suffix;
599
- }
600
- function take(arr, n) {
601
- return arr.slice(0, n);
602
- }
603
- function takeWhile(iterable, predicate) {
604
- const result = [];
605
- for (const item of iterable) {
606
- if (!predicate(item))
607
- break;
608
- result.push(item);
609
- }
610
- return result;
611
- }
612
- function drop(arr, n) {
613
- return arr.slice(n);
614
- }
615
- function dropWhile(iterable, predicate) {
616
- const result = [];
617
- let dropping = true;
618
- for (const item of iterable) {
619
- if (dropping && predicate(item))
620
- continue;
621
- dropping = false;
622
- result.push(item);
623
- }
624
- return result;
625
- }
626
- // ─────────────────────────────────────────────────────────────────────────────
627
- // Numeric extensions
628
- // ─────────────────────────────────────────────────────────────────────────────
629
- function coerceAtLeast(value, min) {
630
- return value < min ? min : value;
631
- }
632
- function coerceAtMost(value, max) {
633
- return value > max ? max : value;
634
- }
635
- function coerceIn(value, min, max) {
636
- return value < min ? min : value > max ? max : value;
637
- }
638
- /** `Int.MAX_VALUE` and friends */
639
- exports.Int = {
640
- MAX_VALUE: 2147483647,
641
- MIN_VALUE: -2147483648,
642
- };
643
- exports.Long = {
644
- MAX_VALUE: BigInt("9223372036854775807"),
645
- MIN_VALUE: BigInt("-9223372036854775808"),
646
- };
647
- // ─────────────────────────────────────────────────────────────────────────────
648
- // String extensions
649
- // ─────────────────────────────────────────────────────────────────────────────
650
- function trimIndent(s) {
651
- const lines = s.split("\n");
652
- const nonEmpty = lines.filter((l) => l.trim().length > 0);
653
- const indent = nonEmpty.reduce((min, l) => {
654
- const m = l.match(/^(\s*)/);
655
- return Math.min(min, m?.[1]?.length ?? 0);
656
- }, Infinity);
657
- const clean = isFinite(indent) ? indent : 0;
658
- return lines.map((l) => l.slice(clean)).join("\n").replace(/^\n/, "").replace(/\n$/, "");
659
- }
660
- function repeat_(s, n) {
661
- return s.repeat(n);
662
- }
663
- function isBlank(s) {
664
- return s.trim().length === 0;
665
- }
666
- function isNotBlank(s) {
667
- return s.trim().length > 0;
668
- }
669
- function isNullOrBlank(s) {
670
- return s == null || s.trim().length === 0;
671
- }
672
- function toIntOrNull(s) {
673
- const n = parseInt(s, 10);
674
- return isNaN(n) ? null : n;
675
- }
676
- function toDoubleOrNull(s) {
677
- const n = parseFloat(s);
678
- return isNaN(n) ? null : n;
679
- }
680
- function toBooleanOrNull(s) {
681
- if (s.toLowerCase() === "true")
682
- return true;
683
- if (s.toLowerCase() === "false")
684
- return false;
685
- return null;
686
- }
687
- function padStart(s, length, padChar = " ") {
688
- return s.padStart(length, padChar);
689
- }
690
- function padEnd(s, length, padChar = " ") {
691
- return s.padEnd(length, padChar);
692
- }
693
- // ─────────────────────────────────────────────────────────────────────────────
694
- // Pair / Triple as classes (mirrors pairOf/tripleOf)
695
- // ─────────────────────────────────────────────────────────────────────────────
696
- class Pair {
697
- first;
698
- second;
699
- constructor(first, second) {
700
- this.first = first;
701
- this.second = second;
702
- }
703
- toList() { return [this.first, this.second]; }
704
- [Symbol.iterator]() {
705
- let i = 0;
706
- const vals = [this.first, this.second];
707
- return { next: () => i < vals.length ? { value: vals[i++], done: false } : { value: undefined, done: true } };
708
- }
709
- toString() { return `(${this.first}, ${this.second})`; }
710
- copy(first = this.first, second = this.second) { return new Pair(first, second); }
711
- }
712
- exports.Pair = Pair;
713
- class Triple {
714
- first;
715
- second;
716
- third;
717
- constructor(first, second, third) {
718
- this.first = first;
719
- this.second = second;
720
- this.third = third;
721
- }
722
- [Symbol.iterator]() {
723
- let i = 0;
724
- const vals = [this.first, this.second, this.third];
725
- return { next: () => i < vals.length ? { value: vals[i++], done: false } : { value: undefined, done: true } };
726
- }
727
- toString() { return `(${this.first}, ${this.second}, ${this.third})`; }
728
- }
729
- exports.Triple = Triple;
730
- // ─────────────────────────────────────────────────────────────────────────────
731
- // Math library
732
- // ─────────────────────────────────────────────────────────────────────────────
733
- exports.abs = Math.abs.bind(Math);
734
- exports.ceil = Math.ceil.bind(Math);
735
- exports.floor = Math.floor.bind(Math);
736
- exports.round = Math.round.bind(Math);
737
- exports.sqrt = Math.sqrt.bind(Math);
738
- exports.pow = Math.pow.bind(Math);
739
- exports.exp = Math.exp.bind(Math);
740
- exports.ln = Math.log.bind(Math);
741
- exports.log2 = Math.log2.bind(Math);
742
- exports.log10 = Math.log10.bind(Math);
743
- exports.sin = Math.sin.bind(Math);
744
- exports.cos = Math.cos.bind(Math);
745
- exports.tan = Math.tan.bind(Math);
746
- exports.asin = Math.asin.bind(Math);
747
- exports.acos = Math.acos.bind(Math);
748
- exports.atan = Math.atan.bind(Math);
749
- exports.atan2 = Math.atan2.bind(Math);
750
- exports.sign = Math.sign.bind(Math);
751
- exports.hypot = Math.hypot.bind(Math);
752
- exports.truncate = Math.trunc.bind(Math);
753
- exports.PI = Math.PI;
754
- exports.E = Math.E;
755
- /** Clamp a numeric value to a range */
756
- function clamp(value, min, max) {
757
- return Math.max(min, Math.min(max, value));
758
- }
759
- /** Returns the integer part, rounding towards zero */
760
- function truncDiv(a, b) {
761
- return Math.trunc(a / b);
762
- }
763
- // ─────────────────────────────────────────────────────────────────────────────
764
- // Extended String utilities
765
- // ─────────────────────────────────────────────────────────────────────────────
766
- function capitalize(s) {
767
- return s.length === 0 ? s : s[0].toUpperCase() + s.slice(1);
768
- }
769
- function decapitalize(s) {
770
- return s.length === 0 ? s : s[0].toLowerCase() + s.slice(1);
771
- }
772
- function substringBefore(s, delimiter) {
773
- const idx = s.indexOf(delimiter);
774
- return idx === -1 ? s : s.slice(0, idx);
775
- }
776
- function substringAfter(s, delimiter) {
777
- const idx = s.indexOf(delimiter);
778
- return idx === -1 ? "" : s.slice(idx + delimiter.length);
779
- }
780
- function substringBeforeLast(s, delimiter) {
781
- const idx = s.lastIndexOf(delimiter);
782
- return idx === -1 ? s : s.slice(0, idx);
783
- }
784
- function substringAfterLast(s, delimiter) {
785
- const idx = s.lastIndexOf(delimiter);
786
- return idx === -1 ? "" : s.slice(idx + delimiter.length);
787
- }
788
- function removePrefix(s, prefix) {
789
- return s.startsWith(prefix) ? s.slice(prefix.length) : s;
790
- }
791
- function removeSuffix(s, suffix) {
792
- return s.endsWith(suffix) ? s.slice(0, s.length - suffix.length) : s;
793
- }
794
- function lines(s) {
795
- return s.split(/\r?\n/);
796
- }
797
- function lineSequence(s) {
798
- return lines(s);
799
- }
800
- function ifEmpty(value, default_) {
801
- return (value == null || value.length === 0) ? default_() : value;
802
- }
803
- function ifBlank(value, default_) {
804
- return (value == null || value.trim().length === 0) ? default_() : value;
805
- }
806
- // ─────────────────────────────────────────────────────────────────────────────
807
- // Type conversion helpers
808
- // ─────────────────────────────────────────────────────────────────────────────
809
- function toInt(v) {
810
- return typeof v === "boolean" ? (v ? 1 : 0) : Math.trunc(Number(v));
811
- }
812
- function toLong(v) {
813
- return toInt(v);
814
- }
815
- function toFloat(v) {
816
- return Number(v);
817
- }
818
- function toDouble(v) {
819
- return Number(v);
820
- }
821
- function toChar(code) {
822
- return String.fromCharCode(code);
823
- }
824
- function charCodeOf(ch) {
825
- return ch.charCodeAt(0);
826
- }
827
- function toString(v) {
828
- return String(v);
829
- }
830
- // ─────────────────────────────────────────────────────────────────────────────
831
- // IntRange — backing type for `..`, `..<`, `downTo`, `step`
832
- // ─────────────────────────────────────────────────────────────────────────────
833
- class IntRange {
834
- start;
835
- endInclusive;
836
- stepSize;
837
- constructor(start, endInclusive, stepSize = 1) {
838
- this.start = start;
839
- this.endInclusive = endInclusive;
840
- this.stepSize = stepSize;
841
- }
842
- get isEmpty() {
843
- return this.stepSize > 0 ? this.start > this.endInclusive : this.start < this.endInclusive;
844
- }
845
- contains(n) {
846
- if (this.stepSize > 0)
847
- return n >= this.start && n <= this.endInclusive;
848
- return n <= this.start && n >= this.endInclusive;
849
- }
850
- [Symbol.iterator]() {
851
- let current = this.start;
852
- const end = this.endInclusive;
853
- const s = this.stepSize;
854
- return {
855
- next() {
856
- if (s > 0 ? current <= end : current >= end) {
857
- const value = current;
858
- current += s;
859
- return { value, done: false };
860
- }
861
- return { value: 0, done: true };
862
- }
863
- };
864
- }
865
- toList() { return [...this]; }
866
- count() { return Math.max(0, Math.floor((this.endInclusive - this.start) / this.stepSize) + 1); }
867
- first() { return this.start; }
868
- last() {
869
- if (this.stepSize === 0)
870
- return this.start;
871
- const n = Math.floor((this.endInclusive - this.start) / this.stepSize);
872
- return this.start + n * this.stepSize;
873
- }
874
- toString() { return `${this.start}..${this.endInclusive} step ${this.stepSize}`; }
875
- }
876
- exports.IntRange = IntRange;
877
- /** `5 downTo 1` — infix desugaring `5.downTo(1)` → `downTo(5, 1)` */
878
- function downTo(start, end) {
879
- return new IntRange(start, end, -1);
880
- }
881
- /** `(1..10).step(2)` — sets a custom step on a range */
882
- function step(range_, stepVal) {
883
- return new IntRange(range_.start, range_.endInclusive, stepVal);
884
- }
885
- // ─────────────────────────────────────────────────────────────────────────────
886
- // Collection builders — buildList {}, buildSet {}, buildMap {}, buildString {}
887
- // ─────────────────────────────────────────────────────────────────────────────
888
- class StringBuilder {
889
- _parts = [];
890
- append(s) { this._parts.push(String(s ?? "")); return this; }
891
- appendLine(s = "") { this._parts.push(String(s)); this._parts.push("\n"); return this; }
892
- prepend(s) { this._parts.unshift(String(s ?? "")); return this; }
893
- clear() { this._parts.length = 0; return this; }
894
- get length() { return this._parts.reduce((sum, p) => sum + p.length, 0); }
895
- isEmpty() { return this.length === 0; }
896
- isNotEmpty() { return this.length > 0; }
897
- toString() { return this._parts.join(""); }
898
- }
899
- exports.StringBuilder = StringBuilder;
900
- function buildString(fn) {
901
- const sb = new StringBuilder();
902
- fn(sb);
903
- return sb.toString();
904
- }
905
- function buildList(fn) {
906
- const arr = [];
907
- fn({
908
- add(item) { arr.push(item); },
909
- addAll(items) { for (const i of items)
910
- arr.push(i); },
911
- get size() { return arr.length; },
912
- });
913
- return arr;
914
- }
915
- function buildSet(fn) {
916
- const s = new Set();
917
- fn({
918
- add(item) { s.add(item); },
919
- addAll(items) { for (const i of items)
920
- s.add(i); },
921
- get size() { return s.size; },
922
- });
923
- return s;
924
- }
925
- function buildMap(fn) {
926
- const m = new Map();
927
- fn({
928
- put(key, value) { m.set(key, value); },
929
- putAll(entries) { for (const [k, v] of entries)
930
- m.set(k, v); },
931
- get size() { return m.size; },
932
- });
933
- return m;
934
- }
935
- // ─────────────────────────────────────────────────────────────────────────────
936
- // Result<T> — mirrors standard Result type
937
- // ─────────────────────────────────────────────────────────────────────────────
938
- class Result {
939
- _value;
940
- _error;
941
- _ok;
942
- constructor(_value, _error, _ok) {
943
- this._value = _value;
944
- this._error = _error;
945
- this._ok = _ok;
946
- }
947
- static success(value) { return new Result(value, undefined, true); }
948
- static failure(error) { return new Result(undefined, error, false); }
949
- get isSuccess() { return this._ok; }
950
- get isFailure() { return !this._ok; }
951
- getOrNull() { return this._ok ? this._value : null; }
952
- getOrUndefined() { return this._ok ? this._value : undefined; }
953
- getOrThrow() {
954
- if (this._ok)
955
- return this._value;
956
- throw this._error;
957
- }
958
- getOrDefault(default_) { return this._ok ? this._value : default_; }
959
- getOrElse(fn) { return this._ok ? this._value : fn(this._error); }
960
- exceptionOrNull() { return this._ok ? null : this._error; }
961
- map(fn) {
962
- if (!this._ok)
963
- return Result.failure(this._error);
964
- try {
965
- return Result.success(fn(this._value));
966
- }
967
- catch (e) {
968
- return Result.failure(e);
969
- }
970
- }
971
- mapCatching(fn) { return this.map(fn); }
972
- recover(fn) {
973
- if (this._ok)
974
- return this;
975
- try {
976
- return Result.success(fn(this._error));
977
- }
978
- catch (e) {
979
- return Result.failure(e);
980
- }
981
- }
982
- onSuccess(fn) {
983
- if (this._ok)
984
- fn(this._value);
985
- return this;
986
- }
987
- onFailure(fn) {
988
- if (!this._ok)
989
- fn(this._error);
990
- return this;
991
- }
992
- fold(onSuccess, onFailure) {
993
- return this._ok ? onSuccess(this._value) : onFailure(this._error);
994
- }
995
- toString() {
996
- return this._ok ? `Result.success(${this._value})` : `Result.failure(${this._error})`;
997
- }
998
- }
999
- exports.Result = Result;
1000
- /** Wrap a throwing function call in a Result. */
1001
- function runCatching(fn) {
1002
- try {
1003
- return Result.success(fn());
1004
- }
1005
- catch (e) {
1006
- return Result.failure(e);
1007
- }
1008
- }
1009
- /** Async variant — wraps a Promise-returning function. */
1010
- async function runCatchingAsync(fn) {
1011
- try {
1012
- return Result.success(await fn());
1013
- }
1014
- catch (e) {
1015
- return Result.failure(e);
1016
- }
1017
- }
1018
- // ─────────────────────────────────────────────────────────────────────────────
1019
- // Regex — thin wrapper over JS RegExp
1020
- // ─────────────────────────────────────────────────────────────────────────────
1021
- class RegexResult {
1022
- value;
1023
- range;
1024
- groupValues;
1025
- constructor(value, range, groupValues) {
1026
- this.value = value;
1027
- this.range = range;
1028
- this.groupValues = groupValues;
1029
- }
1030
- }
1031
- exports.RegexResult = RegexResult;
1032
- class Regex {
1033
- _re;
1034
- constructor(pattern, options = "") {
1035
- // Convert regex options: IGNORE_CASE → i, MULTILINE → m
1036
- const flags = options
1037
- .replace("IGNORE_CASE", "i")
1038
- .replace("MULTILINE", "m")
1039
- .replace("DOT_MATCHES_ALL", "s")
1040
- .replace(/[^gimsuy]/g, "");
1041
- this._re = new RegExp(pattern, flags || undefined);
1042
- }
1043
- /** Returns true if the entire input matches this regex (anchored). */
1044
- matches(input) {
1045
- const re = new RegExp(`^(?:${this._re.source})$`, this._re.flags.replace("g", ""));
1046
- return re.test(input);
1047
- }
1048
- /** Returns true if any part of the input matches. */
1049
- containsMatchIn(input) {
1050
- const re = new RegExp(this._re.source, this._re.flags.replace("g", ""));
1051
- return re.test(input);
1052
- }
1053
- find(input, startIndex = 0) {
1054
- const re = new RegExp(this._re.source, "g" + this._re.flags.replace("g", ""));
1055
- re.lastIndex = startIndex;
1056
- const m = re.exec(input);
1057
- if (!m)
1058
- return null;
1059
- return new RegexResult(m[0], { start: m.index, endInclusive: m.index + m[0].length - 1 }, m.slice(1).map((g) => g ?? ""));
1060
- }
1061
- findAll(input, startIndex = 0) {
1062
- const re = new RegExp(this._re.source, "g" + this._re.flags.replace("g", ""));
1063
- re.lastIndex = startIndex;
1064
- const results = [];
1065
- let m;
1066
- while ((m = re.exec(input)) !== null) {
1067
- results.push(new RegexResult(m[0], { start: m.index, endInclusive: m.index + m[0].length - 1 }, m.slice(1).map((g) => g ?? "")));
1068
- }
1069
- return results;
1070
- }
1071
- replace(input, replacement) {
1072
- const re = new RegExp(this._re.source, "g" + this._re.flags.replace("g", ""));
1073
- if (typeof replacement === "string")
1074
- return input.replace(re, replacement);
1075
- return input.replace(re, (match, ...groups) => {
1076
- const index = groups[groups.length - 2];
1077
- const r = new RegexResult(match, { start: index, endInclusive: index + match.length - 1 }, groups.slice(0, -2).map(String));
1078
- return replacement(r);
1079
- });
1080
- }
1081
- replaceFirst(input, replacement) {
1082
- const re = new RegExp(this._re.source, this._re.flags.replace("g", ""));
1083
- return input.replace(re, replacement);
1084
- }
1085
- split(input, limit) {
1086
- const parts = input.split(this._re);
1087
- return limit !== undefined ? parts.slice(0, limit) : parts;
1088
- }
1089
- toPattern() { return this._re.source; }
1090
- toString() { return this._re.toString(); }
1091
- }
1092
- exports.Regex = Regex;
1093
- exports.JalvinRegex = Regex;
1094
- // ─────────────────────────────────────────────────────────────────────────────
1095
- // Timing utilities
1096
- // ─────────────────────────────────────────────────────────────────────────────
1097
- /** Measures how long a synchronous function takes in milliseconds. */
1098
- function measureTimeMillis(fn) {
1099
- const start = performance.now();
1100
- fn();
1101
- return Math.round(performance.now() - start);
1102
- }
1103
- /** Measures how long an async function takes in milliseconds. */
1104
- async function measureTimeMillisAsync(fn) {
1105
- const start = performance.now();
1106
- await fn();
1107
- return Math.round(performance.now() - start);
1108
- }
1109
- function measureTimedValue(fn) {
1110
- const start = performance.now();
1111
- const value = fn();
1112
- return { value, duration: Math.round(performance.now() - start) };
1113
- }
1114
- // ─────────────────────────────────────────────────────────────────────────────
1115
- // Random
1116
- // ─────────────────────────────────────────────────────────────────────────────
1117
- class Random {
1118
- seed;
1119
- constructor(seed) {
1120
- this.seed = seed;
1121
- // Seeding is approximate — JS Math.random() is not seedable natively
1122
- // For reproducible tests, use a third-party seeded PRNG
1123
- }
1124
- nextInt(fromOrUntil, until) {
1125
- if (fromOrUntil === undefined)
1126
- return Math.floor(Math.random() * 2147483647);
1127
- if (until === undefined)
1128
- return Math.floor(Math.random() * fromOrUntil);
1129
- return fromOrUntil + Math.floor(Math.random() * (until - fromOrUntil));
1130
- }
1131
- nextLong(until) { return this.nextInt(until ?? 2147483647); }
1132
- nextDouble() { return Math.random(); }
1133
- nextFloat() { return Math.random(); }
1134
- nextBoolean() { return Math.random() < 0.5; }
1135
- nextBytes(size) {
1136
- const arr = new Uint8Array(size);
1137
- for (let i = 0; i < size; i++)
1138
- arr[i] = this.nextInt(256);
1139
- return arr;
1140
- }
1141
- }
1142
- exports.Random = Random;
1143
- /** The default global Random instance. */
1144
- exports.Default = new Random();
1145
- /** Generate a RFC 4122 v4 UUID string. */
1146
- function randomUUID() {
1147
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
1148
- return crypto.randomUUID();
1149
- }
1150
- // Fallback for environments without crypto.randomUUID
1151
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1152
- const r = (Math.random() * 16) | 0;
1153
- return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
1154
- });
1155
- }
1156
- // ─────────────────────────────────────────────────────────────────────────────
1157
- // Structural equality — backs the Jalvin `==` operator
1158
- // ─────────────────────────────────────────────────────────────────────────────
1159
- /**
1160
- * Structural equality check:
1161
- * - null-safe: `null == null` is `true`, `null == anything` is `false`
1162
- * - for objects that expose an `.equals(other)` method, delegates to it
1163
- * - for primitives and everything else, falls back to `===`
1164
- */
1165
- function jalvinEquals(a, b) {
1166
- if (a === b)
1167
- return true;
1168
- if (a === null || a === undefined || b === null || b === undefined)
1169
- return false;
1170
- if (typeof a === "object" && typeof a["equals"] === "function") {
1171
- return a.equals(b);
1172
- }
1173
- if (Array.isArray(a) && Array.isArray(b)) {
1174
- if (a.length !== b.length)
1175
- return false;
1176
- return a.every((v, i) => jalvinEquals(v, b[i]));
1177
- }
1178
- return false;
1179
- }
1180
- //# sourceMappingURL=utils.js.map