@holoscript/std 2.1.0 → 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.
Files changed (159) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +197 -0
  4. package/dist/__tests__/EconomicPrimitives.test.d.ts +2 -0
  5. package/dist/__tests__/EconomicPrimitives.test.d.ts.map +1 -0
  6. package/dist/__tests__/EconomicTraits.test.d.ts +2 -0
  7. package/dist/__tests__/EconomicTraits.test.d.ts.map +1 -0
  8. package/dist/__tests__/SimulationLabPrimitives.test.d.ts +2 -0
  9. package/dist/__tests__/SimulationLabPrimitives.test.d.ts.map +1 -0
  10. package/dist/__tests__/collections.test.d.ts +2 -0
  11. package/dist/__tests__/collections.test.d.ts.map +1 -0
  12. package/dist/__tests__/events.test.d.ts +2 -0
  13. package/dist/__tests__/events.test.d.ts.map +1 -0
  14. package/dist/__tests__/index.test.d.ts +2 -0
  15. package/dist/__tests__/index.test.d.ts.map +1 -0
  16. package/dist/__tests__/materials.test.d.ts +2 -0
  17. package/dist/__tests__/materials.test.d.ts.map +1 -0
  18. package/dist/__tests__/math.test.d.ts +2 -0
  19. package/dist/__tests__/math.test.d.ts.map +1 -0
  20. package/dist/__tests__/physics.test.d.ts +2 -0
  21. package/dist/__tests__/physics.test.d.ts.map +1 -0
  22. package/dist/__tests__/spatial.test.d.ts +2 -0
  23. package/dist/__tests__/spatial.test.d.ts.map +1 -0
  24. package/dist/__tests__/standard-library-fundamentals.test.d.ts +2 -0
  25. package/dist/__tests__/standard-library-fundamentals.test.d.ts.map +1 -0
  26. package/dist/__tests__/string-and-time-utilities.test.d.ts +2 -0
  27. package/dist/__tests__/string-and-time-utilities.test.d.ts.map +1 -0
  28. package/dist/__tests__/string-decoupled.test.d.ts +2 -0
  29. package/dist/__tests__/string-decoupled.test.d.ts.map +1 -0
  30. package/dist/__tests__/string.test.d.ts +2 -0
  31. package/dist/__tests__/string.test.d.ts.map +1 -0
  32. package/dist/__tests__/time.test.d.ts +2 -0
  33. package/dist/__tests__/time.test.d.ts.map +1 -0
  34. package/dist/chunk-7HVUYGPS.js +679 -0
  35. package/dist/chunk-7HVUYGPS.js.map +1 -0
  36. package/dist/chunk-P4O3WNG2.js +287 -0
  37. package/dist/chunk-P4O3WNG2.js.map +1 -0
  38. package/dist/chunk-PFX2JM4X.js +683 -0
  39. package/dist/chunk-PFX2JM4X.js.map +1 -0
  40. package/dist/chunk-W2Q3LUCM.js +348 -0
  41. package/dist/chunk-W2Q3LUCM.js.map +1 -0
  42. package/dist/chunk-WS6W35YC.js +443 -0
  43. package/dist/chunk-WS6W35YC.js.map +1 -0
  44. package/dist/chunk-ZXVZAQCZ.js +470 -0
  45. package/dist/chunk-ZXVZAQCZ.js.map +1 -0
  46. package/dist/collections.cjs +715 -0
  47. package/dist/collections.cjs.map +1 -0
  48. package/dist/collections.d.ts.map +1 -1
  49. package/dist/collections.js +16 -719
  50. package/dist/collections.js.map +1 -1
  51. package/dist/events.d.ts +32 -0
  52. package/dist/events.d.ts.map +1 -0
  53. package/dist/index.cjs +4101 -0
  54. package/dist/index.cjs.map +1 -0
  55. package/dist/index.d.ts +21 -9
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +1270 -157
  58. package/dist/index.js.map +1 -1
  59. package/dist/materials.d.ts +50 -0
  60. package/dist/materials.d.ts.map +1 -0
  61. package/dist/math.cjs +591 -0
  62. package/dist/math.cjs.map +1 -0
  63. package/dist/math.d.ts.map +1 -1
  64. package/dist/math.js +51 -537
  65. package/dist/math.js.map +1 -1
  66. package/dist/physics.d.ts +59 -0
  67. package/dist/physics.d.ts.map +1 -0
  68. package/dist/spatial.d.ts +82 -0
  69. package/dist/spatial.d.ts.map +1 -0
  70. package/dist/string.basic.test.d.ts +5 -0
  71. package/dist/string.basic.test.d.ts.map +1 -0
  72. package/dist/string.cjs +422 -0
  73. package/dist/string.cjs.map +1 -0
  74. package/dist/string.d.ts +5 -1
  75. package/dist/string.d.ts.map +1 -1
  76. package/dist/string.js +106 -442
  77. package/dist/string.js.map +1 -1
  78. package/dist/string.test.d.ts +5 -0
  79. package/dist/string.test.d.ts.map +1 -0
  80. package/dist/time.cjs +512 -0
  81. package/dist/time.cjs.map +1 -0
  82. package/dist/time.d.ts.map +1 -1
  83. package/dist/time.js +41 -528
  84. package/dist/time.js.map +1 -1
  85. package/dist/traits/ARTraits.d.ts +14 -0
  86. package/dist/traits/ARTraits.d.ts.map +1 -0
  87. package/dist/traits/EconomicPrimitives.cjs +335 -0
  88. package/dist/traits/EconomicPrimitives.cjs.map +1 -0
  89. package/dist/traits/EconomicPrimitives.d.ts +345 -0
  90. package/dist/traits/EconomicPrimitives.d.ts.map +1 -0
  91. package/dist/traits/EconomicPrimitives.js +55 -0
  92. package/dist/traits/EconomicPrimitives.js.map +1 -0
  93. package/dist/traits/EconomicTraits.cjs +471 -0
  94. package/dist/traits/EconomicTraits.cjs.map +1 -0
  95. package/dist/traits/EconomicTraits.d.ts +71 -0
  96. package/dist/traits/EconomicTraits.d.ts.map +1 -0
  97. package/dist/traits/EconomicTraits.js +17 -0
  98. package/dist/traits/EconomicTraits.js.map +1 -0
  99. package/dist/traits/IoTTraits.d.ts +14 -0
  100. package/dist/traits/IoTTraits.d.ts.map +1 -0
  101. package/dist/traits/SimulationLabPrimitives.d.ts +187 -0
  102. package/dist/traits/SimulationLabPrimitives.d.ts.map +1 -0
  103. package/dist/traits/SimulationLabTraits.d.ts +42 -0
  104. package/dist/traits/SimulationLabTraits.d.ts.map +1 -0
  105. package/dist/traits/VRRTraits.d.ts +150 -0
  106. package/dist/traits/VRRTraits.d.ts.map +1 -0
  107. package/dist/traits/__tests__/ARTraits.test.d.ts +2 -0
  108. package/dist/traits/__tests__/ARTraits.test.d.ts.map +1 -0
  109. package/dist/traits/__tests__/EconomicPrimitives.test.d.ts +2 -0
  110. package/dist/traits/__tests__/EconomicPrimitives.test.d.ts.map +1 -0
  111. package/dist/traits/__tests__/EconomicTraits.test.d.ts +2 -0
  112. package/dist/traits/__tests__/EconomicTraits.test.d.ts.map +1 -0
  113. package/dist/types.d.ts +9 -0
  114. package/dist/types.d.ts.map +1 -1
  115. package/error-utf8.log +6 -0
  116. package/error.log +0 -0
  117. package/package.json +42 -19
  118. package/src/__tests__/EconomicPrimitives.test.ts +690 -0
  119. package/src/__tests__/EconomicTraits.test.ts +425 -0
  120. package/src/__tests__/SimulationLabPrimitives.test.ts +415 -0
  121. package/src/__tests__/collections.test.ts +182 -0
  122. package/src/__tests__/events.test.ts +135 -0
  123. package/src/__tests__/index.test.ts +14 -0
  124. package/src/__tests__/materials.test.ts +84 -0
  125. package/src/__tests__/math.test.ts +246 -0
  126. package/src/__tests__/physics.test.ts +83 -0
  127. package/src/__tests__/spatial.test.ts +333 -0
  128. package/src/__tests__/standard-library-fundamentals.test.ts +1301 -0
  129. package/src/__tests__/string-and-time-utilities.test.ts +1070 -0
  130. package/src/__tests__/string-decoupled.test.ts +14 -0
  131. package/src/__tests__/string.test.ts +164 -0
  132. package/src/__tests__/time.test.ts +110 -0
  133. package/src/collections.ts +8 -2
  134. package/src/events.ts +88 -0
  135. package/src/index.ts +161 -11
  136. package/src/materials.ts +109 -0
  137. package/src/math.ts +30 -14
  138. package/src/physics.ts +141 -0
  139. package/src/spatial.ts +320 -0
  140. package/src/string.basic.test.ts +14 -0
  141. package/src/string.test.ts +335 -0
  142. package/src/string.ts +45 -13
  143. package/src/time.ts +10 -11
  144. package/src/traits/ARTraits.ts +103 -0
  145. package/src/traits/EconomicPrimitives.ts +755 -0
  146. package/src/traits/EconomicTraits.ts +552 -0
  147. package/src/traits/IoTTraits.ts +102 -0
  148. package/src/traits/SimulationLabPrimitives.ts +650 -0
  149. package/src/traits/SimulationLabTraits.ts +191 -0
  150. package/src/traits/VRRTraits.ts +326 -0
  151. package/src/traits/__tests__/ARTraits.test.ts +14 -0
  152. package/src/traits/__tests__/EconomicPrimitives.test.ts +14 -0
  153. package/src/traits/__tests__/EconomicTraits.test.ts +14 -0
  154. package/src/types.ts +47 -12
  155. package/std_error.log +5 -0
  156. package/tsup.config.ts +17 -0
  157. package/vitest.config.ts +10 -0
  158. package/dist/types.js +0 -198
  159. package/dist/types.js.map +0 -1
@@ -0,0 +1,333 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ Vec3,
4
+ Quaternion,
5
+ Transform,
6
+ Ray,
7
+ AABB,
8
+ distance,
9
+ lerp,
10
+ clamp,
11
+ degToRad,
12
+ radToDeg,
13
+ } from '../spatial.js';
14
+
15
+ // =============================================================================
16
+ // Vec3
17
+ // =============================================================================
18
+
19
+ describe('Vec3', () => {
20
+ describe('constructors', () => {
21
+ it('should default to zero', () => {
22
+ const v = new Vec3();
23
+ expect(v.x).toBe(0);
24
+ expect(v.y).toBe(0);
25
+ expect(v.z).toBe(0);
26
+ });
27
+
28
+ it('should create from values', () => {
29
+ const v = new Vec3(1, 2, 3);
30
+ expect(v.x).toBe(1);
31
+ expect(v.y).toBe(2);
32
+ expect(v.z).toBe(3);
33
+ });
34
+
35
+ it('static zero()', () => {
36
+ expect(Vec3.zero().equals(new Vec3(0, 0, 0))).toBe(true);
37
+ });
38
+
39
+ it('static one()', () => {
40
+ expect(Vec3.one().equals(new Vec3(1, 1, 1))).toBe(true);
41
+ });
42
+
43
+ it('static up()', () => {
44
+ expect(Vec3.up().y).toBe(1);
45
+ });
46
+
47
+ it('static forward()', () => {
48
+ expect(Vec3.forward().z).toBe(-1);
49
+ });
50
+
51
+ it('static right()', () => {
52
+ expect(Vec3.right().x).toBe(1);
53
+ });
54
+ });
55
+
56
+ describe('arithmetic', () => {
57
+ it('add', () => {
58
+ const r = new Vec3(1, 2, 3).add(new Vec3(4, 5, 6));
59
+ expect(r.equals(new Vec3(5, 7, 9))).toBe(true);
60
+ });
61
+
62
+ it('sub', () => {
63
+ const r = new Vec3(5, 7, 9).sub(new Vec3(4, 5, 6));
64
+ expect(r.equals(new Vec3(1, 2, 3))).toBe(true);
65
+ });
66
+
67
+ it('mul', () => {
68
+ const r = new Vec3(1, 2, 3).mul(2);
69
+ expect(r.equals(new Vec3(2, 4, 6))).toBe(true);
70
+ });
71
+
72
+ it('div', () => {
73
+ const r = new Vec3(4, 6, 8).div(2);
74
+ expect(r.equals(new Vec3(2, 3, 4))).toBe(true);
75
+ });
76
+ });
77
+
78
+ describe('vector operations', () => {
79
+ it('dot product', () => {
80
+ expect(new Vec3(1, 0, 0).dot(new Vec3(0, 1, 0))).toBe(0);
81
+ expect(new Vec3(1, 0, 0).dot(new Vec3(1, 0, 0))).toBe(1);
82
+ });
83
+
84
+ it('cross product', () => {
85
+ const r = new Vec3(1, 0, 0).cross(new Vec3(0, 1, 0));
86
+ expect(r.equals(new Vec3(0, 0, 1))).toBe(true);
87
+ });
88
+
89
+ it('length', () => {
90
+ expect(new Vec3(3, 4, 0).length()).toBe(5);
91
+ });
92
+
93
+ it('lengthSquared', () => {
94
+ expect(new Vec3(3, 4, 0).lengthSquared()).toBe(25);
95
+ });
96
+
97
+ it('normalize', () => {
98
+ const n = new Vec3(3, 0, 0).normalize();
99
+ expect(n.length()).toBeCloseTo(1);
100
+ expect(n.x).toBeCloseTo(1);
101
+ });
102
+
103
+ it('normalize zero returns zero', () => {
104
+ const n = Vec3.zero().normalize();
105
+ expect(n.length()).toBe(0);
106
+ });
107
+
108
+ it('distanceTo', () => {
109
+ expect(new Vec3(0, 0, 0).distanceTo(new Vec3(3, 4, 0))).toBe(5);
110
+ });
111
+
112
+ it('lerp', () => {
113
+ const r = new Vec3(0, 0, 0).lerp(new Vec3(10, 10, 10), 0.5);
114
+ expect(r.equals(new Vec3(5, 5, 5))).toBe(true);
115
+ });
116
+
117
+ it('lerp at 0 returns start', () => {
118
+ const a = new Vec3(1, 2, 3);
119
+ expect(a.lerp(new Vec3(10, 20, 30), 0).equals(a)).toBe(true);
120
+ });
121
+
122
+ it('lerp at 1 returns end', () => {
123
+ const b = new Vec3(10, 20, 30);
124
+ expect(new Vec3(1, 2, 3).lerp(b, 1).equals(b)).toBe(true);
125
+ });
126
+ });
127
+
128
+ describe('conversion', () => {
129
+ it('toArray', () => {
130
+ expect(new Vec3(1, 2, 3).toArray()).toEqual([1, 2, 3]);
131
+ });
132
+
133
+ it('fromArray', () => {
134
+ expect(Vec3.fromArray([4, 5, 6]).equals(new Vec3(4, 5, 6))).toBe(true);
135
+ });
136
+
137
+ it('fromArray handles short arrays', () => {
138
+ expect(Vec3.fromArray([1]).equals(new Vec3(1, 0, 0))).toBe(true);
139
+ });
140
+
141
+ it('toString', () => {
142
+ expect(new Vec3(1, 2, 3).toString()).toBe('Vec3(1, 2, 3)');
143
+ });
144
+ });
145
+
146
+ describe('equals', () => {
147
+ it('equal vectors', () => {
148
+ expect(new Vec3(1, 2, 3).equals(new Vec3(1, 2, 3))).toBe(true);
149
+ });
150
+
151
+ it('unequal vectors', () => {
152
+ expect(new Vec3(1, 2, 3).equals(new Vec3(1, 2, 4))).toBe(false);
153
+ });
154
+
155
+ it('epsilon comparison', () => {
156
+ expect(new Vec3(1, 2, 3.0000001).equals(new Vec3(1, 2, 3))).toBe(true);
157
+ });
158
+ });
159
+ });
160
+
161
+ // =============================================================================
162
+ // Quaternion
163
+ // =============================================================================
164
+
165
+ describe('Quaternion', () => {
166
+ it('identity', () => {
167
+ const q = Quaternion.identity();
168
+ expect(q.w).toBe(1);
169
+ expect(q.x).toBe(0);
170
+ });
171
+
172
+ it('fromEuler and toEuler roundtrip', () => {
173
+ const q = Quaternion.fromEuler(0.5, 0.3, 0.1);
174
+ const euler = q.toEuler();
175
+ expect(euler.x).toBeCloseTo(0.5, 3);
176
+ expect(euler.y).toBeCloseTo(0.3, 3);
177
+ expect(euler.z).toBeCloseTo(0.1, 3);
178
+ });
179
+
180
+ it('fromAxisAngle', () => {
181
+ const q = Quaternion.fromAxisAngle(Vec3.up(), Math.PI / 2);
182
+ const n = q.normalize();
183
+ expect(n.w).toBeCloseTo(Math.cos(Math.PI / 4));
184
+ });
185
+
186
+ it('multiply identity is no-op', () => {
187
+ const q = Quaternion.fromEuler(0.5, 0.3, 0.1);
188
+ const r = q.multiply(Quaternion.identity());
189
+ expect(r.x).toBeCloseTo(q.x);
190
+ expect(r.y).toBeCloseTo(q.y);
191
+ expect(r.z).toBeCloseTo(q.z);
192
+ expect(r.w).toBeCloseTo(q.w);
193
+ });
194
+
195
+ it('rotateVec3', () => {
196
+ const q = Quaternion.fromAxisAngle(Vec3.up(), Math.PI / 2);
197
+ const v = q.rotateVec3(new Vec3(1, 0, 0));
198
+ expect(v.x).toBeCloseTo(0, 3);
199
+ expect(v.z).toBeCloseTo(-1, 3);
200
+ });
201
+
202
+ it('slerp at 0 returns start', () => {
203
+ const a = Quaternion.identity();
204
+ const b = Quaternion.fromEuler(1, 0, 0);
205
+ const r = a.slerp(b, 0);
206
+ expect(r.w).toBeCloseTo(a.w);
207
+ });
208
+
209
+ it('slerp at 1 returns end', () => {
210
+ const a = Quaternion.identity();
211
+ const b = Quaternion.fromEuler(1, 0, 0);
212
+ const r = a.slerp(b, 1);
213
+ expect(r.x).toBeCloseTo(b.x, 3);
214
+ expect(r.w).toBeCloseTo(b.w, 3);
215
+ });
216
+
217
+ it('normalize preserves direction', () => {
218
+ const q = new Quaternion(0, 0, 0, 2);
219
+ const n = q.normalize();
220
+ expect(n.w).toBeCloseTo(1);
221
+ });
222
+ });
223
+
224
+ // =============================================================================
225
+ // Transform
226
+ // =============================================================================
227
+
228
+ describe('Transform', () => {
229
+ it('identity does nothing', () => {
230
+ const t = Transform.identity();
231
+ const p = t.transformPoint(new Vec3(1, 2, 3));
232
+ expect(p.equals(new Vec3(1, 2, 3))).toBe(true);
233
+ });
234
+
235
+ it('translation', () => {
236
+ const t = new Transform(new Vec3(10, 0, 0));
237
+ const p = t.transformPoint(Vec3.zero());
238
+ expect(p.equals(new Vec3(10, 0, 0))).toBe(true);
239
+ });
240
+
241
+ it('scale', () => {
242
+ const t = new Transform(Vec3.zero(), Quaternion.identity(), new Vec3(2, 2, 2));
243
+ const p = t.transformPoint(new Vec3(1, 1, 1));
244
+ expect(p.equals(new Vec3(2, 2, 2))).toBe(true);
245
+ });
246
+
247
+ it('transformDirection ignores position', () => {
248
+ const t = new Transform(new Vec3(100, 100, 100));
249
+ const d = t.transformDirection(new Vec3(1, 0, 0));
250
+ expect(d.equals(new Vec3(1, 0, 0))).toBe(true);
251
+ });
252
+ });
253
+
254
+ // =============================================================================
255
+ // Ray & AABB
256
+ // =============================================================================
257
+
258
+ describe('Ray', () => {
259
+ it('pointAt', () => {
260
+ const r = new Ray(Vec3.zero(), new Vec3(1, 0, 0));
261
+ expect(r.pointAt(5).equals(new Vec3(5, 0, 0))).toBe(true);
262
+ });
263
+ });
264
+
265
+ describe('AABB', () => {
266
+ const box = new AABB(new Vec3(-1, -1, -1), new Vec3(1, 1, 1));
267
+
268
+ it('contains point inside', () => {
269
+ expect(box.contains(Vec3.zero())).toBe(true);
270
+ });
271
+
272
+ it('does not contain point outside', () => {
273
+ expect(box.contains(new Vec3(2, 0, 0))).toBe(false);
274
+ });
275
+
276
+ it('intersects overlapping AABB', () => {
277
+ const other = new AABB(new Vec3(0, 0, 0), new Vec3(2, 2, 2));
278
+ expect(box.intersects(other)).toBe(true);
279
+ });
280
+
281
+ it('does not intersect non-overlapping AABB', () => {
282
+ const other = new AABB(new Vec3(5, 5, 5), new Vec3(6, 6, 6));
283
+ expect(box.intersects(other)).toBe(false);
284
+ });
285
+
286
+ it('center', () => {
287
+ expect(box.center().equals(Vec3.zero())).toBe(true);
288
+ });
289
+
290
+ it('size', () => {
291
+ expect(box.size().equals(new Vec3(2, 2, 2))).toBe(true);
292
+ });
293
+
294
+ it('ray intersection hit', () => {
295
+ const ray = new Ray(new Vec3(-5, 0, 0), new Vec3(1, 0, 0));
296
+ const t = box.intersectsRay(ray);
297
+ expect(t).not.toBeNull();
298
+ expect(t).toBeCloseTo(4);
299
+ });
300
+
301
+ it('ray intersection miss', () => {
302
+ const ray = new Ray(new Vec3(-5, 5, 0), new Vec3(1, 0, 0));
303
+ expect(box.intersectsRay(ray)).toBeNull();
304
+ });
305
+ });
306
+
307
+ // =============================================================================
308
+ // Utility functions
309
+ // =============================================================================
310
+
311
+ describe('utility functions', () => {
312
+ it('distance', () => {
313
+ expect(distance(Vec3.zero(), new Vec3(3, 4, 0))).toBe(5);
314
+ });
315
+
316
+ it('lerp', () => {
317
+ expect(lerp(0, 10, 0.5)).toBe(5);
318
+ });
319
+
320
+ it('clamp', () => {
321
+ expect(clamp(-5, 0, 10)).toBe(0);
322
+ expect(clamp(15, 0, 10)).toBe(10);
323
+ expect(clamp(5, 0, 10)).toBe(5);
324
+ });
325
+
326
+ it('degToRad', () => {
327
+ expect(degToRad(180)).toBeCloseTo(Math.PI);
328
+ });
329
+
330
+ it('radToDeg', () => {
331
+ expect(radToDeg(Math.PI)).toBeCloseTo(180);
332
+ });
333
+ });