feat(dsl): add constructor to js.Object(T) for one-line object creation
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- zig
- Domain
- api
Research direction
Start in src/js/object.zig and inspect the type returned by Object(T), its set method, and how String.from or Number.from access the environment. Add the proposed constructor using the existing object-creation and population paths, while keeping get, set, and toValue unchanged. Done means callers can create and populate a typed JS object in one call.
Written by the indexing model from the issue text.
Description
Summary
Add a constructor (init / from) to js.Object(T) so user code can create and populate a JS object in a single call, instead of manually creating a raw object, wrapping it, and calling set.
Motivation
Defining an object shape is ergonomic:
pub const BitArray = js.Object(struct {
uint8Array: js.Uint8Array,
bitLen: js.Number,
});
But creating an instance at runtime currently requires the low-level dance:
const e = js.env();
const raw = try e.createObject(); // napi.Value, a fresh {} object
var obj = BitArray{ .val = raw }; // wrap it
try obj.set(.{ .uint8Array = ..., .bitLen = ... });
Object(T) (src/js/object.zig) currently exposes only validateArg, get, set, and toValue — there is no constructor. This boilerplate is repetitive and leaks N-API details into otherwise high-level DSL code.
Proposed solution
Add an init method to the type returned by Object(T). It already knows T and has set, so it just needs to create the underlying object and populate it:
/// Creates a new JS object and populates it from the Zig struct `T`.
pub fn init(value: T) !Self {
const self = Self{ .val = try env().createObject() };
try self.set(value);
return self;
}
(using the in-scope env accessor, matching how String.from / Number.from reach the env)
Call site collapses to:
const ba = try BitArray.init(.{
.uint8Array = js.Uint8Array.from(&bytes),
.bitLen = js.Number.from(@as(i32, 42)),
});
Naming
The scalar DSL wrappers already use from(...) (String.from, Number.from, Boolean.from, Date.from, Uint8Array.from). For consistency we could name it from instead of init — open to either. init reads slightly better here since the argument is a struct of fields rather than a single scalar.
Notes / open questions
- Should there also be an empty constructor (e.g.
empty()/init(.{})when all fields are optional) for incremental population? Probably out of scope for the first pass. - Keep the existing
set/get/toValueAPI unchanged; this is purely additive.
- Dominant language
- Zig
- Stars
- 4
- Forks
- 4
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ChainSafe/zapi
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
Type: Maintenance
Difficulty 1/5 Under an hour Newbie friendliness 76/100
-
clearer errors Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
AXERA-TECH/ax-llm#77 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
kind/cleanup
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
kubernetes-sigs/kueue#15937 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
sympozium-ai/sympozium#627 ·