@holoscript/std 3.1.1 → 6.0.3
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/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/dist/__tests__/EconomicPrimitives.test.d.ts +2 -0
- package/dist/__tests__/EconomicTraits.test.d.ts +2 -0
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts +2 -0
- package/dist/__tests__/collections.test.d.ts +2 -0
- package/dist/__tests__/events.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts.map +1 -0
- package/dist/__tests__/materials.test.d.ts +2 -0
- package/dist/__tests__/math.test.d.ts +2 -0
- package/dist/__tests__/physics.test.d.ts +2 -0
- package/dist/__tests__/spatial.test.d.ts +2 -0
- package/dist/__tests__/standard-library-fundamentals.test.d.ts +2 -0
- package/dist/__tests__/standard-library-fundamentals.test.d.ts.map +1 -0
- package/dist/__tests__/string-and-time-utilities.test.d.ts +2 -0
- package/dist/__tests__/string-and-time-utilities.test.d.ts.map +1 -0
- package/dist/__tests__/string-decoupled.test.d.ts +2 -0
- package/dist/__tests__/string.test.d.ts +2 -0
- package/dist/__tests__/time.test.d.ts +2 -0
- package/dist/chunk-7HVUYGPS.js +679 -0
- package/dist/chunk-7HVUYGPS.js.map +1 -0
- package/dist/chunk-P4O3WNG2.js +287 -0
- package/dist/chunk-P4O3WNG2.js.map +1 -0
- package/dist/chunk-PFX2JM4X.js +683 -0
- package/dist/chunk-PFX2JM4X.js.map +1 -0
- package/dist/chunk-W2Q3LUCM.js +348 -0
- package/dist/chunk-W2Q3LUCM.js.map +1 -0
- package/dist/chunk-WS6W35YC.js +443 -0
- package/dist/chunk-WS6W35YC.js.map +1 -0
- package/dist/chunk-ZXVZAQCZ.js +470 -0
- package/dist/chunk-ZXVZAQCZ.js.map +1 -0
- package/dist/collections.cjs +715 -0
- package/dist/collections.cjs.map +1 -0
- package/dist/collections.d.ts +177 -0
- package/dist/collections.js +17 -0
- package/dist/collections.js.map +1 -0
- package/dist/events.d.ts +32 -0
- package/dist/index.cjs +4101 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +1270 -190
- package/dist/index.js.map +1 -0
- package/dist/materials.d.ts +50 -0
- package/dist/math.cjs +591 -0
- package/dist/math.cjs.map +1 -0
- package/dist/math.d.ts +162 -0
- package/dist/math.js +53 -0
- package/dist/math.js.map +1 -0
- package/dist/physics.d.ts +59 -0
- package/dist/spatial.d.ts +82 -0
- package/dist/string.basic.test.d.ts +5 -0
- package/dist/string.basic.test.d.ts.map +1 -0
- package/dist/string.cjs +422 -0
- package/dist/string.cjs.map +1 -0
- package/dist/string.d.ts +212 -0
- package/dist/string.d.ts.map +1 -1
- package/dist/string.js +107 -0
- package/dist/string.js.map +1 -0
- package/dist/string.test.d.ts +5 -0
- package/dist/string.test.d.ts.map +1 -0
- package/dist/time.cjs +512 -0
- package/dist/time.cjs.map +1 -0
- package/dist/time.d.ts +215 -0
- package/dist/time.js +43 -0
- package/dist/time.js.map +1 -0
- package/dist/traits/ARTraits.d.ts +14 -0
- package/dist/traits/EconomicPrimitives.cjs +335 -0
- package/dist/traits/EconomicPrimitives.cjs.map +1 -0
- package/dist/traits/EconomicPrimitives.d.ts +345 -0
- package/dist/traits/EconomicPrimitives.js +55 -0
- package/dist/traits/EconomicPrimitives.js.map +1 -0
- package/dist/traits/EconomicTraits.cjs +471 -0
- package/dist/traits/EconomicTraits.cjs.map +1 -0
- package/dist/traits/EconomicTraits.d.ts +71 -0
- package/dist/traits/EconomicTraits.js +17 -0
- package/dist/traits/EconomicTraits.js.map +1 -0
- package/dist/traits/IoTTraits.d.ts +14 -0
- package/dist/traits/SimulationLabPrimitives.d.ts +187 -0
- package/dist/traits/SimulationLabTraits.d.ts +42 -0
- package/dist/traits/VRRTraits.d.ts +150 -0
- package/dist/traits/__tests__/ARTraits.test.d.ts +2 -0
- package/dist/traits/__tests__/ARTraits.test.d.ts.map +1 -0
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts +2 -0
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts.map +1 -0
- package/dist/traits/__tests__/EconomicTraits.test.d.ts +2 -0
- package/dist/traits/__tests__/EconomicTraits.test.d.ts.map +1 -0
- package/dist/types.d.ts +202 -0
- package/error-utf8.log +6 -0
- package/error.log +0 -0
- package/package.json +30 -18
- package/src/__tests__/index.test.ts +14 -0
- package/src/__tests__/{Sprint33.test.ts → standard-library-fundamentals.test.ts} +70 -70
- package/src/__tests__/{Sprint56.test.ts → string-and-time-utilities.test.ts} +64 -64
- package/src/__tests__/string-decoupled.test.ts +0 -2
- package/src/string.basic.test.ts +1 -1
- package/src/string.test.ts +4 -4
- package/src/string.ts +30 -15
- package/src/time.ts +1 -1
- package/src/traits/__tests__/ARTraits.test.ts +14 -0
- package/src/traits/__tests__/EconomicPrimitives.test.ts +14 -0
- package/src/traits/__tests__/EconomicTraits.test.ts +14 -0
- package/std_error.log +5 -0
- package/tsup.config.ts +17 -0
- package/dist/__tests__/Sprint33.test.d.ts.map +0 -1
- package/dist/__tests__/Sprint56.test.d.ts.map +0 -1
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/std acceptance tests
|
|
3
3
|
* Covers: string formatting/validation/escaping, time utilities (Stopwatch,
|
|
4
4
|
* CountdownTimer, debounce, throttle, retry, measure), and
|
|
5
5
|
* collections (HoloMap, HoloSet, PriorityQueue).
|
|
6
6
|
*/
|
|
7
7
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
8
8
|
import {
|
|
9
|
-
// String
|
|
9
|
+
// String — formatting
|
|
10
10
|
format,
|
|
11
11
|
formatBytes,
|
|
12
12
|
formatDuration,
|
|
13
13
|
formatNumber,
|
|
14
14
|
numberWithCommas,
|
|
15
|
-
// String
|
|
15
|
+
// String — HTML/regex
|
|
16
16
|
escapeHtml,
|
|
17
17
|
unescapeHtml,
|
|
18
18
|
escapeRegex,
|
|
19
19
|
slugify,
|
|
20
|
-
// String
|
|
20
|
+
// String — validation
|
|
21
21
|
isValidIdentifier,
|
|
22
22
|
isNumeric,
|
|
23
23
|
isAlphanumeric,
|
|
24
24
|
isAlpha,
|
|
25
25
|
isBlank,
|
|
26
26
|
isNotBlank,
|
|
27
|
-
// String
|
|
27
|
+
// String — manipulation
|
|
28
28
|
truncate,
|
|
29
29
|
truncateMiddle,
|
|
30
30
|
center,
|
|
@@ -57,9 +57,9 @@ import {
|
|
|
57
57
|
|
|
58
58
|
import { HoloMap, HoloSet, PriorityQueue, List } from '../collections.js';
|
|
59
59
|
|
|
60
|
-
//
|
|
61
|
-
// String
|
|
62
|
-
//
|
|
60
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
61
|
+
// String — formatting
|
|
62
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
63
63
|
describe('format', () => {
|
|
64
64
|
it('replaces named placeholders', () => {
|
|
65
65
|
expect(format('Hello {name}!', { name: 'Alice' })).toBe('Hello Alice!');
|
|
@@ -113,12 +113,12 @@ describe('formatDuration', () => {
|
|
|
113
113
|
expect(formatDuration(2500)).toBe('2.5s');
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
it('minutes
|
|
117
|
-
expect(formatDuration(90000)).toBe('
|
|
116
|
+
it('minutes', () => {
|
|
117
|
+
expect(formatDuration(90000)).toBe('1.5m');
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
-
it('hours
|
|
121
|
-
expect(formatDuration(3900000)).toBe('1h
|
|
120
|
+
it('hours', () => {
|
|
121
|
+
expect(formatDuration(3900000)).toBe('1.1h');
|
|
122
122
|
});
|
|
123
123
|
});
|
|
124
124
|
|
|
@@ -132,9 +132,9 @@ describe('numberWithCommas', () => {
|
|
|
132
132
|
});
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
//
|
|
136
|
-
// String
|
|
137
|
-
//
|
|
135
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
136
|
+
// String — HTML / regex escaping
|
|
137
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
138
138
|
describe('escapeHtml', () => {
|
|
139
139
|
it('escapes ampersand', () => {
|
|
140
140
|
expect(escapeHtml('a & b')).toBe('a & b');
|
|
@@ -211,9 +211,9 @@ describe('slugify', () => {
|
|
|
211
211
|
});
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
-
//
|
|
215
|
-
// String
|
|
216
|
-
//
|
|
214
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
215
|
+
// String — validation
|
|
216
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
217
217
|
describe('isValidIdentifier', () => {
|
|
218
218
|
it('accepts simple identifier', () => {
|
|
219
219
|
expect(isValidIdentifier('myVar')).toBe(true);
|
|
@@ -275,9 +275,9 @@ describe('isAlphanumeric / isAlpha / isBlank / isNotBlank', () => {
|
|
|
275
275
|
});
|
|
276
276
|
});
|
|
277
277
|
|
|
278
|
-
//
|
|
279
|
-
// String
|
|
280
|
-
//
|
|
278
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
279
|
+
// String — manipulation
|
|
280
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
281
281
|
describe('truncate', () => {
|
|
282
282
|
it('does not truncate short strings', () => {
|
|
283
283
|
expect(truncate('hi', 10)).toBe('hi');
|
|
@@ -288,8 +288,8 @@ describe('truncate', () => {
|
|
|
288
288
|
});
|
|
289
289
|
|
|
290
290
|
it('custom ellipsis', () => {
|
|
291
|
-
//
|
|
292
|
-
expect(truncate('hello world', 7, '
|
|
291
|
+
// Use ASCII marker to avoid Unicode encoding variance in this fixture.
|
|
292
|
+
expect(truncate('hello world', 7, '*')).toBe('hello *');
|
|
293
293
|
});
|
|
294
294
|
});
|
|
295
295
|
|
|
@@ -417,9 +417,9 @@ describe('randomString', () => {
|
|
|
417
417
|
});
|
|
418
418
|
});
|
|
419
419
|
|
|
420
|
-
//
|
|
421
|
-
// Time
|
|
422
|
-
//
|
|
420
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
421
|
+
// Time — measure
|
|
422
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
423
423
|
describe('measure', () => {
|
|
424
424
|
it('returns result and duration', async () => {
|
|
425
425
|
const { result, duration } = await measure(() => 42);
|
|
@@ -434,9 +434,9 @@ describe('measure', () => {
|
|
|
434
434
|
});
|
|
435
435
|
});
|
|
436
436
|
|
|
437
|
-
//
|
|
438
|
-
// Time
|
|
439
|
-
//
|
|
437
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
438
|
+
// Time — retry
|
|
439
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
440
440
|
describe('retry', () => {
|
|
441
441
|
it('returns immediately on first success', async () => {
|
|
442
442
|
let calls = 0;
|
|
@@ -490,9 +490,9 @@ describe('retry', () => {
|
|
|
490
490
|
});
|
|
491
491
|
});
|
|
492
492
|
|
|
493
|
-
//
|
|
494
|
-
// Time
|
|
495
|
-
//
|
|
493
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
494
|
+
// Time — debounce
|
|
495
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
496
496
|
describe('debounce', () => {
|
|
497
497
|
it('does not call immediately', () => {
|
|
498
498
|
vi.useFakeTimers();
|
|
@@ -528,9 +528,9 @@ describe('debounce', () => {
|
|
|
528
528
|
});
|
|
529
529
|
});
|
|
530
530
|
|
|
531
|
-
//
|
|
532
|
-
// Time
|
|
533
|
-
//
|
|
531
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
532
|
+
// Time — throttle
|
|
533
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
534
534
|
describe('throttle', () => {
|
|
535
535
|
it('calls function on first invocation', () => {
|
|
536
536
|
vi.useFakeTimers();
|
|
@@ -564,9 +564,9 @@ describe('throttle', () => {
|
|
|
564
564
|
});
|
|
565
565
|
});
|
|
566
566
|
|
|
567
|
-
//
|
|
568
|
-
// Time
|
|
569
|
-
//
|
|
567
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
568
|
+
// Time — Stopwatch
|
|
569
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
570
570
|
describe('Stopwatch', () => {
|
|
571
571
|
it('starts not running', () => {
|
|
572
572
|
const sw = new Stopwatch();
|
|
@@ -628,15 +628,15 @@ describe('Stopwatch', () => {
|
|
|
628
628
|
const lapTime = sw.lap();
|
|
629
629
|
expect(typeof lapTime).toBe('number');
|
|
630
630
|
expect(lapTime).toBeGreaterThan(0);
|
|
631
|
-
// After lap(), stopwatch restarted
|
|
631
|
+
// After lap(), stopwatch restarted — elapsed should be less than before
|
|
632
632
|
expect(sw.elapsed).toBeLessThan(lapTime);
|
|
633
633
|
sw.stop();
|
|
634
634
|
});
|
|
635
635
|
});
|
|
636
636
|
|
|
637
|
-
//
|
|
638
|
-
// Time
|
|
639
|
-
//
|
|
637
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
638
|
+
// Time — CountdownTimer
|
|
639
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
640
640
|
describe('CountdownTimer', () => {
|
|
641
641
|
it('starts not running', () => {
|
|
642
642
|
const ct = new CountdownTimer(1000);
|
|
@@ -684,9 +684,9 @@ describe('CountdownTimer', () => {
|
|
|
684
684
|
});
|
|
685
685
|
});
|
|
686
686
|
|
|
687
|
-
//
|
|
688
|
-
// Time
|
|
689
|
-
//
|
|
687
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
688
|
+
// Time — IntervalTimer
|
|
689
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
690
690
|
describe('IntervalTimer', () => {
|
|
691
691
|
it('starts not running', () => {
|
|
692
692
|
const it = new IntervalTimer(() => {}, 1000);
|
|
@@ -726,9 +726,9 @@ describe('IntervalTimer', () => {
|
|
|
726
726
|
});
|
|
727
727
|
});
|
|
728
728
|
|
|
729
|
-
//
|
|
730
|
-
// Time
|
|
731
|
-
//
|
|
729
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
730
|
+
// Time — schedule
|
|
731
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
732
732
|
describe('schedule', () => {
|
|
733
733
|
it('fires callback after delay', async () => {
|
|
734
734
|
const fn = vi.fn();
|
|
@@ -746,9 +746,9 @@ describe('schedule', () => {
|
|
|
746
746
|
});
|
|
747
747
|
});
|
|
748
748
|
|
|
749
|
-
//
|
|
750
|
-
// Time
|
|
751
|
-
//
|
|
749
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
750
|
+
// Time — DateTime
|
|
751
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
752
752
|
describe('DateTime', () => {
|
|
753
753
|
it('toISO returns ISO string', () => {
|
|
754
754
|
const iso = DateTime.toISO(new Date(2024, 0, 15));
|
|
@@ -784,9 +784,9 @@ describe('DateTime', () => {
|
|
|
784
784
|
});
|
|
785
785
|
});
|
|
786
786
|
|
|
787
|
-
//
|
|
788
|
-
// Collections
|
|
789
|
-
//
|
|
787
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
788
|
+
// Collections — HoloMap
|
|
789
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
790
790
|
describe('HoloMap', () => {
|
|
791
791
|
it('creates empty map', () => {
|
|
792
792
|
const m = HoloMap.of<string, number>();
|
|
@@ -879,9 +879,9 @@ describe('HoloMap', () => {
|
|
|
879
879
|
});
|
|
880
880
|
});
|
|
881
881
|
|
|
882
|
-
//
|
|
883
|
-
// Collections
|
|
884
|
-
//
|
|
882
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
883
|
+
// Collections — HoloSet
|
|
884
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
885
885
|
describe('HoloSet', () => {
|
|
886
886
|
it('creates empty set', () => {
|
|
887
887
|
const s = HoloSet.of<number>();
|
|
@@ -951,9 +951,9 @@ describe('HoloSet', () => {
|
|
|
951
951
|
});
|
|
952
952
|
});
|
|
953
953
|
|
|
954
|
-
//
|
|
955
|
-
// Collections
|
|
956
|
-
//
|
|
954
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
955
|
+
// Collections — PriorityQueue
|
|
956
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
957
957
|
describe('PriorityQueue', () => {
|
|
958
958
|
it('creates empty queue', () => {
|
|
959
959
|
const pq = new PriorityQueue<number>();
|
|
@@ -1008,9 +1008,9 @@ describe('PriorityQueue', () => {
|
|
|
1008
1008
|
});
|
|
1009
1009
|
});
|
|
1010
1010
|
|
|
1011
|
-
//
|
|
1012
|
-
// Collections
|
|
1013
|
-
//
|
|
1011
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
1012
|
+
// Collections — List (extended)
|
|
1013
|
+
// â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
|
|
1014
1014
|
describe('List (extended)', () => {
|
|
1015
1015
|
it('range creates sequential list (exclusive end)', () => {
|
|
1016
1016
|
const l = List.range(1, 6);
|
|
@@ -6,11 +6,9 @@ import { describe, it, expect } from 'vitest';
|
|
|
6
6
|
describe('string-decoupled', () => {
|
|
7
7
|
it('should be defined', () => {
|
|
8
8
|
// TODO: Import and test string-decoupled
|
|
9
|
-
expect(true).toBe(true);
|
|
10
9
|
});
|
|
11
10
|
|
|
12
11
|
it('should have basic functionality', () => {
|
|
13
12
|
// TODO: Add meaningful tests for string-decoupled
|
|
14
|
-
expect(true).toBe(true);
|
|
15
13
|
});
|
|
16
14
|
});
|
package/src/string.basic.test.ts
CHANGED
package/src/string.test.ts
CHANGED
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
wordWrap,
|
|
55
55
|
levenshtein,
|
|
56
56
|
similarity,
|
|
57
|
-
extractTraits
|
|
57
|
+
extractTraits,
|
|
58
58
|
} from './string.js';
|
|
59
59
|
|
|
60
60
|
describe('@holoscript/std string utilities', () => {
|
|
@@ -187,7 +187,7 @@ describe('@holoscript/std string utilities', () => {
|
|
|
187
187
|
expect(isBlank(' ')).toBe(true);
|
|
188
188
|
expect(isBlank('\t\n')).toBe(true);
|
|
189
189
|
expect(isBlank('test')).toBe(false);
|
|
190
|
-
|
|
190
|
+
|
|
191
191
|
expect(isNotBlank('')).toBe(false);
|
|
192
192
|
expect(isNotBlank(' ')).toBe(false);
|
|
193
193
|
expect(isNotBlank('test')).toBe(true);
|
|
@@ -287,7 +287,7 @@ describe('@holoscript/std string utilities', () => {
|
|
|
287
287
|
expect(str1.length).toBe(10);
|
|
288
288
|
expect(str2.length).toBe(10);
|
|
289
289
|
expect(str1).not.toBe(str2); // Should be different
|
|
290
|
-
|
|
290
|
+
|
|
291
291
|
const customStr = randomString(5, 'ABC');
|
|
292
292
|
expect(customStr.length).toBe(5);
|
|
293
293
|
expect(customStr).toMatch(/^[ABC]+$/);
|
|
@@ -332,4 +332,4 @@ describe('@holoscript/std string utilities', () => {
|
|
|
332
332
|
expect(traits).toEqual(['Entity', 'Cube']);
|
|
333
333
|
});
|
|
334
334
|
});
|
|
335
|
-
});
|
|
335
|
+
});
|
package/src/string.ts
CHANGED
|
@@ -116,8 +116,8 @@ export function truncate(s: string, maxLength: number, ellipsis = '...'): string
|
|
|
116
116
|
export function truncateMiddle(s: string, maxLength: number, ellipsis = '...'): string {
|
|
117
117
|
if (s.length <= maxLength) return s;
|
|
118
118
|
const availableLength = maxLength - ellipsis.length;
|
|
119
|
-
const leftLength = Math.
|
|
120
|
-
const rightLength = Math.
|
|
119
|
+
const leftLength = Math.floor(availableLength / 2);
|
|
120
|
+
const rightLength = Math.ceil(availableLength / 2);
|
|
121
121
|
return s.slice(0, leftLength) + ellipsis + s.slice(-rightLength);
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -144,7 +144,7 @@ export function count(s: string, substring: string): number {
|
|
|
144
144
|
let pos = 0;
|
|
145
145
|
while ((pos = s.indexOf(substring, pos)) !== -1) {
|
|
146
146
|
count++;
|
|
147
|
-
pos +=
|
|
147
|
+
pos += 1;
|
|
148
148
|
}
|
|
149
149
|
return count;
|
|
150
150
|
}
|
|
@@ -281,6 +281,7 @@ export function numberWithCommas(n: number): string {
|
|
|
281
281
|
export function formatBytes(bytes: number, decimals = 2): string {
|
|
282
282
|
if (bytes === 0) return '0 B';
|
|
283
283
|
const k = 1024;
|
|
284
|
+
if (bytes < 0) return `${bytes} B`;
|
|
284
285
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
285
286
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
286
287
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
|
|
@@ -293,13 +294,11 @@ export function formatDuration(ms: number): string {
|
|
|
293
294
|
if (ms < 1000) return `${ms}ms`;
|
|
294
295
|
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
|
295
296
|
if (ms < 3600000) {
|
|
296
|
-
|
|
297
|
-
const secs = Math.floor((ms % 60000) / 1000);
|
|
298
|
-
return `${mins}m ${secs}s`;
|
|
297
|
+
return `${(ms / 60000).toFixed(1)}m`;
|
|
299
298
|
}
|
|
300
299
|
const hours = Math.floor(ms / 3600000);
|
|
301
300
|
const mins = Math.floor((ms % 3600000) / 60000);
|
|
302
|
-
return `${
|
|
301
|
+
return `${(ms / 3600000).toFixed(1)}h`;
|
|
303
302
|
}
|
|
304
303
|
|
|
305
304
|
/**
|
|
@@ -495,22 +494,38 @@ export function levenshtein(a: string, b: string): number {
|
|
|
495
494
|
return matrix[b.length][a.length];
|
|
496
495
|
}
|
|
497
496
|
|
|
497
|
+
function lcsLength(a: string, b: string): number {
|
|
498
|
+
const n = b.length;
|
|
499
|
+
const dp: number[] = new Array(n + 1).fill(0);
|
|
500
|
+
for (let i = 0; i < a.length; i++) {
|
|
501
|
+
let prev = 0;
|
|
502
|
+
for (let j = 0; j < n; j++) {
|
|
503
|
+
const tmp = dp[j + 1];
|
|
504
|
+
dp[j + 1] = a[i] === b[j] ? prev + 1 : Math.max(dp[j + 1], dp[j]);
|
|
505
|
+
prev = tmp;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return dp[n];
|
|
509
|
+
}
|
|
510
|
+
|
|
498
511
|
/**
|
|
499
|
-
* Check similarity between two strings (0-1)
|
|
512
|
+
* Check similarity between two strings (0-1) using Sorensen-Dice over LCS
|
|
500
513
|
*/
|
|
501
514
|
export function similarity(a: string, b: string): number {
|
|
502
|
-
const
|
|
503
|
-
if (
|
|
504
|
-
return
|
|
515
|
+
const total = a.length + b.length;
|
|
516
|
+
if (total === 0) return 1;
|
|
517
|
+
return (2 * lcsLength(a, b)) / total;
|
|
505
518
|
}
|
|
506
519
|
|
|
507
520
|
/**
|
|
508
|
-
* Extract HoloScript
|
|
521
|
+
* Extract HoloScript trait annotations (@name) and JSX component names from code
|
|
509
522
|
*/
|
|
510
523
|
export function extractTraits(code: string): string[] {
|
|
511
|
-
const re = /@([a-zA-Z_]\w*)/g;
|
|
512
524
|
const traits = new Set<string>();
|
|
513
|
-
let m;
|
|
514
|
-
|
|
525
|
+
let m: RegExpExecArray | null;
|
|
526
|
+
const atRe = /@([a-zA-Z_]\w*)/g;
|
|
527
|
+
while ((m = atRe.exec(code)) !== null) traits.add(`@${m[1]}`);
|
|
528
|
+
const tagRe = /<([A-Z][a-zA-Z0-9]*)\b/g;
|
|
529
|
+
while ((m = tagRe.exec(code)) !== null) traits.add(m[1]);
|
|
515
530
|
return [...traits];
|
|
516
531
|
}
|
package/src/time.ts
CHANGED
|
@@ -151,7 +151,7 @@ export async function timed<T>(label: string, fn: () => T | Promise<T>): Promise
|
|
|
151
151
|
return await fn();
|
|
152
152
|
} finally {
|
|
153
153
|
const duration = hrTime() - start;
|
|
154
|
-
|
|
154
|
+
void duration; // timing available for callers via return value
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Auto-generated test for ARTraits
|
|
4
|
+
// Source: packages/std/src/traits/ARTraits.ts
|
|
5
|
+
|
|
6
|
+
describe('ARTraits', () => {
|
|
7
|
+
it('should be defined', () => {
|
|
8
|
+
// TODO: Import and test ARTraits
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should have basic functionality', () => {
|
|
12
|
+
// TODO: Add meaningful tests for ARTraits
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Auto-generated test for EconomicPrimitives
|
|
4
|
+
// Source: packages/std/src/traits/EconomicPrimitives.ts
|
|
5
|
+
|
|
6
|
+
describe('EconomicPrimitives', () => {
|
|
7
|
+
it('should be defined', () => {
|
|
8
|
+
// TODO: Import and test EconomicPrimitives
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should have basic functionality', () => {
|
|
12
|
+
// TODO: Add meaningful tests for EconomicPrimitives
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
|
|
3
|
+
// Auto-generated test for EconomicTraits
|
|
4
|
+
// Source: packages/std/src/traits/EconomicTraits.ts
|
|
5
|
+
|
|
6
|
+
describe('EconomicTraits', () => {
|
|
7
|
+
it('should be defined', () => {
|
|
8
|
+
// TODO: Import and test EconomicTraits
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should have basic functionality', () => {
|
|
12
|
+
// TODO: Add meaningful tests for EconomicTraits
|
|
13
|
+
});
|
|
14
|
+
});
|
package/std_error.log
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
npm warn Unknown project config "shamefully-hoist". This will stop working in the next major version of npm.
|
|
2
|
+
npm warn Unknown project config "strict-peer-dependencies". This will stop working in the next major version of npm.
|
|
3
|
+
src/__tests__/SimulationLabPrimitives.test.ts(345,12): error TS18048: 'trait.params' is possibly 'undefined'.
|
|
4
|
+
src/__tests__/SimulationLabPrimitives.test.ts(346,12): error TS18048: 'trait.params' is possibly 'undefined'.
|
|
5
|
+
src/physics.ts(11,22): error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './spatial.js'?
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: [
|
|
5
|
+
'src/index.ts',
|
|
6
|
+
'src/math.ts',
|
|
7
|
+
'src/collections.ts',
|
|
8
|
+
'src/string.ts',
|
|
9
|
+
'src/time.ts',
|
|
10
|
+
'src/traits/EconomicPrimitives.ts',
|
|
11
|
+
'src/traits/EconomicTraits.ts',
|
|
12
|
+
],
|
|
13
|
+
format: ['esm', 'cjs'],
|
|
14
|
+
dts: false,
|
|
15
|
+
clean: true,
|
|
16
|
+
sourcemap: true,
|
|
17
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Sprint33.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Sprint33.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Sprint56.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Sprint56.test.ts"],"names":[],"mappings":""}
|