Skip to content

Add external#42

Merged
richerfu merged 3 commits into
mainfrom
feat-external
May 27, 2026
Merged

Add external#42
richerfu merged 3 commits into
mainfrom
feat-external

Conversation

@richerfu

Copy link
Copy Markdown
Contributor

No description provided.

@github-actions

github-actions Bot commented May 27, 2026

Copy link
Copy Markdown

zig-napi ArkVM benchmark

  • Generated: 2026-05-27T03:57:56Z
  • Status: ZIG_NAPI_BENCHMARK_RESULT status=ok
module api content iterations native C N-API avg (us) zig-napi avg (us) diff (us) ratio
global function void(*)() 100000 0.104 0.108 0.004 1.034x
primitive i32(i32, i32) 100000 0.132 0.137 0.005 1.039x
primitive bool(bool) 100000 0.126 0.129 0.004 1.029x
string len(string) 100000 0.155 0.152 -0.003 0.982x
object read properties 100000 0.315 0.326 0.011 1.036x
array sum(number[]) 100000 0.633 0.614 -0.019 0.971x
function call callback 100000 0.271 0.282 0.011 1.04x
class constructor 20000 0.967 4.485 3.518 4.637x
class getter 100000 0.205 0.199 -0.006 0.971x
class setter 100000 0.379 0.379 0 1x
class method 100000 0.218 0.217 -0.001 0.993x
ArrayBuffer constructor 20000 0.317 0.368 0.051 1.16x
ArrayBuffer byteLength 100000 0.155 0.158 0.003 1.019x
Buffer constructor 20000 0.881 0.756 -0.125 0.858x
Buffer length 100000 0.161 0.161 0 0.999x
TypedArray Uint8Array constructor 20000 0.699 0.865 0.166 1.237x
TypedArray Uint8Array sum 100000 0.191 0.217 0.025 1.133x
DataView constructor 20000 0.413 0.438 0.025 1.061x
DataView byteLength 100000 0.153 0.191 0.038 1.251x

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for N-API “external” values to the zig-napi wrapper layer, plus TS type generation and coverage in both the Node test addon and the ArkTS test suite.

Changes:

  • Introduce napi.External(T) wrapper with type-tagging, optional size hint, and finalizer-based cleanup.
  • Integrate externals into runtime conversion (from_napi_value / to_napi_value) and TS type generation (ExternalObject<T>).
  • Add external-focused tests and example exports to validate roundtrips, mutation, and type-mismatch errors.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/external.spec.ts Adds ArkTS test coverage for creating/reading/mutating externals and mismatch errors.
test/basic.ts Registers the new external test in the basic test suite.
src/napi/wrapper/external.zig Implements External(T) wrapper, tagging, finalizer cleanup, and size-hint support.
src/napi/util/napi.zig Enables conversions/type checks to recognize External(T) as a supported wrapper type.
src/napi/util/helper.zig Adds isExternal() helper used by conversion and fast-path logic.
src/napi.zig Exposes External from the top-level napi module.
src/build/napi-tsgen.zig Generates TS surface types for External(T) as ExternalObject<T>.
node-test/napi/src/values.zig Adds Node-test addon functions exercising External(u32) and External(ExternalPoint).
node-test/napi/src/lib.zig Re-exports the new node-test external functions.
node-test/napi/tests/values.spec.js Adds JS tests validating external behavior and error cases.
examples/basic/src/hello.zig Exposes external example functions from the basic example module.
examples/basic/src/external.zig Implements basic example external functions mirroring the node-test API.
examples/basic/index.d.ts Updates generated TS declarations to include ExternalObject<T> and external APIs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +97 to +112
pub fn to_napi_value(self: Self, env: napi.napi_env) !napi.napi_value {
if (self.raw != null) {
return self.raw;
}

const size_hint_i64 = std.math.cast(i64, self.header.size_hint) orelse {
self.destroyDetached();
return NapiError.Error.fromStatus(NapiError.Status.InvalidArg);
};

var result: napi.napi_value = undefined;
const status = napi.napi_create_external(env, self.header, externalFinalizer, null, &result);
if (status != napi.napi_ok) {
self.destroyDetached();
return NapiError.Error.fromStatus(NapiError.Status.New(status));
}
Comment thread src/napi/wrapper/external.zig Outdated
Comment on lines +82 to +88
}

const header: *TaggedHeader = @ptrCast(@alignCast(data.?));
if (header.magic != external_magic or !std.mem.eql(u8, header.typeName(), @typeName(T))) {
NapiError.last_error = NapiError.Error.withCodeAndMessage("InvalidArg", "External value type does not match expected type");
return invalid(env, raw);
}
Comment thread src/napi/wrapper/external.zig Outdated
Comment on lines +121 to +125
if (adjust_status != napi.napi_ok) {
return NapiError.Error.fromStatus(NapiError.Status.New(adjust_status));
}
self.header.memory_adjusted = true;
self.header.adjusted_size = adjusted_size;
Comment thread src/build/napi-tsgen.zig Outdated
Comment on lines +1158 to +1159
try append(&state.declarations, "export interface ExternalObject<T> {\n");
try append(&state.declarations, " readonly __napiExternal?: T\n");

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Comment on lines +228 to +230
if (env != null and header.memory_adjusted and header.size_hint > 0) {
var adjusted_size: i64 = 0;
_ = napi.napi_adjust_external_memory(env, -@as(i64, @intCast(header.size_hint)), &adjusted_size);
.header = header,
};
}

Comment thread src/napi/util/napi.zig
Comment on lines 173 to 177
if (comptime helper.isTypedArray(T)) break :blk isTypedArrayValue(env, raw);
if (comptime helper.isDataView(T)) break :blk isDataViewValue(env, raw);
if (comptime helper.isReference(T)) break :blk true;
if (comptime helper.isExternal(T)) break :blk napiTypeOf(env, raw) == napi.napi_external;
if (comptime helper.isTuple(T)) break :blk isArrayValue(env, raw);

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.

@richerfu richerfu merged commit 2960b19 into main May 27, 2026
24 checks passed
@richerfu richerfu deleted the feat-external branch May 27, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants