UNPKG

optimade

Version:

Aggregating Optimade client for the online materials databases

48 lines (36 loc) 6.1 kB
## Context The `optimade` package is published via `npm publish`, which triggers `prepublishOnly``npm run build && npm run prefetch`. On the current development machine (Node 22, npm 10) this pipeline exits non-zero, blocking releases. Root-cause analysis identified two independent dependency incompatibilities rather than a source-code defect: 1. **Build step crash.** `rollup-plugin-typescript2@0.28.0` declares a default `include` of `["*.ts+(|x)", "**/*.ts+(|x)"]`. It resolves `@rollup/pluginutils@3.1.0`, whose picomatch does not interpret the `+(|x)` extglob the way rpt2 expects. The internal `filter(id)` therefore returns `false` for `src/index.ts`, the `transform` hook returns `undefined`, and rollup's native acorn parser then chokes on TypeScript syntax (`import type * as Types from './types';`) with `Unexpected token`. Confirmed by tracing the `transform` hook and observing it return `undefined`; the same file transforms correctly once pluginutils is upgraded. 2. **Prefetch step crash.** `prefetch.js` does `global.AbortController = require('node-abort-controller').AbortController` before requiring `./dist/index`. The polyfill's `AbortSignal` is not the native `AbortSignal` that undici (Node's built-in `fetch`) binds to its internal `EventEmitter`. When `fetchWithTimeout` fires `ac.abort()` after the timeout, undici calls `this.removeEventListener(...)` on its own internal controller and throws `TypeError: this.removeEventListener is not a function`, crashing the process. Removing the polyfill override and using the native `AbortController` (available since Node 18) eliminates the crash; individual provider JSON errors are already swallowed by the existing `catch` blocks in `src/index.ts`. Constraints: no public API change, no source change in `src/utils.ts`, must keep producing `dist/index.mjs` (ESM) and `dist/index.js` (UMD) via the existing rollup config. ## Goals / Non-Goals **Goals:** - `npm publish --dry-run` and `npm publish` complete `prepublishOnly` with exit code 0 on Node 18+. - `rollup --config` transforms `src/index.ts` and emits both `dist/index.mjs` and `dist/index.js`. - `prefetch.js` runs to completion without a `removeEventListener` crash; transient per-provider HTTP/JSON errors remain non-fatal (as today). - Minimize churn: keep the existing `rollup.config.js` structure and `src/` untouched. **Non-Goals:** - Rewriting the build to a newer rollup major (3.x/4.x) or to `@rollup/plugin-typescript`. - Replacing `isomorphic-unfetch` or restructuring `fetchWithTimeout`. - Hardening `prefetch.js` against malformed provider responses beyond the existing `catch` behavior. - Adding CI or a Node engines constraint beyond what already exists (though `engines` may be noted as a follow-up). ## Decisions **Decision 1 — Bump `rollup-plugin-typescript2` to `^0.37.0` rather than pinning a workaround.** - Rationale: 0.37 depends on `@rollup/pluginutils@^4`, whose micromatch matches `**/*.ts+(|x)`, restoring the `transform` hook for `.ts` files. Verified empirically: after the upgrade, `npm run build` emits both output files in ~400ms. - Alternatives considered: - Pass an explicit `include: ['src/**/*.ts', 'src/**/*.tsx']` to `typescript()` in `rollup.config.js` and keep rpt2 0.28. This fixes the filter but leaves the package on an unmaintained rpt2 with known incompatibilities. Rejected: more invasive (config edit) and leaves stale dependency. - Switch to `@rollup/plugin-typescript`. Rejected: requires `tslib` wiring and a config rewrite, larger blast radius for a publish fix. - Trade-off: 0.37 keeps `rollup >= 1.26.3` as a peer, so it stays compatible with the pinned `rollup ^2.47.0`. No rollup upgrade required. **Decision 2 — Remove `node-abort-controller` entirely (dependency + override) rather than keeping it guarded.** - Rationale: `AbortController` and `fetch` are global on Node 18+. The package already depends on a native `fetch` (via `isomorphic-unfetch` in the browser path and undici in Node). The polyfill is actively harmful on supported Node versions because undici assumes a native signal. - Alternatives considered: - Guard the override with `if (!global.AbortController)`. Rejected: keeps a dead dependency in `dependencies` (ship weight) and the polyfill is still wrong if ever loaded on a modern runtime. - Bump `node-abort-controller` to a newer major. Rejected: the project does not need a polyfill at all on Node 18+; newer majors of that package also just re-export the native impl on modern Node. - Trade-off: drops support for Node < 18 for the `prefetch.js` script. Acceptable because Node 16 is EOL and the native `fetch` path already requires a modern runtime. The library code (`src/utils.ts`) is unchanged and continues to use the global `AbortController`. **Decision 3 — Keep `rollup.config.js`, `tsconfig.json`, and `src/` untouched.** - Rationale: the failure is purely dependency/toolchain-side. Editing source would expand scope and risk changing published behavior. ## Risks / Trade-offs - [Node < 18 users running `prefetch.js`] → Mitigation: native `AbortController` is required; this is the same baseline Node's own `fetch` requires. Document in the change that the prefetch script targets Node 18+. (The published library itself does not invoke `prefetch.js`.) - [`rollup-plugin-typescript2@0.37` brings `tslib@^2` as a runtime dependency of the plugin] → Mitigation: `tslib` is only used by rpt2 internals; the emitted bundle does not import `tslib` unless `importHelpers` is set (it is not in `tsconfig.json`). Verified by inspecting emitted `dist/index.mjs`. - [Transient provider-side errors during `prefetch.js` still print stack traces] → Non-fatal: these are caught by existing `try/catch` blocks in `addProvider`/`getProviders`; the script continues and writes its output. Out of scope to silence. - [npm transitive dedupe leaves `@rollup/pluginutils@3` for `@rollup/plugin-json@4`] → Acceptable: rpt2 now resolves its own `@rollup/pluginutils@4`; the two copies coexist without conflict (confirmed via `npm ls @rollup/pluginutils`).