Repository navigation
feat(napi): convert composite types in createCallback - #84
Draft
nazarhussain wants to merge 1 commit into
Draft
nazarhussain wants to merge 1 commit into
nazarhussain wants to merge 1 commit into
Conversation
fromValue/toValue now handle optionals, enums, structs, tuples, fixed arrays and slices recursively, and read string arguments into a per-call arena that is freed when the callback returns. Omitted trailing optional arguments become null. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
napi.createCallbackcould only convertbool, integers, floats and Buffer byte slices. A function taking a string, an optional, a struct or an array needed a hand-written callback. This brings over the reflection-based reader/writer idea from the early prototype at nazarhussain/zapi, rewritten against the currentValue/EnvAPI with checked conversions.Changes
fromValue/toValueinsrc/to_from_value.zignow convert recursively:?Tnull/undefined↔nullenum(Int)InvalidArgstruct { ... }ObjectExpected)[N]TArrayExpected/InvalidArg)[]T,[]const T[]const u8argument with.autoGenericFailure).returns = .stringmakes a struct's[]const u8fields come back as strings.createCallbackgivesfromValuea per-callArenaAllocatorfor strings and slices. The arena is freed after the return value has been converted, so returning a borrowed argument slice is safe.nullinstead of throwingERR_INVALID_ARG_COUNT. This matches the DSL'sconvertArgWithOptional.fromValueis internal (not re-exported), so adding theallocatorparameter is not a public API change.Behaviour changes to note
[N]Tor non-byte slice failed at runtime withGenericFailure. Those now convert.[N]u8returned by value now becomes a JS array.*[N]u8and[]u8still become Buffers.Tests
hello_worldexample functions (greet,scalePoint,sum,swap,reverse3,nextColor) with vitest cases, including rejection paths: wrong type, wrong tuple/array length, unknown enum tag, non-object struct argument.zig build test:zapi,pnpm build:zigandpnpm test:js(150 passed, 1 skipped) all pass locally.zig fmt --checkis clean.🤖 Generated with Claude Code