1use crate::runtime::host::{abi_arg, abi_result};
7use wasmtime::{FuncType, HeapType, Linker, RefType, StructType, Val, ValType};
8
9use crate::runtime::StoreData;
10use crate::runtime::fuel;
11use crate::runtime::host::{
12 intrinsic_array_type, intrinsic_string_type, intrinsic_uint8_array_type, register_host_fn,
13 register_host_fn_async, write_submilli_string_struct, write_submilli_string_struct_units,
14};
15use crate::runtime::intrinsic_types::{IntrinsicTypes, build_intrinsic_types, intrinsic_types};
16use crate::runtime::prelude::vtable::read_string_units;
17use crate::runtime::prelude::{MODULE_NAME, closure, declare_method};
18use crate::{MangledName, PackageDeclaration, Param, Type};
19
20fn method_key(method: &str) -> MangledName {
22 crate::mangle::extend(&crate::mangle::prelude("Uint8Array"), method)
23}
24
25fn ctor_key(method: &str) -> MangledName {
27 crate::mangle::extend(&crate::mangle::prelude("Uint8ArrayConstructor"), method)
28}
29
30fn ref_to(struct_ty: StructType) -> ValType {
31 ValType::Ref(RefType::new(false, HeapType::ConcreteStruct(struct_ty)))
32}
33
34fn object_ref(intr: &IntrinsicTypes) -> ValType {
37 ValType::Ref(RefType::new(
38 true,
39 HeapType::ConcreteStruct(intr.object.clone()),
40 ))
41}
42
43fn f64v(v: &Val) -> f64 {
44 match v {
45 Val::F64(bits) => f64::from_bits(*bits),
46 _ => f64::NAN,
47 }
48}
49
50fn string_val(caller: &mut wasmtime::Caller<'_, StoreData>, s: &str) -> wasmtime::Result<Val> {
51 let st = write_submilli_string_struct(caller, s)?;
52 Ok(Val::AnyRef(Some(st.to_anyref())))
53}
54
55#[allow(clippy::too_many_lines)]
56pub fn install(linker: &mut Linker<StoreData>) -> wasmtime::Result<()> {
57 let engine = linker.engine().clone();
58 let intr = build_intrinsic_types(&engine)?;
59 let uint8 = ref_to(intrinsic_uint8_array_type(&engine)?);
60 let string = ref_to(intrinsic_string_type(&engine)?);
61 let array = ref_to(intrinsic_array_type(&engine)?);
62 let obj = object_ref(&intr);
63 let num = ValType::F64;
64 let boolean = ValType::I32;
65 let callback = obj.clone();
67
68 let ft = |params: Vec<ValType>, results: Vec<ValType>| FuncType::new(&engine, params, results);
69
70 register_host_fn(
72 linker,
73 MODULE_NAME,
74 method_key("length"),
75 ft(vec![uint8.clone()], vec![num.clone()]),
76 true,
77 |caller, params, results| {
78 *abi_result(results, 0)? = Val::F64(
79 super::length(caller, abi_arg(params, 0)?, "Uint8Array#length")?.to_bits(),
80 );
81 Ok(())
82 },
83 )?;
84 register_host_fn(
85 linker,
86 MODULE_NAME,
87 method_key("byteLength"),
88 ft(vec![uint8.clone()], vec![num.clone()]),
89 true,
90 |caller, params, results| {
91 *abi_result(results, 0)? = Val::F64(
92 super::length(caller, abi_arg(params, 0)?, "Uint8Array#byteLength")?.to_bits(),
93 );
94 Ok(())
95 },
96 )?;
97 register_host_fn(
98 linker,
99 MODULE_NAME,
100 method_key("at"),
101 ft(vec![uint8.clone(), num.clone()], vec![obj.clone()]),
102 true,
103 |caller, params, results| {
104 *abi_result(results, 0)? = super::at(
105 caller,
106 abi_arg(params, 0)?,
107 f64v(abi_arg(params, 1)?),
108 "Uint8Array#at",
109 )?;
110 Ok(())
111 },
112 )?;
113 for name in ["slice", "subarray"] {
114 register_host_fn(
115 linker,
116 MODULE_NAME,
117 method_key(name),
118 ft(
119 vec![uint8.clone(), num.clone(), num.clone()],
120 vec![uint8.clone()],
121 ),
122 true,
123 |caller, params, results| {
124 let out = super::slice(
125 caller,
126 abi_arg(params, 0)?,
127 f64v(abi_arg(params, 1)?),
128 f64v(abi_arg(params, 2)?),
129 "Uint8Array#slice",
130 )?;
131 *abi_result(results, 0)? = super::build(caller, &out)?;
132 Ok(())
133 },
134 )?;
135 }
136 register_host_fn(
137 linker,
138 MODULE_NAME,
139 method_key("with"),
140 ft(
141 vec![uint8.clone(), num.clone(), num.clone()],
142 vec![uint8.clone()],
143 ),
144 true,
145 |caller, params, results| {
146 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#with")?;
147 match super::with(&bytes, f64v(abi_arg(params, 1)?), f64v(abi_arg(params, 2)?)) {
148 Some(out) => {
149 *abi_result(results, 0)? = super::build(caller, &out)?;
150 Ok(())
151 }
152 None => Err(crate::runtime::host::range_error("index out of range")),
153 }
154 },
155 )?;
156 for name in ["indexOf", "lastIndexOf"] {
157 let last = name == "lastIndexOf";
158 register_host_fn(
159 linker,
160 MODULE_NAME,
161 method_key(name),
162 ft(
163 vec![uint8.clone(), num.clone(), num.clone()],
164 vec![num.clone()],
165 ),
166 true,
167 move |caller, params, results| {
168 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#indexOf")?;
169 let r = if last {
170 super::last_index_of(
171 &bytes,
172 f64v(abi_arg(params, 1)?),
173 f64v(abi_arg(params, 2)?),
174 )
175 } else {
176 super::index_of(&bytes, f64v(abi_arg(params, 1)?), f64v(abi_arg(params, 2)?))
177 };
178 *abi_result(results, 0)? = Val::F64(r.to_bits());
179 Ok(())
180 },
181 )?;
182 }
183 register_host_fn(
184 linker,
185 MODULE_NAME,
186 method_key("includes"),
187 ft(
188 vec![uint8.clone(), num.clone(), num.clone()],
189 vec![boolean.clone()],
190 ),
191 true,
192 |caller, params, results| {
193 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#includes")?;
194 let r = super::includes(&bytes, f64v(abi_arg(params, 1)?), f64v(abi_arg(params, 2)?));
195 *abi_result(results, 0)? = Val::I32(i32::from(r));
196 Ok(())
197 },
198 )?;
199 register_host_fn(
200 linker,
201 MODULE_NAME,
202 method_key("join"),
203 ft(vec![uint8.clone(), string.clone()], vec![string.clone()]),
204 true,
205 |caller, params, results| {
206 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#join")?;
207 let sep = read_string_units(caller, abi_arg(params, 1)?, "Uint8Array#join separator")?;
208 let out = super::join(&bytes, &sep);
209 *abi_result(results, 0)? = {
210 let st = write_submilli_string_struct_units(caller, &out)?;
211 Val::AnyRef(Some(st.to_anyref()))
212 };
213 Ok(())
214 },
215 )?;
216 register_host_fn(
217 linker,
218 MODULE_NAME,
219 method_key("toString"),
220 ft(vec![uint8.clone()], vec![string.clone()]),
221 true,
222 |caller, params, results| {
223 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toString")?;
224 let out = super::join(&bytes, &[u16::from(b',')]);
225 *abi_result(results, 0)? = {
226 let st = write_submilli_string_struct_units(caller, &out)?;
227 Val::AnyRef(Some(st.to_anyref()))
228 };
229 Ok(())
230 },
231 )?;
232 register_host_fn(
233 linker,
234 MODULE_NAME,
235 method_key("toJson"),
236 ft(vec![uint8.clone()], vec![string.clone()]),
237 true,
238 |caller, params, results| {
239 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toJson")?;
240 let json = format!("\"{}\"", super::to_base64_standard(&bytes));
241 *abi_result(results, 0)? = string_val(caller, &json)?;
242 Ok(())
243 },
244 )?;
245 register_host_fn(
246 linker,
247 MODULE_NAME,
248 method_key("toHex"),
249 ft(vec![uint8.clone()], vec![string.clone()]),
250 true,
251 |caller, params, results| {
252 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toHex")?;
253 *abi_result(results, 0)? = string_val(caller, &super::to_hex(&bytes))?;
254 Ok(())
255 },
256 )?;
257 register_host_fn(
258 linker,
259 MODULE_NAME,
260 method_key("toBase64"),
261 ft(vec![uint8.clone(), obj.clone()], vec![string.clone()]),
262 true,
263 |caller, params, results| {
264 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toBase64")?;
265 let (url_safe, omit) = super::read_base64_options(caller, abi_arg(params, 1)?)?;
266 fuel::charge(&mut *caller, fuel::SCAN, bytes.len() as u64)?;
267 *abi_result(results, 0)? =
268 string_val(caller, &super::encode_base64(&bytes, url_safe, omit))?;
269 Ok(())
270 },
271 )?;
272 register_host_fn(
273 linker,
274 MODULE_NAME,
275 method_key("equals"),
276 ft(vec![uint8.clone(), uint8.clone()], vec![boolean.clone()]),
277 true,
278 |caller, params, results| {
279 let a = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#equals")?;
280 let b = super::read_bytes(caller, abi_arg(params, 1)?, "Uint8Array#equals")?;
281 *abi_result(results, 0)? = Val::I32(i32::from(super::equals(&a, &b)));
282 Ok(())
283 },
284 )?;
285
286 register_host_fn(
288 linker,
289 MODULE_NAME,
290 method_key("reverse"),
291 ft(vec![uint8.clone()], vec![uint8.clone()]),
292 true,
293 |caller, params, results| {
294 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#reverse")?;
295 *abi_result(results, 0)? = super::reverse(caller, abi_arg(params, 0)?, bytes)?;
296 Ok(())
297 },
298 )?;
299 register_host_fn(
300 linker,
301 MODULE_NAME,
302 method_key("fill"),
303 ft(
304 vec![uint8.clone(), num.clone(), num.clone(), num.clone()],
305 vec![uint8.clone()],
306 ),
307 true,
308 |caller, params, results| {
309 *abi_result(results, 0)? = super::fill(
310 caller,
311 abi_arg(params, 0)?,
312 f64v(abi_arg(params, 1)?),
313 f64v(abi_arg(params, 2)?),
314 f64v(abi_arg(params, 3)?),
315 )?;
316 Ok(())
317 },
318 )?;
319 register_host_fn(
320 linker,
321 MODULE_NAME,
322 method_key("copyWithin"),
323 ft(
324 vec![uint8.clone(), num.clone(), num.clone(), num.clone()],
325 vec![uint8.clone()],
326 ),
327 true,
328 |caller, params, results| {
329 *abi_result(results, 0)? = super::copy_within(
330 caller,
331 abi_arg(params, 0)?,
332 f64v(abi_arg(params, 1)?),
333 f64v(abi_arg(params, 2)?),
334 f64v(abi_arg(params, 3)?),
335 )?;
336 Ok(())
337 },
338 )?;
339 register_host_fn(
340 linker,
341 MODULE_NAME,
342 method_key("set"),
343 ft(vec![uint8.clone(), uint8.clone(), num.clone()], vec![]),
344 true,
345 |caller, params, _results| {
346 super::set(
347 caller,
348 abi_arg(params, 0)?,
349 abi_arg(params, 1)?,
350 f64v(abi_arg(params, 2)?),
351 )
352 },
353 )?;
354 register_host_fn_async(
355 linker,
356 MODULE_NAME,
357 method_key("sort"),
358 ft(vec![uint8.clone(), obj.clone()], vec![uint8.clone()]),
359 true,
360 |caller, params, results| {
361 Box::pin(async move {
362 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#sort")?;
363 let cmp =
364 read_comparator(caller, abi_arg(params, 1)?, "Uint8Array#sort comparator")?;
365 *abi_result(results, 0)? =
366 super::sort(caller, abi_arg(params, 0)?, bytes, cmp).await?;
367 Ok(())
368 })
369 },
370 )?;
371
372 register_host_fn(
374 linker,
375 MODULE_NAME,
376 method_key("toReversed"),
377 ft(vec![uint8.clone()], vec![uint8.clone()]),
378 true,
379 |caller, params, results| {
380 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toReversed")?;
381 let out = super::to_reversed(bytes);
382 *abi_result(results, 0)? = super::build(caller, &out)?;
383 Ok(())
384 },
385 )?;
386 register_host_fn_async(
387 linker,
388 MODULE_NAME,
389 method_key("toSorted"),
390 ft(vec![uint8.clone(), obj.clone()], vec![uint8.clone()]),
391 true,
392 |caller, params, results| {
393 Box::pin(async move {
394 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#toSorted")?;
395 let cmp = read_comparator(
396 caller,
397 abi_arg(params, 1)?,
398 "Uint8Array#toSorted comparator",
399 )?;
400 let out = super::to_sorted(caller, bytes, cmp).await?;
401 *abi_result(results, 0)? = super::build(caller, &out)?;
402 Ok(())
403 })
404 },
405 )?;
406
407 register_host_fn_async(
409 linker,
410 MODULE_NAME,
411 method_key("forEach"),
412 ft(vec![uint8.clone(), callback.clone()], vec![]),
413 true,
414 |caller, params, _results| {
415 Box::pin(async move {
416 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#forEach")?;
417 let f = closure::read_callback(
418 caller,
419 abi_arg(params, 1)?,
420 "Uint8Array#forEach callback",
421 )?;
422 super::for_each(caller, *abi_arg(params, 0)?, bytes, &f).await
423 })
424 },
425 )?;
426 register_host_fn_async(
427 linker,
428 MODULE_NAME,
429 method_key("map"),
430 ft(vec![uint8.clone(), callback.clone()], vec![uint8.clone()]),
431 true,
432 |caller, params, results| {
433 Box::pin(async move {
434 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#map")?;
435 let f =
436 closure::read_callback(caller, abi_arg(params, 1)?, "Uint8Array#map callback")?;
437 let out = super::map(caller, *abi_arg(params, 0)?, bytes, &f).await?;
438 *abi_result(results, 0)? = super::build(caller, &out)?;
439 Ok(())
440 })
441 },
442 )?;
443 register_host_fn_async(
444 linker,
445 MODULE_NAME,
446 method_key("filter"),
447 ft(vec![uint8.clone(), callback.clone()], vec![uint8.clone()]),
448 true,
449 |caller, params, results| {
450 Box::pin(async move {
451 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#filter")?;
452 let pred = closure::read_callback(
453 caller,
454 abi_arg(params, 1)?,
455 "Uint8Array#filter predicate",
456 )?;
457 let out = super::filter(caller, *abi_arg(params, 0)?, bytes, &pred).await?;
458 *abi_result(results, 0)? = super::build(caller, &out)?;
459 Ok(())
460 })
461 },
462 )?;
463 for (name, reverse) in [("reduce", false), ("reduceRight", true)] {
464 register_host_fn_async(
465 linker,
466 MODULE_NAME,
467 method_key(name),
468 ft(
469 vec![uint8.clone(), callback.clone(), obj.clone()],
470 vec![obj.clone()],
471 ),
472 true,
473 move |caller, params, results| {
474 Box::pin(async move {
475 let bytes =
476 super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#reduce")?;
477 let f = closure::read_callback(
478 caller,
479 abi_arg(params, 1)?,
480 "Uint8Array#reduce callback",
481 )?;
482 *abi_result(results, 0)? = super::reduce(
483 caller,
484 *abi_arg(params, 0)?,
485 bytes,
486 &f,
487 *abi_arg(params, 2)?,
488 reverse,
489 )
490 .await?;
491 Ok(())
492 })
493 },
494 )?;
495 }
496 for (name, reverse) in [("find", false), ("findLast", true)] {
497 register_host_fn_async(
498 linker,
499 MODULE_NAME,
500 method_key(name),
501 ft(vec![uint8.clone(), callback.clone()], vec![obj.clone()]),
502 true,
503 move |caller, params, results| {
504 Box::pin(async move {
505 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#find")?;
506 let pred = closure::read_callback(
507 caller,
508 abi_arg(params, 1)?,
509 "Uint8Array#find predicate",
510 )?;
511 *abi_result(results, 0)? = match super::find_match(
512 caller,
513 *abi_arg(params, 0)?,
514 &bytes,
515 &pred,
516 reverse,
517 )
518 .await?
519 {
520 Some(i) => {
521 let byte = *bytes.get(i).ok_or_else(|| {
522 crate::runtime::host::fatal_host_error(
523 "Uint8Array#find: invalid result index",
524 )
525 })?;
526 super::box_byte(caller, byte)?
527 }
528 None => crate::runtime::prelude::undefined::value(caller)?,
529 };
530 Ok(())
531 })
532 },
533 )?;
534 }
535 for (name, reverse) in [("findIndex", false), ("findLastIndex", true)] {
536 register_host_fn_async(
537 linker,
538 MODULE_NAME,
539 method_key(name),
540 ft(vec![uint8.clone(), callback.clone()], vec![num.clone()]),
541 true,
542 move |caller, params, results| {
543 Box::pin(async move {
544 let bytes =
545 super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#findIndex")?;
546 let pred = closure::read_callback(
547 caller,
548 abi_arg(params, 1)?,
549 "Uint8Array#findIndex predicate",
550 )?;
551 let idx =
552 super::find_match(caller, *abi_arg(params, 0)?, &bytes, &pred, reverse)
553 .await?;
554 let r = idx.map_or(-1.0, |i| i as f64);
555 *abi_result(results, 0)? = Val::F64(r.to_bits());
556 Ok(())
557 })
558 },
559 )?;
560 }
561 register_host_fn_async(
562 linker,
563 MODULE_NAME,
564 method_key("some"),
565 ft(vec![uint8.clone(), callback.clone()], vec![boolean.clone()]),
566 true,
567 |caller, params, results| {
568 Box::pin(async move {
569 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#some")?;
570 let pred = closure::read_callback(
571 caller,
572 abi_arg(params, 1)?,
573 "Uint8Array#some predicate",
574 )?;
575 let r = super::some(caller, *abi_arg(params, 0)?, bytes, &pred).await?;
576 *abi_result(results, 0)? = Val::I32(i32::from(r));
577 Ok(())
578 })
579 },
580 )?;
581 register_host_fn_async(
582 linker,
583 MODULE_NAME,
584 method_key("every"),
585 ft(vec![uint8.clone(), callback.clone()], vec![boolean.clone()]),
586 true,
587 |caller, params, results| {
588 Box::pin(async move {
589 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array#every")?;
590 let pred = closure::read_callback(
591 caller,
592 abi_arg(params, 1)?,
593 "Uint8Array#every predicate",
594 )?;
595 let r = super::every(caller, *abi_arg(params, 0)?, bytes, &pred).await?;
596 *abi_result(results, 0)? = Val::I32(i32::from(r));
597 Ok(())
598 })
599 },
600 )?;
601
602 for (name, label) in [
604 ("fromArray", "Uint8Array.fromArray"),
605 ("of", "Uint8Array.of"),
606 ] {
607 register_host_fn(
608 linker,
609 MODULE_NAME,
610 ctor_key(name),
611 ft(vec![array.clone()], vec![uint8.clone()]),
612 true,
613 move |caller, params, results| {
614 let bytes = super::read_number_array(caller, abi_arg(params, 0)?, label)?;
615 *abi_result(results, 0)? = super::build(caller, &bytes)?;
616 Ok(())
617 },
618 )?;
619 }
620 let object_nonnull = ValType::Ref(RefType::new(
625 false,
626 HeapType::ConcreteStruct(intr.object.clone()),
627 ));
628 register_host_fn(
629 linker,
630 MODULE_NAME,
631 ctor_key("new"),
632 ft(vec![object_nonnull], vec![uint8.clone()]),
633 true,
634 |caller, params, results| {
635 let intr = intrinsic_types(&mut *caller)?;
636 let bytes = if crate::runtime::prelude::collection::is_a(
637 caller,
638 abi_arg(params, 0)?,
639 &intr.array,
640 )? {
641 super::read_number_array(caller, abi_arg(params, 0)?, "Uint8Array.new")?
642 } else {
643 let n = crate::runtime::host::read_boxed_number(
644 caller,
645 abi_arg(params, 0)?,
646 "Uint8Array.new",
647 )?;
648 *abi_result(results, 0)? = super::allocate(caller, super::alloc_len(n)?)?;
649 return Ok(());
650 };
651 *abi_result(results, 0)? = super::build(caller, &bytes)?;
652 Ok(())
653 },
654 )?;
655 register_host_fn(
656 linker,
657 MODULE_NAME,
658 ctor_key("alloc"),
659 ft(vec![num.clone()], vec![uint8.clone()]),
660 true,
661 |caller, params, results| {
662 let n = super::alloc_len(f64v(abi_arg(params, 0)?))?;
663 *abi_result(results, 0)? = super::allocate(caller, n)?;
664 Ok(())
665 },
666 )?;
667 register_host_fn(
668 linker,
669 MODULE_NAME,
670 ctor_key("fromBytes"),
671 ft(vec![uint8.clone()], vec![uint8.clone()]),
672 true,
673 |caller, params, results| {
674 let bytes = super::read_bytes(caller, abi_arg(params, 0)?, "Uint8Array.fromBytes")?;
675 *abi_result(results, 0)? = super::build(caller, &bytes)?;
676 Ok(())
677 },
678 )?;
679 register_host_fn(
680 linker,
681 MODULE_NAME,
682 ctor_key("fromBase64"),
683 ft(vec![string.clone(), obj.clone()], vec![uint8.clone()]),
684 true,
685 |caller, params, results| {
686 let units = read_string_units(caller, abi_arg(params, 0)?, "Uint8Array.fromBase64")?;
687 let s = String::from_utf16_lossy(&units);
688 let (url_safe, _) = super::read_base64_options(caller, abi_arg(params, 1)?)?;
689 fuel::charge(&mut *caller, fuel::SCAN, s.len() as u64)?;
690 let bytes = super::decode_base64(&s, url_safe)?;
691 *abi_result(results, 0)? = super::build(caller, &bytes)?;
692 Ok(())
693 },
694 )?;
695 register_host_fn(
696 linker,
697 MODULE_NAME,
698 ctor_key("fromHex"),
699 ft(vec![string.clone()], vec![uint8.clone()]),
700 true,
701 |caller, params, results| {
702 let units = read_string_units(caller, abi_arg(params, 0)?, "Uint8Array.fromHex")?;
703 let bytes = super::from_hex(&units)?;
704 *abi_result(results, 0)? = super::build(caller, &bytes)?;
705 Ok(())
706 },
707 )?;
708 Ok(())
709}
710
711fn read_comparator(
713 caller: &mut wasmtime::Caller<'_, StoreData>,
714 val: &Val,
715 name: &str,
716) -> wasmtime::Result<Option<closure::Closure>> {
717 if crate::runtime::prelude::undefined::is_undefined(caller, val)? {
718 Ok(None)
719 } else {
720 Ok(Some(closure::read_callback(caller, val, name)?))
721 }
722}
723
724fn byte_callback_params(leading: Vec<Type>) -> Vec<Type> {
728 leading
729 .into_iter()
730 .chain([Type::Number, Type::Number, Type::Uint8Array])
731 .collect()
732}
733
734pub fn declare(defs: &mut PackageDeclaration) {
735 let u8a = || Param::new("a", Type::Uint8Array);
736 let callback = || Param::new("f", Type::Unknown);
739 let n = |name: &str| Param::new(name, Type::Number);
740 let u8_ret = Type::Uint8Array;
741 let comparator = || {
742 Type::Union(vec![
743 Type::Function {
744 optional: 0,
745 params: vec![Type::Number, Type::Number],
746 ret: Box::new(Type::Number),
747 predicate: None,
748 has_rest: false,
749 },
750 Type::Undefined,
751 ])
752 };
753 let base64_options = || {
754 Type::Union(vec![
755 Type::prelude_interface("Base64Options".to_string(), Vec::new()),
756 Type::Undefined,
757 ])
758 };
759
760 let m = |defs: &mut PackageDeclaration, name: &str, params: Vec<Param>, ret: Type| {
761 declare_method(defs, name, method_key(name), params, ret);
762 };
763
764 m(defs, "length", vec![u8a()], Type::Number);
765 m(defs, "byteLength", vec![u8a()], Type::Number);
766 m(
767 defs,
768 "at",
769 vec![u8a(), n("index")],
770 Type::Union(vec![Type::Number, Type::Undefined]),
771 );
772 for name in ["slice", "subarray"] {
773 m(
774 defs,
775 name,
776 vec![u8a(), n("start"), n("end")],
777 u8_ret.clone(),
778 );
779 }
780 m(
781 defs,
782 "with",
783 vec![u8a(), n("index"), n("value")],
784 u8_ret.clone(),
785 );
786 for name in ["indexOf", "lastIndexOf"] {
787 m(
788 defs,
789 name,
790 vec![u8a(), n("value"), n("fromIndex")],
791 Type::Number,
792 );
793 }
794 m(
795 defs,
796 "includes",
797 vec![u8a(), n("value"), n("fromIndex")],
798 Type::Boolean,
799 );
800 m(
801 defs,
802 "join",
803 vec![u8a(), Param::new("sep", Type::String)],
804 Type::String,
805 );
806 m(defs, "toString", vec![u8a()], Type::String);
807 m(defs, "toJson", vec![u8a()], Type::String);
808 m(defs, "toHex", vec![u8a()], Type::String);
809 m(
810 defs,
811 "toBase64",
812 vec![u8a(), Param::new("options", base64_options())],
813 Type::String,
814 );
815 m(
816 defs,
817 "equals",
818 vec![u8a(), Param::new("other", Type::Uint8Array)],
819 Type::Boolean,
820 );
821
822 m(defs, "reverse", vec![u8a()], u8_ret.clone());
823 m(
824 defs,
825 "fill",
826 vec![u8a(), n("value"), n("start"), n("end")],
827 u8_ret.clone(),
828 );
829 m(
830 defs,
831 "copyWithin",
832 vec![u8a(), n("target"), n("start"), n("end")],
833 u8_ret.clone(),
834 );
835 m(
836 defs,
837 "set",
838 vec![u8a(), Param::new("source", Type::Uint8Array), n("offset")],
839 Type::Void,
840 );
841 m(
842 defs,
843 "sort",
844 vec![u8a(), Param::new("compareFn", comparator())],
845 u8_ret.clone(),
846 );
847 m(defs, "toReversed", vec![u8a()], u8_ret.clone());
848 m(
849 defs,
850 "toSorted",
851 vec![u8a(), Param::new("compareFn", comparator())],
852 u8_ret.clone(),
853 );
854
855 m(defs, "forEach", vec![u8a(), callback()], Type::Void);
856 for name in ["map", "filter"] {
857 m(defs, name, vec![u8a(), callback()], u8_ret.clone());
858 }
859 let u = || Type::TypeVar("U".to_string());
860 for name in ["reduce", "reduceRight"] {
861 m(
862 defs,
863 name,
864 vec![u8a(), callback(), Param::new("initial", u())],
865 u(),
866 );
867 }
868 for name in ["find", "findLast"] {
869 m(
870 defs,
871 name,
872 vec![u8a(), callback()],
873 Type::Union(vec![Type::Number, Type::Undefined]),
874 );
875 }
876 for name in ["findIndex", "findLastIndex"] {
877 m(defs, name, vec![u8a(), callback()], Type::Number);
878 }
879 for name in ["some", "every"] {
880 m(defs, name, vec![u8a(), callback()], Type::Boolean);
881 }
882
883 let items = || Param::new("items", Type::Array(Box::new(Type::Number)));
884 for name in ["fromArray", "of"] {
885 declare_method(defs, name, ctor_key(name), vec![items()], u8_ret.clone());
886 }
887 declare_method(
890 defs,
891 "new",
892 ctor_key("new"),
893 vec![Param::new(
894 "values",
895 Type::Union(vec![Type::Array(Box::new(Type::Number)), Type::Number]),
896 )],
897 u8_ret.clone(),
898 );
899 declare_method(
900 defs,
901 "alloc",
902 ctor_key("alloc"),
903 vec![Param::new("length", Type::Number)],
904 u8_ret.clone(),
905 );
906 declare_method(
907 defs,
908 "fromBytes",
909 ctor_key("fromBytes"),
910 vec![Param::new("bytes", Type::Uint8Array)],
911 u8_ret.clone(),
912 );
913 declare_method(
914 defs,
915 "fromBase64",
916 ctor_key("fromBase64"),
917 vec![
918 Param::new("encoded", Type::String),
919 Param::new("options", base64_options()),
920 ],
921 u8_ret.clone(),
922 );
923 declare_method(
924 defs,
925 "fromHex",
926 ctor_key("fromHex"),
927 vec![Param::new("encoded", Type::String)],
928 u8_ret,
929 );
930}
931
932#[allow(clippy::too_many_lines)]
935pub(crate) fn declare_types(defs: &mut crate::PackageDeclaration) {
936 use crate::runtime::prelude::declaration::doc;
937 use crate::{
938 Dispatch, MethodSig, Param, PropertySig, Span, Type, TypeKind, TypeSymbol, ValueKind,
939 ValueSymbol,
940 };
941 use std::collections::BTreeMap;
942 defs.types.insert(
943 "Uint8Array".to_string(),
944 TypeSymbol {
945 name: "Uint8Array".to_string(),
946 mangled_name: crate::mangle::prelude("Uint8Array"),
947 declaration_span: Span::at(crate::FileId::PRELUDE),
948 kind: TypeKind::Interface { index: None,
949 generics: Vec::new(),
950 methods: BTreeMap::from([
951 (
952 "toString".to_string(),
953 MethodSig {
954 optional: false,
955 generics: Vec::new(),
956 params: Vec::new(),
957 ret: Type::String,
958 predicate: None,
959 doc: doc(
960 "/** Returns this array's bytes joined as a comma-separated decimal string — e.g. `Uint8Array.new([1, 2, 3]).toString() === \"1,2,3\"`. Matches the JS `Uint8Array.prototype.toString` shape. */",
961 ),
962 },
963 ),
964 (
965 "toJson".to_string(),
966 MethodSig {
967 optional: false,
968 generics: Vec::new(),
969 params: Vec::new(),
970 ret: Type::String,
971 predicate: None,
972 doc: doc(
973 "/** Returns this array's bytes as a standard (padded) base64 string wrapped in `\"…\"` (the JSON string form). */",
974 ),
975 },
976 ),
977 (
978 "equals".to_string(),
979 MethodSig {
980 optional: false,
981 generics: Vec::new(),
982 params: vec![Param::new("other", Type::Uint8Array)],
983 ret: Type::Boolean,
984 predicate: None,
985 doc: doc(
986 "/**\n * Byte-by-byte equality with `other`. Returns `false` when lengths differ.\n * @param other Bytes to compare against.\n */",
987 ),
988 },
989 ),
990 (
991 "join".to_string(),
992 MethodSig {
993 optional: false,
994 generics: Vec::new(),
995 params: vec![Param::with_default(
996 "separator",
997 Type::String,
998 crate::DefaultValue::String(",".to_string()),
999 )],
1000 ret: Type::String,
1001 predicate: None,
1002 doc: doc(
1003 "/**\n * Returns this array's bytes formatted in decimal and concatenated with `separator` between adjacent pairs.\n * @param separator String placed between elements. Defaults to `\",\"`.\n */",
1004 ),
1005 },
1006 ),
1007 (
1008 "reverse".to_string(),
1009 MethodSig {
1010 optional: false,
1011 generics: Vec::new(),
1012 params: Vec::new(),
1013 ret: Type::Uint8Array,
1014 predicate: None,
1015 doc: doc(
1016 "/** Reverses this array's bytes in place and returns `this`. */",
1017 ),
1018 },
1019 ),
1020 (
1021 "fill".to_string(),
1022 MethodSig {
1023 optional: false,
1024 generics: Vec::new(),
1025 params: vec![
1026 Param::new("value", Type::Number),
1027 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1028 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1029 ],
1030 ret: Type::Uint8Array,
1031 predicate: None,
1032 doc: doc("/** Converts `value` to a byte and writes it to every position in `[start, end)`. Returns `this`. */"),
1033 },
1034 ),
1035 (
1036 "copyWithin".to_string(),
1037 MethodSig {
1038 optional: false,
1039 generics: Vec::new(),
1040 params: vec![
1041 Param::new("target", Type::Number),
1042 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1043 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1044 ],
1045 ret: Type::Uint8Array,
1046 predicate: None,
1047 doc: doc("/** Copies `bytes[start..end)` to `bytes[target..]` in place. Returns `this`. */"),
1048 },
1049 ),
1050 (
1051 "slice".to_string(),
1052 MethodSig {
1053 optional: false,
1054 generics: Vec::new(),
1055 params: vec![
1056 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1057 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1058 ],
1059 ret: Type::Uint8Array,
1060 predicate: None,
1061 doc: doc("/** Returns a fresh copy of the bytes in `[start, end)`. */"),
1062 },
1063 ),
1064 (
1065 "subarray".to_string(),
1066 MethodSig {
1067 optional: false,
1068 generics: Vec::new(),
1069 params: vec![
1070 Param::with_default("start", Type::Number, crate::DefaultValue::Number(0.0)),
1071 Param::with_default("end", Type::Number, crate::DefaultValue::Number(f64::INFINITY)),
1072 ],
1073 ret: Type::Uint8Array,
1074 predicate: None,
1075 doc: doc("/** Deep-copy alias for `slice` under v1 (no `ArrayBuffer` view sharing). */"),
1076 },
1077 ),
1078 (
1079 "with".to_string(),
1080 MethodSig {
1081 optional: false,
1082 generics: Vec::new(),
1083 params: vec![
1084 Param::new("index", Type::Number),
1085 Param::new("value", Type::Number),
1086 ],
1087 ret: Type::Uint8Array,
1088 predicate: None,
1089 doc: doc("/** Returns a clone of this array with `value` converted to a byte and written at `index`. */"),
1090 },
1091 ),
1092 (
1093 "set".to_string(),
1094 MethodSig {
1095 optional: false,
1096 generics: Vec::new(),
1097 params: vec![
1098 Param::new("values", Type::Uint8Array),
1099 Param::with_default("offset", Type::Number, crate::DefaultValue::Number(0.0)),
1100 ],
1101 ret: Type::Void,
1102 predicate: None,
1103 doc: doc("/** Copies `values` into this array starting at `offset`. Throws on out-of-bounds. */"),
1104 },
1105 ),
1106 (
1107 "forEach".to_string(),
1108 MethodSig {
1109 optional: false,
1110 generics: Vec::new(),
1111 params: vec![Param::new("callback", Type::Function {
1112 optional: 0,
1113 params: byte_callback_params(Vec::new()),
1114 ret: Box::new(Type::Void),
1115 predicate: None,
1116 has_rest: false,
1117 })],
1118 ret: Type::Void,
1119 predicate: None,
1120 doc: doc("/** Invokes `callback(byte, index, array)` for every byte in order. */"),
1121 },
1122 ),
1123 (
1124 "map".to_string(),
1125 MethodSig {
1126 optional: false,
1127 generics: Vec::new(),
1128 params: vec![Param::new("callback", Type::Function {
1129 optional: 0,
1130 params: byte_callback_params(Vec::new()),
1131 ret: Box::new(Type::Number),
1132 predicate: None,
1133 has_rest: false,
1134 })],
1135 ret: Type::Uint8Array,
1136 predicate: None,
1137 doc: doc("/** Returns a new `Uint8Array` with each `callback(this[i], i, this)` result converted to a byte. */"),
1138 },
1139 ),
1140 (
1141 "filter".to_string(),
1142 MethodSig {
1143 optional: false,
1144 generics: Vec::new(),
1145 params: vec![Param::new("predicate", Type::Function {
1146 optional: 0,
1147 params: byte_callback_params(Vec::new()),
1148 ret: Box::new(Type::Unknown),
1149 predicate: None,
1150 has_rest: false,
1151 })],
1152 ret: Type::Uint8Array,
1153 predicate: None,
1154 doc: doc("/** Returns a new `Uint8Array` containing every byte for which `predicate(byte, index, array)` returns a truthy value. */"),
1155 },
1156 ),
1157 (
1158 "some".to_string(),
1159 MethodSig {
1160 optional: false,
1161 generics: Vec::new(),
1162 params: vec![Param::new("predicate", Type::Function {
1163 optional: 0,
1164 params: byte_callback_params(Vec::new()),
1165 ret: Box::new(Type::Unknown),
1166 predicate: None,
1167 has_rest: false,
1168 })],
1169 ret: Type::Boolean,
1170 predicate: None,
1171 doc: doc("/** Returns `true` if `predicate` returns a truthy value for any byte. */"),
1172 },
1173 ),
1174 (
1175 "every".to_string(),
1176 MethodSig {
1177 optional: false,
1178 generics: Vec::new(),
1179 params: vec![Param::new("predicate", Type::Function {
1180 optional: 0,
1181 params: byte_callback_params(Vec::new()),
1182 ret: Box::new(Type::Unknown),
1183 predicate: None,
1184 has_rest: false,
1185 })],
1186 ret: Type::Boolean,
1187 predicate: None,
1188 doc: doc("/** Returns `true` iff `predicate(byte, index, array)` returns a truthy value for every byte. */"),
1189 },
1190 ),
1191 (
1192 "reduce".to_string(),
1193 MethodSig {
1194 optional: false,
1195 generics: vec!["U".to_string()],
1196 params: vec![
1197 Param::new("callback", Type::Function {
1198 optional: 0,
1199 params: byte_callback_params(vec![Type::TypeVar("U".to_string())]),
1200 ret: Box::new(Type::TypeVar("U".to_string())),
1201 predicate: None,
1202 has_rest: false,
1203 }),
1204 Param::new("initial", Type::TypeVar("U".to_string())),
1205 ],
1206 ret: Type::TypeVar("U".to_string()),
1207 predicate: None,
1208 doc: doc("/** Folds bytes left-to-right with `callback(acc, byte, index, array)`. */"),
1209 },
1210 ),
1211 (
1212 "reduceRight".to_string(),
1213 MethodSig {
1214 optional: false,
1215 generics: vec!["U".to_string()],
1216 params: vec![
1217 Param::new("callback", Type::Function {
1218 optional: 0,
1219 params: byte_callback_params(vec![Type::TypeVar("U".to_string())]),
1220 ret: Box::new(Type::TypeVar("U".to_string())),
1221 predicate: None,
1222 has_rest: false,
1223 }),
1224 Param::new("initial", Type::TypeVar("U".to_string())),
1225 ],
1226 ret: Type::TypeVar("U".to_string()),
1227 predicate: None,
1228 doc: doc("/** Folds bytes right-to-left with `callback(acc, byte, index, array)`. */"),
1229 },
1230 ),
1231 (
1232 "at".to_string(),
1233 MethodSig {
1234 optional: false,
1235 generics: Vec::new(),
1236 params: vec![Param::new("index", Type::Number)],
1237 ret: Type::Union(vec![Type::Number, Type::Undefined]),
1238 predicate: None,
1239 doc: doc("/** Returns the byte at `index`, or `undefined` if out of range. Negative indices count from the end. */"),
1240 },
1241 ),
1242 (
1243 "indexOf".to_string(),
1244 MethodSig {
1245 optional: false,
1246 generics: Vec::new(),
1247 params: vec![
1248 Param::new("target", Type::Number),
1249 Param::with_default("fromIndex", Type::Number, crate::DefaultValue::Number(0.0)),
1250 ],
1251 ret: Type::Number,
1252 predicate: None,
1253 doc: doc("/** Returns the first index of `target`, or `-1`. */"),
1254 },
1255 ),
1256 (
1257 "lastIndexOf".to_string(),
1258 MethodSig {
1259 optional: false,
1260 generics: Vec::new(),
1261 params: vec![
1262 Param::new("target", Type::Number),
1263 Param::with_default("fromIndex", Type::Number, crate::DefaultValue::OmittedNumber { omitted: f64::INFINITY, undefined: 0.0 }),
1264 ],
1265 ret: Type::Number,
1266 predicate: None,
1267 doc: doc("/** Returns the last index of `target`, or `-1`. */"),
1268 },
1269 ),
1270 (
1271 "includes".to_string(),
1272 MethodSig {
1273 optional: false,
1274 generics: Vec::new(),
1275 params: vec![
1276 Param::new("target", Type::Number),
1277 Param::with_default("fromIndex", Type::Number, crate::DefaultValue::Number(0.0)),
1278 ],
1279 ret: Type::Boolean,
1280 predicate: None,
1281 doc: doc("/** Returns `true` if `target` appears at or after `fromIndex`. */"),
1282 },
1283 ),
1284 (
1285 "find".to_string(),
1286 MethodSig {
1287 optional: false,
1288 generics: Vec::new(),
1289 params: vec![Param::new("predicate", Type::Function {
1290 optional: 0,
1291 params: byte_callback_params(Vec::new()),
1292 ret: Box::new(Type::Boolean),
1293 predicate: None,
1294 has_rest: false,
1295 })],
1296 ret: Type::Union(vec![Type::Number, Type::Undefined]),
1297 predicate: None,
1298 doc: doc("/** Returns the first byte for which `predicate(byte, index, array)` returns `true`, or `undefined`. */"),
1299 },
1300 ),
1301 (
1302 "findLast".to_string(),
1303 MethodSig {
1304 optional: false,
1305 generics: Vec::new(),
1306 params: vec![Param::new("predicate", Type::Function {
1307 optional: 0,
1308 params: byte_callback_params(Vec::new()),
1309 ret: Box::new(Type::Unknown),
1310 predicate: None,
1311 has_rest: false,
1312 })],
1313 ret: Type::Union(vec![Type::Number, Type::Undefined]),
1314 predicate: None,
1315 doc: doc("/** Returns the last byte for which `predicate(byte, index, array)` returns a truthy value, or `undefined`. */"),
1316 },
1317 ),
1318 (
1319 "findIndex".to_string(),
1320 MethodSig {
1321 optional: false,
1322 generics: Vec::new(),
1323 params: vec![Param::new("predicate", Type::Function {
1324 optional: 0,
1325 params: byte_callback_params(Vec::new()),
1326 ret: Box::new(Type::Boolean),
1327 predicate: None,
1328 has_rest: false,
1329 })],
1330 ret: Type::Number,
1331 predicate: None,
1332 doc: doc("/** Returns the index of the first matching byte, or `-1`. */"),
1333 },
1334 ),
1335 (
1336 "findLastIndex".to_string(),
1337 MethodSig {
1338 optional: false,
1339 generics: Vec::new(),
1340 params: vec![Param::new("predicate", Type::Function {
1341 optional: 0,
1342 params: byte_callback_params(Vec::new()),
1343 ret: Box::new(Type::Unknown),
1344 predicate: None,
1345 has_rest: false,
1346 })],
1347 ret: Type::Number,
1348 predicate: None,
1349 doc: doc("/** Returns the index of the last matching byte, or `-1`. */"),
1350 },
1351 ),
1352 (
1353 "sort".to_string(),
1354 MethodSig {
1355 optional: false,
1356 generics: Vec::new(),
1357 params: vec![Param::with_default(
1358 "compareFn",
1359 Type::Union(vec![
1360 Type::Function {
1361 optional: 0,
1362 params: vec![Type::Number, Type::Number],
1363 ret: Box::new(Type::Number),
1364 predicate: None,
1365 has_rest: false,
1366 },
1367 Type::Undefined,
1368 ]),
1369 crate::DefaultValue::Undefined,
1370 )],
1371 ret: Type::Uint8Array,
1372 predicate: None,
1373 doc: doc("/** Sorts bytes in place via `compareFn(a, b)`. With no `compareFn`, sorts numerically ascending. Returns `this`. */"),
1374 },
1375 ),
1376 (
1377 "toReversed".to_string(),
1378 MethodSig {
1379 optional: false,
1380 generics: Vec::new(),
1381 params: Vec::new(),
1382 ret: Type::Uint8Array,
1383 predicate: None,
1384 doc: doc("/** Returns a fresh copy with bytes reversed. */"),
1385 },
1386 ),
1387 (
1388 "toSorted".to_string(),
1389 MethodSig {
1390 optional: false,
1391 generics: Vec::new(),
1392 params: vec![Param::with_default(
1393 "compareFn",
1394 Type::Union(vec![
1395 Type::Function {
1396 optional: 0,
1397 params: vec![Type::Number, Type::Number],
1398 ret: Box::new(Type::Number),
1399 predicate: None,
1400 has_rest: false,
1401 },
1402 Type::Undefined,
1403 ]),
1404 crate::DefaultValue::Undefined,
1405 )],
1406 ret: Type::Uint8Array,
1407 predicate: None,
1408 doc: doc("/** Returns a fresh copy sorted via `compareFn`. With no `compareFn`, sorts numerically ascending. */"),
1409 },
1410 ),
1411 (
1412 "toBase64".to_string(),
1413 MethodSig {
1414 optional: false,
1415 generics: Vec::new(),
1416 params: vec![Param::with_default(
1417 "options",
1418 Type::Union(vec![
1419 Type::prelude_interface("Base64Options".to_string(), Vec::new()),
1420 Type::Undefined,
1421 ]),
1422 crate::DefaultValue::Undefined,
1423 )],
1424 ret: Type::String,
1425 predicate: None,
1426 doc: doc("/** Returns the bytes as a base64 string. `options` selects alphabet and padding. */"),
1427 },
1428 ),
1429 (
1430 "toHex".to_string(),
1431 MethodSig {
1432 optional: false,
1433 generics: Vec::new(),
1434 params: Vec::new(),
1435 ret: Type::String,
1436 predicate: None,
1437 doc: doc("/** Returns the bytes as a lowercase hex string. */"),
1438 },
1439 ),
1440 ]),
1441 properties: BTreeMap::from([
1442 (
1443 "length".to_string(),
1444 PropertySig {
1445 ty: Type::Number,
1446 readonly: true,
1447 intrinsic: false,
1448 optional: false,
1449 doc: doc("/** The number of bytes in this array. */"),
1450 },
1451 ),
1452 (
1453 "byteLength".to_string(),
1454 PropertySig {
1455 ty: Type::Number,
1456 readonly: true,
1457 intrinsic: false,
1458 optional: false,
1459 doc: doc("/** Equivalent to `length`. Provided for JS `TypedArray` API compatibility. */"),
1460 },
1461 ),
1462 ]),
1463 dispatch: Dispatch::Direct,
1464 doc: doc(
1465 "/** Packed byte array. Constructed via `new Uint8Array([...])` / `Uint8Array.alloc(n)` / `Uint8Array.fromArray(...)` / etc. */",
1466 ),
1467 },
1468 },
1469 );
1470
1471 defs.types.insert(
1472 "Uint8ArrayConstructor".to_string(),
1473 TypeSymbol {
1474 name: "Uint8ArrayConstructor".to_string(),
1475 mangled_name: crate::mangle::prelude("Uint8ArrayConstructor"),
1476 declaration_span: Span::at(crate::FileId::PRELUDE),
1477 kind: TypeKind::Interface { index: None,
1478 generics: Vec::new(),
1479 methods: BTreeMap::from([
1480 (
1481 "new".to_string(),
1482 MethodSig {
1483 optional: false,
1484 generics: Vec::new(),
1485 params: vec![Param::new(
1486 "values",
1487 Type::Union(vec![
1488 Type::Array(Box::new(Type::Number)),
1489 Type::Number,
1490 ]),
1491 )],
1492 ret: Type::Uint8Array,
1493 predicate: None,
1494 doc: doc(
1495 "/**\n * Build a new `Uint8Array`. Given an array, truncates each element and reduces it modulo 256, as JavaScript does, so `-1` is 255. Given a number, allocates that many zero bytes (the same as `Uint8Array.alloc`, including its `RangeError` on a negative or too-large length).\n * @param values Numeric values to copy into the new array, or the length to allocate.\n */",
1496 ),
1497 },
1498 ),
1499 (
1500 "alloc".to_string(),
1501 MethodSig {
1502 optional: false,
1503 generics: Vec::new(),
1504 params: vec![Param::new("n", Type::Number)],
1505 ret: Type::Uint8Array,
1506 predicate: None,
1507 doc: doc(
1508 "/**\n * Allocate a zero-filled `Uint8Array` of length `n`. Fractional values truncate toward zero and `NaN` gives an empty array; a negative or too-large `n` raises a `RangeError`.\n * @param n Length in bytes.\n */",
1509 ),
1510 },
1511 ),
1512 (
1513 "fromArray".to_string(),
1514 MethodSig {
1515 optional: false,
1516 generics: Vec::new(),
1517 params: vec![Param::new(
1518 "values",
1519 Type::Array(Box::new(Type::Number)),
1520 )],
1521 ret: Type::Uint8Array,
1522 predicate: None,
1523 doc: doc(
1524 "/** Build a new `Uint8Array` from `values` — canonical name for `Uint8Array.new(values)`. */",
1525 ),
1526 },
1527 ),
1528 (
1529 "fromBytes".to_string(),
1530 MethodSig {
1531 optional: false,
1532 generics: Vec::new(),
1533 params: vec![Param::new("other", Type::Uint8Array)],
1534 ret: Type::Uint8Array,
1535 predicate: None,
1536 doc: doc(
1537 "/** Returns a deep copy of `other`. Mutations on the result don't touch `other`. */",
1538 ),
1539 },
1540 ),
1541 (
1542 "of".to_string(),
1543 MethodSig {
1544 optional: false,
1545 generics: Vec::new(),
1546 params: vec![Param::rest(
1547 "values",
1548 Type::Array(Box::new(Type::Number)),
1549 )],
1550 ret: Type::Uint8Array,
1551 predicate: None,
1552 doc: doc(
1553 "/** Build a `Uint8Array` from the supplied byte values — `Uint8Array.of(1, 2, 3)`. */",
1554 ),
1555 },
1556 ),
1557 (
1558 "fromBase64".to_string(),
1559 MethodSig {
1560 optional: false,
1561 generics: Vec::new(),
1562 params: vec![
1563 Param::new("s", Type::String),
1564 Param::with_default(
1565 "options",
1566 Type::Union(vec![
1567 Type::prelude_interface("Base64Options".to_string(), Vec::new()),
1568 Type::Undefined,
1569 ]),
1570 crate::DefaultValue::Undefined,
1571 ),
1572 ],
1573 ret: Type::Uint8Array,
1574 predicate: None,
1575 doc: doc(
1576 "/** Decode `s` as base64; `options.alphabet` picks standard vs URL-safe. Malformed input throws a `SyntaxError`. */",
1577 ),
1578 },
1579 ),
1580 (
1581 "fromHex".to_string(),
1582 MethodSig {
1583 optional: false,
1584 generics: Vec::new(),
1585 params: vec![Param::new("s", Type::String)],
1586 ret: Type::Uint8Array,
1587 predicate: None,
1588 doc: doc(
1589 "/** Decode `s` as a hex string. Mixed case accepted; whitespace or an odd length throws a `SyntaxError`. */",
1590 ),
1591 },
1592 ),
1593 ]),
1594 properties: BTreeMap::new(),
1595 dispatch: Dispatch::Static,
1596 doc: doc(
1597 "/** Constructor object for `Uint8Array`. Accessed via the global `Uint8Array` binding. */",
1598 ),
1599 },
1600 },
1601 );
1602
1603 defs.types.insert(
1604 "Base64Options".to_string(),
1605 TypeSymbol {
1606 name: "Base64Options".to_string(),
1607 mangled_name: crate::mangle::prelude("Base64Options"),
1608 declaration_span: Span::at(crate::FileId::PRELUDE),
1609 kind: TypeKind::Interface { index: None,
1610 generics: Vec::new(),
1611 methods: BTreeMap::new(),
1612 properties: BTreeMap::from([
1613 (
1614 "alphabet".to_string(),
1615 PropertySig {
1616 ty: Type::Union(vec![
1617 Type::StringLiteral("base64".to_string()),
1618 Type::StringLiteral("base64url".to_string()),
1619 ]),
1620 readonly: false,
1621 intrinsic: false,
1622 optional: true,
1623 doc: doc(
1624 "/** Alphabet selector. `\"base64\"` (default) or `\"base64url\"`. */",
1625 ),
1626 },
1627 ),
1628 (
1629 "omitPadding".to_string(),
1630 PropertySig {
1631 ty: Type::Boolean,
1632 readonly: false,
1633 intrinsic: false,
1634 optional: true,
1635 doc: doc(
1636 "/** When `true`, omit the trailing `=` padding. Encode-only. */",
1637 ),
1638 },
1639 ),
1640 ]),
1641 dispatch: Dispatch::VTable,
1642 doc: doc(
1643 "/** Options bag for `Uint8Array#toBase64` / `Uint8Array.fromBase64`. All fields optional. */",
1644 ),
1645 },
1646 },
1647 );
1648
1649 defs.values.insert(
1650 "Uint8Array".to_string(),
1651 ValueSymbol {
1652 name: "Uint8Array".to_string(),
1653 mangled_name: crate::mangle::prelude("Uint8Array"),
1654 declaration_span: Span::at(crate::FileId::PRELUDE),
1655 kind: ValueKind::Const {
1656 ty: Type::prelude_interface("Uint8ArrayConstructor".to_string(), Vec::new()),
1657 doc: doc(
1658 "/** The `Uint8Array` constructor — call `Uint8Array.new([...])` or `Uint8Array.alloc(n)` to make instances. */",
1659 ),
1660 },
1661 },
1662 );
1663}