juspay / juspay/rescript-bindgen

Support global-only declaration packages such as @webgpu/types

Open
#194 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
ReScript
Stars
8
Forks
0
Avg merge
9h 33m
Merged PRs (30d)
15

Description

## Problem

`@webgpu/types` is a type-only package whose `dist/index.d.ts` declares WebGPU browser globals such as `GPUDevice`, `GPUBuffer`, `GPUTexture`, and additions to `Navigator`/canvas interfaces. It is not an importable JavaScript module.

After fixing the Windows scratch-cache path in #193, the package installs and its declaration entry resolves correctly, but extraction stops at the module boundary:

```text
$ npx @juspay/rescript-bindgen --pkg @webgpu/types --out webgpu-types
[bindgen] entry: .../.bindgen-cache/node_modules/@webgpu/types/dist/index.d.ts
[bindgen] @module("@webgpu/types")
[bindgen] error: No module symbol for .../@webgpu/types/dist/index.d.ts
```

Tested with `@webgpu/types@0.1.71`.

## Root cause

The extractor currently starts from either:

- a source file with top-level module exports; or
- an ambient `declare module "..."` block.

It then emits React components, exported functions, and exported classes, with runtime access generally rooted in `@module(...)`.

A global-script declaration file has neither kind of module symbol. Even if it were allowed past that check, `@module("@webgpu/types")` would be incorrect because the package has no runtime module to import, and top-level type/interface declarations are not currently treated as generation roots.

## Proposed support

Add a global-declarations extraction/emission mode for global-only `.d.ts` packages:

- detect an entry containing global declarations but no external/ambient module symbol;
- traverse relevant top-level global interfaces, type aliases, variables, constructors, and functions;
- emit browser-global runtime bindings with the appropriate `@val`, `@new`, `@get`, `@set`, and `@send` annotations instead of `@module`;
- make referenced type aliases and interfaces available as generated ReScript types;
- preserve declaration merging/augmentations such as `Navigator`, `HTMLCanvasElement`, and `OffscreenCanvas` additions;
- report unsupported global declarations explicitly rather than silently dropping them.

Whether this is auto-detected or enabled through an explicit flag can be decided during implementation, but normal importable-package behavior must remain unchanged.

## Acceptance criteria

- `@webgpu/types` gets past resolution and extraction without `No module symbol`.
- Generated bindings never attempt to import a runtime `@webgpu/types` module.
- A representative slice of WebGPU globals is usable from ReScript and compiles under the supported ReScript version.
- Global constructors/constants and instance methods/properties use correct interop annotations.
- A self-contained global-only golden fixture covers the mode without requiring network access.
- Existing module and ambient-module fixtures remain byte-identical unless intentionally updated.

## Related

- #193 fixes the separate Windows `C:\\C:\\...` scratch-cache path problem exposed before extraction begins.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the extractor's module-symbol resolution path, where the global-only declaration currently fails, and compare the existing module and ambient-module fixture behavior. Use a self-contained global-only golden fixture to cover representative WebGPU declarations without network access. Done means extraction succeeds without importing @webgpu/types, generated bindings compile under the supported ReScript version, and existing fixtures remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.