From 630f249c3623907ca635b534cf7370d4b71f721f Mon Sep 17 00:00:00 2001 From: bing Date: Fri, 31 Jul 2026 03:09:33 +0800 Subject: [PATCH] feat(js): add typed array toArray --- README.md | 2 +- examples/js_dsl/mod.test.ts | 9 +++++++++ examples/js_dsl/mod.zig | 10 ++++++++++ src/js/typed_arrays.zig | 12 ++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 09cec47..11a8517 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ c.count; // 1 (getter, not a method call) | `Object(T)` | `object` | `get()`, `set(value)` — `T` fields must be DSL types | | `Function` | `Function` | `call(args)` | | `Value` | `any` | `isNumber()`, `asNumber()`, type checking/narrowing | -| `Uint8Array` etc. | `TypedArray` | `toSlice()`, `from(slice)` | +| `Uint8Array` etc. | `TypedArray` | `toSlice()`, `toArray(len)`, `from(slice)` | | `Promise(T)` | `Promise` | `resolve(value)`, `reject(err)` | --- diff --git a/examples/js_dsl/mod.test.ts b/examples/js_dsl/mod.test.ts index c694890..bf70c22 100644 --- a/examples/js_dsl/mod.test.ts +++ b/examples/js_dsl/mod.test.ts @@ -201,6 +201,15 @@ describe("typed arrays", () => { expect(mod.uint8Sum(data)).toEqual(15); }); + it("toArray copies a TypedArray of the expected length", () => { + expect(mod.uint8Array4Sum(new Uint8Array([1, 2, 3, 4]))).toEqual(10); + }); + + it("toArray rejects TypedArrays of a different length", () => { + expect(() => mod.uint8Array4Sum(new Uint8Array([1, 2, 3]))).toThrow(); + expect(() => mod.uint8Array4Sum(new Uint8Array([1, 2, 3, 4, 5]))).toThrow(); + }); + it("float64Scale scales values", () => { const data = new Float64Array([1.0, 2.0, 3.0]); const result = mod.float64Scale(data, 2.5); diff --git a/examples/js_dsl/mod.zig b/examples/js_dsl/mod.zig index 0d13d9c..4a6e517 100644 --- a/examples/js_dsl/mod.zig +++ b/examples/js_dsl/mod.zig @@ -190,6 +190,16 @@ pub fn uint8Sum(data: Uint8Array) !Number { return Number.from(sum); } +/// Sum exactly four bytes copied from a Uint8Array into a Zig array. +pub fn uint8Array4Sum(data: Uint8Array) !Number { + const array = try data.toArray(4); + var sum: i32 = 0; + for (array) |byte| { + sum += @intCast(byte); + } + return Number.from(sum); +} + /// Scale all values in a Float64Array by a factor. Returns a new array. pub fn float64Scale(data: Float64Array, factor: Number) !Float64Array { const slice = try data.toSlice(); diff --git a/src/js/typed_arrays.zig b/src/js/typed_arrays.zig index 87eb5cd..c1f0d0f 100644 --- a/src/js/typed_arrays.zig +++ b/src/js/typed_arrays.zig @@ -50,6 +50,18 @@ pub fn TypedArray(comptime Element: type, comptime array_type: TypedarrayType) t return typed_ptr[0..info.length]; } + /// Copies the TypedArray into a zig array of exactly `len` elements. + /// + /// Returns: + /// 1) `error.LengthMismatch` when the TypedArray length differs from + /// `len`, or + /// 2) `error.TypeMismatch` when its element type is wrong. + pub fn toArray(self: Self, comptime len: usize) ![len]Element { + const slice = try self.toSlice(); + if (slice.len != len) return error.LengthMismatch; + return slice[0..len].*; + } + /// Creates a new JavaScript TypedArray backed by an *external* (native-heap) /// ArrayBuffer. ///