Skip to content

feat: use high level zapi dsl #302

Closed
nazarhussain wants to merge 10 commits intomainfrom
nh/zapi-dsl-integ
Closed

feat: use high level zapi dsl #302
nazarhussain wants to merge 10 commits intomainfrom
nh/zapi-dsl-integ

Conversation

@nazarhussain
Copy link
Copy Markdown
Contributor

To make the development of the bindings easy and consistent use the new DSL introduced in ChainSafe/zapi#11

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request migrates the existing N-API bindings to the new high-level ZAPI DSL. This change aims to reduce boilerplate code, enhance type safety, and ensure more consistent development across the bindings. The update includes necessary adjustments to build configurations, module registration, and test suites to accommodate the new DSL structure.

Highlights

  • Migration to ZAPI DSL: Updated all N-API bindings to utilize the new high-level ZAPI DSL, simplifying the codebase and improving consistency.
  • Dependency Update: Updated the zapi dependency to the latest version to support the new DSL features.
  • Refactored Module Registration: Simplified module registration by leveraging js.exportModule and streamlining initialization/cleanup hooks.
  • API Changes: Converted several properties to functions (e.g., pubkeys.size) to align with current DSL limitations, requiring corresponding updates in tests.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the N-API bindings to use a new DSL and the zapi module structure, moving away from manual registration in favor of js.exportModule. Key changes include updating import paths, refactoring functions to use zapi.js types (such as js.Value, js.Number, and js.Uint8Array), and adjusting the pubkeys cache size from a property to a function. Feedback focuses on adhering to the repository's strict style guide, specifically regarding assertion density (minimum two per function), function length limits (70 lines), avoiding variable abbreviations, and removing redundant type casts.

Comment thread bindings/napi/config.zig

pub fn Config_set(env: napi.Env, cb: napi.CallbackInfo(2)) !napi.Value {
/// JS: config.set(chainConfigObj, genesisValidatorsRoot)
pub fn set(obj: js.Value, genesis_root: js.Uint8Array) !void {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This function lacks assertions. The repository style guide requires that all function arguments, return values, pre/postconditions, and invariants be asserted. Furthermore, the assertion density must average a minimum of two assertions per function.

References
  1. Assert all function arguments and return values, pre/postconditions and invariants. The assertion density of the code must average a minimum of two assertions per function. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Arguments are asserted inside the functions.

Comment thread bindings/napi/config.zig Outdated
Comment thread bindings/napi/config.zig
}

pub fn chainConfigFromObject(env: napi.Env, obj: napi.Value) !ChainConfig {
fn chainConfigFromObject(env: napi.Env, obj: napi.Value) !ChainConfig {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The function chainConfigFromObject exceeds the hard limit of 70 lines (it is currently 80 lines long). Consider refactoring this function by splitting the complex object parsing into smaller, specialized helper functions.

References
  1. Restrict the length of function bodies to reduce the probability of poorly structured code. We enforce a hard limit of 70 lines per function. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Out of scope from this PR.

Comment thread bindings/napi/pubkeys.zig Outdated
Comment thread bindings/napi/pubkeys.zig Outdated
}

return try env.createUint32(@intCast(state.index2pubkey.items.len));
return js.Number.from(@as(u32, @intCast(state.index2pubkey.items.len)));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The @as(u32, ...) cast is redundant here. Since @intCast is used within the context of a function call where the expected type can be inferred, the explicit type attribution is unnecessary.

    return js.Number.from(@intCast(state.index2pubkey.items.len));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

js.Number.from accepts anytype so we have to use @as for proper typecast.

Comment thread bindings/napi/shuffle.zig Outdated
Comment thread bindings/napi/config.zig
return env.getUndefined();
}

pub fn chainConfigFromObject(env: napi.Env, obj: napi.Value) !ChainConfig {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As the pub is removed, this function will not be exposed to binding.

Comment thread bindings/napi/pool.zig
return error.PoolNotInitialized;
}

const requested = new_size.assertU32();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't see that the DSL contract enforces that new_size is a number? so using assertXX here is not ideal and can cause a crash (when it should just throw an error).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The type new_size: js.Number enforces it's a number, but it can be a uint or int, as JS number support both. So we need to assert here.

This is same as std.debug.assert for function arguments.

nazarhussain and others added 4 commits April 8, 2026 21:07
Resolve conflicts with 5c50ab4 (chore: fix zapi usage #307).
Main's changes (import rename to zapi:zapi, env.wrap extra param,
error message update) are all superseded by the DSL rewrite — kept
our version for all 15 conflicted files.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@nazarhussain
Copy link
Copy Markdown
Contributor Author

Closing in favor of #320

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