Skip to content

feat!: error on non-DSL pub fn in exportModule - #38

Merged
nazarhussain merged 2 commits into
mainfrom
bing/warn-dsl
May 26, 2026
Merged

feat!: error on non-DSL pub fn in exportModule#38
nazarhussain merged 2 commits into
mainfrom
bing/warn-dsl

Conversation

@spiral-ladder

@spiral-ladder spiral-ladder commented May 22, 2026

Copy link
Copy Markdown
Member

js.exportModule previously silently dropped pub fns whose parameters weren't DSL-compatible. That made it easy to ship a function you thought was exported but wasn't (see ChainSafe/lodestar-z#371).

Now exportModule raises a @compileError naming the offending decl.
Fix it by one of:

  • use DSL-compatible parameters (e.g. js.Number),
  • drop pub if the function is a helper not meant for JS,
  • pass a custom .register to js.exportModule to export the function manually.

BREAKING CHANGE

Modules with non-DSL pub fns alongside DSL exports will no longer build.

Zig functions are skipped if they:

1) are not `pub fn`,
2) do not use DSL-compatible types from the `js` module

We can't error since we want flexibility to define and use other
functions in the same file, so we just
add a simple warning to warn the user about this at comptime.

This is to avoid future situations encountered here: ChainSafe/lodestar-z#371
@spiral-ladder spiral-ladder self-assigned this May 22, 2026
@nazarhussain nazarhussain changed the title feat: warn when dsl incompatible functions are skipped feat!: error on non-DSL pub fn in exportModule May 26, 2026
@nazarhussain

Copy link
Copy Markdown
Contributor

Problem with simple warning is that binding author might not notice it at all, as most of the time there will some CI workflow building buildings, not a human looking at build warnings. And then for binding consumer that warning will be too late to address any solution.

@nazarhussain
nazarhussain merged commit d72deb7 into main May 26, 2026
9 of 15 checks passed
nazarhussain added a commit to ChainSafe/lodestar-z that referenced this pull request Jul 27, 2026
## Motivation

zapi v3.0.0 added a lifecycle-managed `js.io()` to the JS DSL
(ChainSafe/zapi#26): `js.exportModule` retains a shared
`std.Io.Threaded` before the module's `init` hook and releases it after
the `cleanup` hook, refcounted across N-API environments. This is the
same lifecycle our hand-rolled `bindings/napi/io.zig` implemented, so
the local module can be deleted.

## Summary

- bump zapi v2.2.0 → v3.0.0
- delete `bindings/napi/io.zig`; replace all `napi_io.get()` call sites
with `js.io()` (`blst`, `pubkeys`, `metrics`, `BeaconStateView`, `root`)
- drop manual io init/deinit from the `root.zig` lifecycle hooks —
ordering is preserved upstream (`retain()` runs before `init`,
`release()` after `cleanup`), so `js.io()` is valid during CPU detection
at init and thread pool teardown at cleanup

### zapi v3 breaking change

v3.0.0 rejects non-DSL `pub fn`s in `exportModule` (ChainSafe/zapi#38)
instead of silently skipping them. Internal decls that the exporter
walked are now hidden:

- `pool.State`, `config.State`, `pubkeys.State`,
`config.chainConfigFromObject`: de-pubbed (cross-file access still works
through the pub `state` vars; the exporter skips pub vars)
- `pool.PoolRc`: de-pubbed; `BeaconStateView.pool_rc` now uses
`@TypeOf(pool.state.pool_rc)`
- `blst.initThreadPool`/`deinitThreadPool`: moved behind a pub
`lifecycle` var so they stay native-only and are no longer silently
exported to JS (`deinitThreadPool`, zero-arg, previously *was* reachable
from JS; nothing on the TS side used it)

## Validation

- `zig build build-lib:bindings` (Debug and ReleaseSafe)
- `pnpm test`: all 233 tests pass, including `teardown.test.ts` (clean
process exit through the new env-cleanup → io release path, no panic)
- `zig fmt --check` on changed files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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