@holoscript/std 2.1.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.
- package/dist/collections.d.ts +177 -0
- package/dist/collections.d.ts.map +1 -0
- package/dist/collections.js +720 -0
- package/dist/collections.js.map +1 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +177 -0
- package/dist/index.js.map +1 -0
- package/dist/math.d.ts +162 -0
- package/dist/math.d.ts.map +1 -0
- package/dist/math.js +539 -0
- package/dist/math.js.map +1 -0
- package/dist/string.d.ts +208 -0
- package/dist/string.d.ts.map +1 -0
- package/dist/string.js +443 -0
- package/dist/string.js.map +1 -0
- package/dist/time.d.ts +215 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +530 -0
- package/dist/time.js.map +1 -0
- package/dist/types.d.ts +193 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +198 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
- package/src/collections.ts +844 -0
- package/src/index.ts +324 -0
- package/src/math.ts +658 -0
- package/src/string.ts +499 -0
- package/src/time.ts +622 -0
- package/src/types.ts +376 -0
- package/tsconfig.json +18 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/std - Standard Library for HoloScript Plus
|
|
3
|
+
*
|
|
4
|
+
* Provides core types, math utilities, collections, string operations,
|
|
5
|
+
* and time management for HoloScript Plus programs.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```hsplus
|
|
9
|
+
* import { Vec3, List, sleep } from "@holoscript/std";
|
|
10
|
+
*
|
|
11
|
+
* let position = Vec3(0, 1, 0);
|
|
12
|
+
* let items = List.of(1, 2, 3).map(n => n * 2);
|
|
13
|
+
*
|
|
14
|
+
* async fn main() {
|
|
15
|
+
* await sleep(1000);
|
|
16
|
+
* print("Done!");
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// Re-export everything from types.js
|
|
22
|
+
export * from './types.js';
|
|
23
|
+
|
|
24
|
+
// Math utilities - export objects from math.ts
|
|
25
|
+
export {
|
|
26
|
+
// Constants
|
|
27
|
+
PI,
|
|
28
|
+
TAU,
|
|
29
|
+
HALF_PI,
|
|
30
|
+
EPSILON,
|
|
31
|
+
DEG_TO_RAD,
|
|
32
|
+
RAD_TO_DEG,
|
|
33
|
+
|
|
34
|
+
// Basic math functions
|
|
35
|
+
clamp,
|
|
36
|
+
lerp,
|
|
37
|
+
inverseLerp,
|
|
38
|
+
remap,
|
|
39
|
+
smoothstep,
|
|
40
|
+
smootherstep,
|
|
41
|
+
sign,
|
|
42
|
+
fract,
|
|
43
|
+
mod,
|
|
44
|
+
step,
|
|
45
|
+
degToRad,
|
|
46
|
+
radToDeg,
|
|
47
|
+
|
|
48
|
+
// Math utility objects (access methods like vec2Math.add(), vec3Math.cross(), etc.)
|
|
49
|
+
vec2Math,
|
|
50
|
+
vec3Math,
|
|
51
|
+
quatMath,
|
|
52
|
+
aabbMath,
|
|
53
|
+
noise,
|
|
54
|
+
random,
|
|
55
|
+
} from './math.js';
|
|
56
|
+
|
|
57
|
+
// Re-export with alternate names for convenience
|
|
58
|
+
export { degToRad as toRadians, radToDeg as toDegrees } from './math.js';
|
|
59
|
+
|
|
60
|
+
// Collections
|
|
61
|
+
export {
|
|
62
|
+
List,
|
|
63
|
+
HoloMap,
|
|
64
|
+
HoloSet,
|
|
65
|
+
HoloMap as Map,
|
|
66
|
+
HoloSet as Set,
|
|
67
|
+
SpatialGrid,
|
|
68
|
+
PriorityQueue,
|
|
69
|
+
} from './collections.js';
|
|
70
|
+
|
|
71
|
+
// String utilities
|
|
72
|
+
export {
|
|
73
|
+
isBlank,
|
|
74
|
+
isNotBlank,
|
|
75
|
+
capitalize,
|
|
76
|
+
titleCase,
|
|
77
|
+
camelCase,
|
|
78
|
+
pascalCase,
|
|
79
|
+
snakeCase,
|
|
80
|
+
kebabCase,
|
|
81
|
+
constantCase,
|
|
82
|
+
padLeft,
|
|
83
|
+
padRight,
|
|
84
|
+
center,
|
|
85
|
+
truncate,
|
|
86
|
+
truncateMiddle,
|
|
87
|
+
repeat,
|
|
88
|
+
reverse,
|
|
89
|
+
count,
|
|
90
|
+
containsIgnoreCase,
|
|
91
|
+
startsWithIgnoreCase,
|
|
92
|
+
endsWithIgnoreCase,
|
|
93
|
+
removeWhitespace,
|
|
94
|
+
collapseWhitespace,
|
|
95
|
+
removePrefix,
|
|
96
|
+
removeSuffix,
|
|
97
|
+
wrap as wrapString,
|
|
98
|
+
unwrap,
|
|
99
|
+
lines,
|
|
100
|
+
words,
|
|
101
|
+
chars,
|
|
102
|
+
join,
|
|
103
|
+
format,
|
|
104
|
+
formatNumber,
|
|
105
|
+
numberWithCommas,
|
|
106
|
+
formatBytes,
|
|
107
|
+
formatDuration,
|
|
108
|
+
escapeHtml,
|
|
109
|
+
unescapeHtml,
|
|
110
|
+
escapeRegex,
|
|
111
|
+
slugify,
|
|
112
|
+
isValidIdentifier,
|
|
113
|
+
isNumeric,
|
|
114
|
+
isAlphanumeric,
|
|
115
|
+
isAlpha,
|
|
116
|
+
randomString,
|
|
117
|
+
uuid,
|
|
118
|
+
indent,
|
|
119
|
+
dedent,
|
|
120
|
+
wordWrap,
|
|
121
|
+
levenshtein,
|
|
122
|
+
similarity,
|
|
123
|
+
} from './string.js';
|
|
124
|
+
|
|
125
|
+
// Time utilities
|
|
126
|
+
export {
|
|
127
|
+
now,
|
|
128
|
+
hrTime,
|
|
129
|
+
sleep,
|
|
130
|
+
waitUntil,
|
|
131
|
+
withTimeout,
|
|
132
|
+
retry,
|
|
133
|
+
debounce,
|
|
134
|
+
throttle,
|
|
135
|
+
measure,
|
|
136
|
+
timed,
|
|
137
|
+
Stopwatch,
|
|
138
|
+
IntervalTimer,
|
|
139
|
+
CountdownTimer,
|
|
140
|
+
FrameTimer,
|
|
141
|
+
schedule,
|
|
142
|
+
scheduleInterval,
|
|
143
|
+
scheduleFrame,
|
|
144
|
+
createTicker,
|
|
145
|
+
DateTime,
|
|
146
|
+
} from './time.js';
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Print to console (HoloScript standard output)
|
|
150
|
+
*/
|
|
151
|
+
export function print(...args: unknown[]): void {
|
|
152
|
+
console.log(...args);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Print error to console
|
|
157
|
+
*/
|
|
158
|
+
export function printError(...args: unknown[]): void {
|
|
159
|
+
console.error(...args);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Print warning to console
|
|
164
|
+
*/
|
|
165
|
+
export function printWarn(...args: unknown[]): void {
|
|
166
|
+
console.warn(...args);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Assert a condition is true
|
|
171
|
+
*/
|
|
172
|
+
export function assert(condition: boolean, message?: string): asserts condition {
|
|
173
|
+
if (!condition) {
|
|
174
|
+
throw new Error(message ?? 'Assertion failed');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Assert a value is not null or undefined
|
|
180
|
+
*/
|
|
181
|
+
export function assertDefined<T>(value: T | null | undefined, message?: string): asserts value is T {
|
|
182
|
+
if (value === null || value === undefined) {
|
|
183
|
+
throw new Error(message ?? 'Value is null or undefined');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Unreachable code marker (for exhaustiveness checking)
|
|
189
|
+
*/
|
|
190
|
+
export function unreachable(message?: string): never {
|
|
191
|
+
throw new Error(message ?? 'Unreachable code reached');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Todo marker (throws at runtime)
|
|
196
|
+
*/
|
|
197
|
+
export function todo(message?: string): never {
|
|
198
|
+
throw new Error(`TODO: ${message ?? 'Not implemented'}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Deep clone an object
|
|
203
|
+
*/
|
|
204
|
+
export function clone<T>(value: T): T {
|
|
205
|
+
if (value === null || typeof value !== 'object') {
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (Array.isArray(value)) {
|
|
210
|
+
return value.map(clone) as T;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (value instanceof Date) {
|
|
214
|
+
return new Date(value.getTime()) as T;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (value instanceof Map) {
|
|
218
|
+
return new Map([...value].map(([k, v]) => [clone(k), clone(v)])) as T;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (value instanceof Set) {
|
|
222
|
+
return new Set([...value].map(clone)) as T;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const result: Record<string, unknown> = {};
|
|
226
|
+
for (const key in value) {
|
|
227
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
228
|
+
result[key] = clone((value as Record<string, unknown>)[key]);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return result as T;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Deep equality check
|
|
236
|
+
*/
|
|
237
|
+
export function equals(a: unknown, b: unknown): boolean {
|
|
238
|
+
if (a === b) return true;
|
|
239
|
+
if (a === null || b === null) return false;
|
|
240
|
+
if (typeof a !== typeof b) return false;
|
|
241
|
+
|
|
242
|
+
if (typeof a !== 'object') return false;
|
|
243
|
+
|
|
244
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
245
|
+
if (a.length !== b.length) return false;
|
|
246
|
+
return a.every((item, i) => equals(item, b[i]));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (a instanceof Date && b instanceof Date) {
|
|
250
|
+
return a.getTime() === b.getTime();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (a instanceof Map && b instanceof Map) {
|
|
254
|
+
if (a.size !== b.size) return false;
|
|
255
|
+
for (const [key, value] of a) {
|
|
256
|
+
if (!b.has(key) || !equals(value, b.get(key))) return false;
|
|
257
|
+
}
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (a instanceof Set && b instanceof Set) {
|
|
262
|
+
if (a.size !== b.size) return false;
|
|
263
|
+
for (const value of a) {
|
|
264
|
+
if (!b.has(value)) return false;
|
|
265
|
+
}
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const keysA = Object.keys(a as object);
|
|
270
|
+
const keysB = Object.keys(b as object);
|
|
271
|
+
if (keysA.length !== keysB.length) return false;
|
|
272
|
+
|
|
273
|
+
return keysA.every((key) =>
|
|
274
|
+
equals((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Pipe a value through a series of functions
|
|
280
|
+
*/
|
|
281
|
+
export function pipe<A>(value: A): A;
|
|
282
|
+
export function pipe<A, B>(value: A, fn1: (a: A) => B): B;
|
|
283
|
+
export function pipe<A, B, C>(value: A, fn1: (a: A) => B, fn2: (b: B) => C): C;
|
|
284
|
+
export function pipe<A, B, C, D>(value: A, fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D): D;
|
|
285
|
+
export function pipe<A, B, C, D, E>(
|
|
286
|
+
value: A,
|
|
287
|
+
fn1: (a: A) => B,
|
|
288
|
+
fn2: (b: B) => C,
|
|
289
|
+
fn3: (c: C) => D,
|
|
290
|
+
fn4: (d: D) => E
|
|
291
|
+
): E;
|
|
292
|
+
export function pipe(value: unknown, ...fns: ((x: unknown) => unknown)[]): unknown {
|
|
293
|
+
return fns.reduce((acc, fn) => fn(acc), value);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Compose functions right to left
|
|
298
|
+
*/
|
|
299
|
+
export function compose<A>(): (a: A) => A;
|
|
300
|
+
export function compose<A, B>(fn1: (a: A) => B): (a: A) => B;
|
|
301
|
+
export function compose<A, B, C>(fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => C;
|
|
302
|
+
export function compose<A, B, C, D>(fn3: (c: C) => D, fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => D;
|
|
303
|
+
export function compose(...fns: ((x: unknown) => unknown)[]): (x: unknown) => unknown {
|
|
304
|
+
return (value: unknown) => fns.reduceRight((acc, fn) => fn(acc), value);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Identity function
|
|
309
|
+
*/
|
|
310
|
+
export function identity<T>(value: T): T {
|
|
311
|
+
return value;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* No-operation function
|
|
316
|
+
*/
|
|
317
|
+
export function noop(): void {}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Create a constant function
|
|
321
|
+
*/
|
|
322
|
+
export function constant<T>(value: T): () => T {
|
|
323
|
+
return () => value;
|
|
324
|
+
}
|