Affected versions
@perspective-dev/viewer-datagrid 5.2.0 and 5.3.0 (verified in both published tarballs).
@perspective-dev/viewer-charts 5.2.0 and 5.3.0 have the related-but-worse variant: no dependencies field at all.
What happens
@perspective-dev/viewer-datagrid's published package.json (5.3.0):
"dependencies": {
"@perspective-dev/client": "",
"@perspective-dev/viewer": "",
"regular-table": "=0.9.0"
}
The empty string is a valid semver range that matches any version (equivalent to *). So the plugin never constrains which client/viewer it runs against. @perspective-dev/viewer-charts goes further — its published package.json declares no dependencies at all, while its ESM bundle (dist/esm/perspective-viewer-charts.js) imports @perspective-dev/viewer; it works only via hoisting.
Consequence: when a consumer bumps the top-level packages 5.2.0 → 5.3.0, a stale pnpm lockfile legitimately keeps the old viewer resolved for the plugin subtree — the empty range is satisfied by 5.2.0, so pnpm has no reason to re-resolve it. Result: two viewer copies in one node_modules.
Reproduction
- Install
@perspective-dev/viewer@5.2.0 + @perspective-dev/viewer-datagrid@5.2.0 with pnpm; commit the lockfile.
- Bump only the top-level specifiers to 5.3.0 and
pnpm install (no pnpm update/dedupe).
node_modules/.pnpm now contains both @perspective-dev+viewer@5.2.0... and @perspective-dev+viewer@5.3.0...; the datagrid subtree still links 5.2.0 because "" is satisfied.
Affected versions
@perspective-dev/viewer-datagrid5.2.0 and 5.3.0 (verified in both published tarballs).@perspective-dev/viewer-charts5.2.0 and 5.3.0 have the related-but-worse variant: nodependenciesfield at all.What happens
@perspective-dev/viewer-datagrid's publishedpackage.json(5.3.0):The empty string is a valid semver range that matches any version (equivalent to
*). So the plugin never constrains whichclient/viewerit runs against.@perspective-dev/viewer-chartsgoes further — its publishedpackage.jsondeclares nodependenciesat all, while its ESM bundle (dist/esm/perspective-viewer-charts.js) imports@perspective-dev/viewer; it works only via hoisting.Consequence: when a consumer bumps the top-level packages 5.2.0 → 5.3.0, a stale pnpm lockfile legitimately keeps the old viewer resolved for the plugin subtree — the empty range is satisfied by 5.2.0, so pnpm has no reason to re-resolve it. Result: two viewer copies in one
node_modules.Reproduction
@perspective-dev/viewer@5.2.0+@perspective-dev/viewer-datagrid@5.2.0with pnpm; commit the lockfile.pnpm install(nopnpm update/dedupe).node_modules/.pnpmnow contains both@perspective-dev+viewer@5.2.0...and@perspective-dev+viewer@5.3.0...; the datagrid subtree still links 5.2.0 because""is satisfied.