juspay / juspay/blend-rescript

0.0.37: deleting ChartsTypes for the 33k-line HighchartsSharedTypes leaves an ambiguous namespace (67 colliding constructors)

Open
#133 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
ReScript
Stars
1
Forks
0
Avg merge
2h 48m
Merged PRs (30d)
4

Description

### Summary

Upgrading `@juspay/rescript-blend` from `0.0.37-beta.8` to `0.0.37` broke consumer code in ways that were not signalled by the version bump and are not recoverable by a mechanical rename. The largest cause is that `ChartsTypes` was **deleted** and folded into `HighchartsSharedTypes`, which is a 33,309-line module whose namespace is ambiguous.

We absorbed this in the Juspay Portal dashboard. Filing so the same shape of change can be caught before publish rather than after.

### 1. `ChartsTypes` was deleted, not deprecated

`src/ChartsTypes.res` exists in `0.0.37-beta.8` and is gone in `0.0.37`. Its contents now live in `HighchartsSharedTypes`. Every consumer reference (`ChartsTypes.chartType`, `ChartsTypes.axisConfig`, `ChartsTypes.newNestedDataPoint`, …) fails to resolve, with no deprecation window.

### 2. `HighchartsSharedTypes` is not usable as a drop-in replacement

The obvious fix — alias the new module, or rename references to it — does not work, because the merge collapsed many small type modules into one namespace:

- **33,309 lines**, **404 distinct constructors**, of which **67 collide**.
- ReScript resolves a name to the **last** definition, so even a *fully qualified* reference silently binds to the wrong type:

| Constructor | Resolves to | What consumers actually want |
|---|---|---|
| `Percentage` | `optionsUnitValue` (L327) | `axisType` (L14) |
| `Number` | `optionsColumnTypesValue` (L203) | `axisType` (L15) |
| `Top` | `chartsSeriesOrganizationOptionsNodeAlignment` (L311) | `chartLegendPosition` (L17) |
| `Right` | `chartsSeriesOrganizationOptionsHangingSide` (L305) | `chartLegendPosition` (L18) |

`Right` has **five** definitions; `X`, `Y` and `Str` have **seven** each.

```rescript
// Looks correct, compiles, and is wrong:
Blend.HighchartsSharedTypes.Percentage // => optionsUnitValue.Percentage
```

- **`open` is unusable.** The module defines `None` twice (`cursorValue` L114, `optionsApproximationValue` L294), so `open HighchartsSharedTypes` shadows the stdlib `None`/`Some` and breaks every `option` in the file.
- **Record fields collide too.** `{name, data}` resolves to a record whose `data` is `string`, not `Dict.t`.

The only way through is to pin the expected type at every binding that touches an ambiguous name:

```rescript
let type_: option = switch metricType {
| Rate => Some(Blend.HighchartsSharedTypes.Percentage) // now correct
...
```

### 3. Other unsignalled breaking changes in the same bump

| Binding | `0.0.37-beta.8` | `0.0.37` |
|---|---|---|
| `Sidebar.data` | `Nullable.t>` | `array` |
| `DateRangePicker.customDisableDates` | `Date.t => bool` | `(Date.t, option) => bool` |
| `HighchartsSharedTypes.chart` | 1 type param | 3 type params |
| `HighchartsSharedTypes.options` | 1 type param | 3 type params |
| `DistTypes.highchartsReactRefObject` | 1 type param | 3 type params |

### What we'd like going forward

1. **Don't delete a public type module in a patch release.** Keep the old module as a thin re-export (`type chartType = HighchartsSharedTypes.chartType = | @as("line") Line | …`) for at least one release, marked `@deprecated`.
2. **Keep generated type modules narrow and unambiguous.** A per-component `ChartsTypes` was fine precisely because its namespace was small. If a merged module is unavoidable, please make the generator detect duplicate constructor/field names and either namespace them or fail the build — a module that can't be `open`ed and whose qualified names resolve to the wrong type is not a usable public API.
3. **Signal binding-level breaking changes.** Prop type changes (nullability, callback arity, type-param arity) aren't visible in the changelog today. A generated "breaking bindings" diff between releases would let consumers scope the upgrade before starting it.
4. **Reflect breakage in the version.** `0.0.37-beta.8 → 0.0.37` reads as a release-candidate promotion; it removed a public module.

Happy to send a PR for (1) if that's the direction you'd take.

Contributor guide

Open the contributing guide

Research direction

Start by comparing src/ChartsTypes.res from 0.0.37-beta.8 with the generated HighchartsSharedTypes module in 0.0.37, then review the listed binding changes and constructor collisions. A complete fix should preserve a usable public type API and provide a way to detect or signal the breaking changes before release.

Written by the indexing model from the issue text.

Assessment

Domain
api
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.