Skip to content

Commit e6c27e1

Browse files
committed
feat: add NodeArray
1 parent 096af2e commit e6c27e1

4 files changed

Lines changed: 98 additions & 21 deletions

File tree

src/node_values.zig

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,41 @@ pub const NodeObject = struct {
192192
}
193193
};
194194

195+
pub const NodeArray = struct {
196+
const Self = @This();
197+
198+
napi_env: c.napi_env,
199+
napi_value: c.napi_value,
200+
201+
pub fn asValue(self: NodeArray.Self) !NodeValue {
202+
return NodeValue{
203+
.napi_env = self.napi_env,
204+
.napi_value = self.napi_value,
205+
};
206+
}
207+
208+
pub fn len(self: NodeArray.Self) !u32 {
209+
var v: u32 = undefined;
210+
try s2e(c.napi_get_array_length(self.napi_env, self.napi_value, &v));
211+
return v;
212+
}
213+
214+
/// Gets a NodeValue indicating wether the object has a property with the specified name.
215+
pub fn get(self: NodeArray.Self, index: u32) !NodeValue {
216+
var v: c.napi_value = undefined;
217+
try s2e(c.napi_get_element(self.napi_env, self.napi_value, index, &v));
218+
return NodeValue{ .napi_env = self.napi_env, .napi_value = v };
219+
}
220+
221+
/// Set the specified NodeValue at the specified index of the NodeArray.
222+
pub fn set(self: NodeArray.Self, index: u32, value: NodeValue) !NodeValue {
223+
try s2e(c.napi_set_element(self.napi_env, self.napi_value, index, value.napi_value));
224+
return value;
225+
}
226+
227+
// get/set [], push, splice, etc.
228+
};
229+
195230
/// Represents a JS function.
196231
pub fn NodeFunction(comptime F: anytype) type {
197232
const f = switch (@typeInfo(F)) {
@@ -234,24 +269,3 @@ fn TupleTypeOf(params: []const std.builtin.Type.Fn.Param) type {
234269

235270
return std.meta.Tuple(&argTypes);
236271
}
237-
pub const NodeArray = struct {
238-
const Self = @This();
239-
240-
napi_env: c.napi_env,
241-
napi_value: c.napi_value,
242-
243-
fn len(self: NodeValue.Self) !u32 {
244-
var v: u32 = undefined;
245-
s2e(c.napi_get_array_length(self.napi_env, self.napi_value, &v));
246-
return v;
247-
}
248-
249-
pub fn asValue(self: NodeArray.Self) !NodeValue {
250-
return NodeValue{
251-
.napi_env = self.napi_env,
252-
.napi_value = self.napi_value,
253-
};
254-
}
255-
256-
// get/set [], push, splice, etc.
257-
};

tests/node-array.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import addon from "node-api-test-module";
2+
import { describe, it, expect } from "bun:test";
3+
4+
describe("NodeArray", () => {
5+
describe("len", () => {
6+
it("should return zero for empty array ", () => {
7+
expect(addon.nodeArray.len([])).toEqual(0);
8+
});
9+
it("should return length of non-emtpy array ", () => {
10+
expect(addon.nodeArray.len([123, 123, 123])).toEqual(3);
11+
});
12+
});
13+
14+
describe("get", () => {
15+
it("should get value of index", () => {
16+
expect(addon.nodeArray.get([123, 456], 1)).toEqual(456);
17+
});
18+
it("should get undefined for invalid index ", () => {
19+
expect(addon.nodeArray.get([], 1)).toEqual(undefined);
20+
});
21+
});
22+
23+
describe("set", () => {
24+
it("should set value at index", () => {
25+
const arr = [1, 2, 3] as any[];
26+
expect(addon.nodeArray.set(arr, 1, "foo")).toEqual("foo");
27+
expect(arr).toEqual([1, "foo", 3]);
28+
});
29+
it("should set value at index past len", () => {
30+
const arr = [1, 2, 3] as any[];
31+
expect(addon.nodeArray.set(arr, 5, "foo")).toEqual("foo");
32+
expect(arr).toEqual([1, 2, 3, undefined, undefined, "foo"]);
33+
});
34+
});
35+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const std = @import("std");
2+
const node_api = @import("node-api");
3+
4+
const NodeContext = node_api.NodeContext;
5+
const NodeValue = node_api.NodeValue;
6+
const NodeObject = node_api.NodeObject;
7+
const NodeArray = node_api.NodeArray;
8+
9+
pub fn init() @This() {
10+
return @This(){};
11+
}
12+
13+
// TODO: make this optional
14+
pub fn deinit() !void {}
15+
16+
pub fn len(arr: NodeArray) !u32 {
17+
return try arr.len();
18+
}
19+
20+
pub fn get(arr: NodeArray, index: u32) !NodeValue {
21+
return try arr.get(index);
22+
}
23+
24+
pub fn set(arr: NodeArray, index: u32, v: NodeValue) !NodeValue {
25+
return try arr.set(index, v);
26+
}

tests/zig/test-module.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const node_api = @import("node-api");
33

44
const TestClass = @import("TestClass.zig");
55
const NodeObjectTests = @import("node_values/NodeObjectTests.zig");
6+
const NodeArrayTests = @import("node_values/NodeArrayTests.zig");
67
const WrapTarget = @import("WrapTarget.zig");
78
const Serialization = @import("Serialization.zig");
89

@@ -16,6 +17,7 @@ fn init(node: node_api.NodeContext) !?node_api.NodeValue {
1617

1718
return try node.serialize(.{
1819
.nodeObject = NodeObjectTests,
20+
.nodeArray = NodeArrayTests,
1921
.serialization = Serialization,
2022
.TestClass = TestClass,
2123
.wrappedInstance = try node.wrapInstance(WrapTarget, .{ .foo = 123, .bar = "hopla" }),

0 commit comments

Comments
 (0)