Problem
eventsource-parser is held at major 3 (clients/ts/package.json: "^3.1.0"), with a version-update:semver-major ignore in .github/dependabot.yml. It is @wavehouse/sdk's only runtime dependency, so this pin is worth an owner rather than a YAML comment.
eventsource-parser@4.0.0 (2026-08-10) is not a normal major — it drops the CJS build:
|
exports["."] |
3.1.0 |
{ import, require: "./dist/index.cjs", default } — dual |
4.0.0 |
{ source, default: "./dist/index.js" } — ESM only, no require condition |
and raises engines.node from >=18.0.0 to >=22.12.
Those two changes are the same decision: Node 22.12 is where require(esm) became unflagged, so upstream dropped CJS and set the floor to match.
Why that breaks us
@wavehouse/sdk ships a CJS build and does not bundle this dependency:
clients/ts/package.json: main: "./dist/index.cjs", exports["."].require: "./dist/index.cjs"
clients/ts/dist/index.cjs contains a literal require("eventsource-parser") (tsup externalises dependencies by default)
clients/ts/package.json: engines.node: ">=22"
So on v4:
- Node >= 22.12 — fine,
require(esm) resolves it
- Node 22.0 – 22.11 —
ERR_REQUIRE_ESM; the SDK's CJS entry point is broken
That window sits inside our advertised support range, and >=22 is a deliberate choice (see the CHANGELOG entry "@wavehouse/sdk engines.node floor back to >=22, matching the only line we test").
The API surface is unaffected — clients/ts/src/stream/sse.ts uses only createParser({ onEvent }) and parser.feed(), which v4 keeps. This is purely a packaging/engines break, so holding at v3 costs nothing functionally.
Drop condition — a decision, not a wait
Take v4 when we do one of:
- Raise
@wavehouse/sdk's engines.node to >=22.12 — narrows supported Node for a published package; reverses the >=22 decision above.
- Stop shipping a CJS build — drop
cjs from format in clients/ts/tsup.config.ts and the require/main fields. Defensible given Node 22.12+ can require() ESM, but it's a breaking change for consumers on older bundler setups.
Either is user-visible, which is why it shouldn't ride in on a dependency bump. Once decided, remove the eventsource-parser ignore from .github/dependabot.yml.
Why CI didn't catch it
Nothing exercises the CJS entry point. .nvmrc is 22, which resolves to the latest 22.x (22.23.x — above 22.12), and every test runs ESM. #491 went fully green while proposing exactly this break.
Suggested guard, whether or not we take v4:
node -e 'require("./clients/ts/dist/index.cjs")'
as a post-build smoke check, ideally under the oldest Node we claim to support rather than .nvmrc's floating 22.x. That would have caught this and will catch the next one. Split into its own issue if it deserves one.
Context
Surfaced reviewing Dependabot #491, which bundled this major with two harmless minors. The minors were taken separately; this row was held.
Problem
eventsource-parseris held at major 3 (clients/ts/package.json:"^3.1.0"), with aversion-update:semver-majorignore in.github/dependabot.yml. It is@wavehouse/sdk's only runtime dependency, so this pin is worth an owner rather than a YAML comment.eventsource-parser@4.0.0(2026-08-10) is not a normal major — it drops the CJS build:exports["."]3.1.0{ import, require: "./dist/index.cjs", default }— dual4.0.0{ source, default: "./dist/index.js" }— ESM only, norequireconditionand raises
engines.nodefrom>=18.0.0to>=22.12.Those two changes are the same decision: Node 22.12 is where
require(esm)became unflagged, so upstream dropped CJS and set the floor to match.Why that breaks us
@wavehouse/sdkships a CJS build and does not bundle this dependency:clients/ts/package.json:main: "./dist/index.cjs",exports["."].require: "./dist/index.cjs"clients/ts/dist/index.cjscontains a literalrequire("eventsource-parser")(tsup externalisesdependenciesby default)clients/ts/package.json:engines.node: ">=22"So on v4:
require(esm)resolves itERR_REQUIRE_ESM; the SDK's CJS entry point is brokenThat window sits inside our advertised support range, and
>=22is a deliberate choice (see the CHANGELOG entry "@wavehouse/sdkengines.nodefloor back to>=22, matching the only line we test").The API surface is unaffected —
clients/ts/src/stream/sse.tsuses onlycreateParser({ onEvent })andparser.feed(), which v4 keeps. This is purely a packaging/engines break, so holding at v3 costs nothing functionally.Drop condition — a decision, not a wait
Take v4 when we do one of:
@wavehouse/sdk'sengines.nodeto>=22.12— narrows supported Node for a published package; reverses the>=22decision above.cjsfromformatinclients/ts/tsup.config.tsand therequire/mainfields. Defensible given Node 22.12+ canrequire()ESM, but it's a breaking change for consumers on older bundler setups.Either is user-visible, which is why it shouldn't ride in on a dependency bump. Once decided, remove the
eventsource-parserignore from.github/dependabot.yml.Why CI didn't catch it
Nothing exercises the CJS entry point.
.nvmrcis22, which resolves to the latest 22.x (22.23.x — above 22.12), and every test runs ESM. #491 went fully green while proposing exactly this break.Suggested guard, whether or not we take v4:
node -e 'require("./clients/ts/dist/index.cjs")'as a post-build smoke check, ideally under the oldest Node we claim to support rather than
.nvmrc's floating 22.x. That would have caught this and will catch the next one. Split into its own issue if it deserves one.Context
Surfaced reviewing Dependabot #491, which bundled this major with two harmless minors. The minors were taken separately; this row was held.