Repository navigation
fix: make the ESM bundle load under native Node, fix ConnectionChip in dark mode, and require React 18 - #1872
Conversation
js-yaml 5's ESM entry has named exports only, but the CustomCatalog and CatalogDetail helpers default-imported it. The CommonJS bundle and jest's interop papered over that, while any bundler linking dist/index.mjs failed with "No matching export ... for import 'default'". Import load/dump by name, and add a guard that bundles the built dist/index.mjs with esbuild (resolved through tsup) and asserts it links cleanly. It fails against a build of the old helpers with exactly that error, and follows the existing dist-guard contract: skip without a build, fail in CI without one. Signed-off-by: Sheikh Mohammad <182693777+winkletinkle@users.noreply.github.com>
permissions.tsx, which every Sistent Button depends on, calls React.useId, which exists only in React 18 and later. The package still advertised React 17 peer support, so a React 17 consumer installed cleanly and then crashed at render. Make the declared range match what the code actually requires. Signed-off-by: Sheikh Mohammad <182693777+winkletinkle@users.noreply.github.com>
The chip hardcoded a white background, black text and a fixed grey border, so on a dark page it rendered as a white slab and its delete icon vanished white-on-white. Resolve background, text and border from the active palette (background.card, text.default, border.strong); light mode is visually unchanged. Add a test pinning the resolved colors in both palette modes, and CSF3 stories rendering the chip on each mode's page background. Signed-off-by: Sheikh Mohammad <182693777+winkletinkle@users.noreply.github.com>
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. ⛔ Files ignored due to path filters: 1
⚙️ Run configuration
⛔ Files ignored due to path filters: 1
You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Signed-off-by: Sheikh Mohammad <182693777+winkletinkle@users.noreply.github.com>
Signed-off-by: Sheikh Mohammad <182693777+winkletinkle@users.noreply.github.com>
e1b8f06 to
908842f
Compare
Intent
Your standing instructions for this session are to merge when green and release as needed.
Context: while building the GitHub connection primitives for #1847 (merged in #1870), the worker found three pre-existing defects in this repo:
src/custom/CustomCatalog/Helper.tsand the CatalogDetailhelper.tsuseimport jsyaml from 'js-yaml'. The CommonJS build works; ESM resolution breaks.ConnectionChiphardcodes white and black colors, so it is broken in dark mode.package.jsonstill declares React 17 peer support, butReact.useId(React 18+) is already used bypermissions.tsx, which every Sistent Button depends on, so React 17 consumers are already broken.What Changed
import { load } from 'js-yaml'instead of the default import. js-yaml 5 has no default ESM export.debounceimports now point atlodash/debounce.js. This affectsSearchBar,StyledSearchBar,ShareModalandTeamSearchField.tsup.config.tsnow marks every dependency and peer dependency as external through a custom esbuild plugin.@meshery/schemasis still bundled. In the ESM build, inlined CommonJS that callsrequire()on an external (for exampleuse-sync-external-storerequiringreact) now gets a static import instead. Before, that call became a runtimerequirethat fails with "Dynamic require ... is not supported". The newesmBundleLoads.test.tsloadsdist/index.mjswith nativeimport()to guard this.ConnectionChipnow uses theme tokens instead of hardcoded black, white and#51636B. The text color istext.default, the border isborder.strongand the background isbackground.card, so the chip renders correctly in dark mode. The change addsConnectionChip.test.tsxand a light/dark Storybook story.reactandreact-dompeer ranges no longer include 17. They are now^18.0.0 || ^19.0.0.React.useId, whichpermissions.tsxalready uses (and every Sistent Button depends on), needs React 18. This is a consumer-visible change to the peer range.Risk Assessment
✅ Low: All three fixes are small and well-bounded. The two js-yaml imports now use named
load/dump, and no other default imports of js-yaml remain in src. ConnectionChip uses existing palette tokens the way sibling components do, and the peer range now matches the React 18 APIs the code already uses. The new tests check behavior: computed chip styles, and an actual esbuild ESM link of dist.Testing
I rebuilt the target, packed it and installed it into a throwaway consumer that has React 18 but neither optional peer. In that consumer, native Node ESM import, CJS require and SSR rendering of ConnectionChip (dark), SearchBar and Button all succeeded. Undoing the fix makes both a direct import and the new jest guard fail, so the guard does catch the regression. The packed tarball rejects a React 17 install. The js-yaml/esbuild link test, the ConnectionChip theme-token test, and the export-parity and optional-peer guards passed in jest, but those are not live runs, so the js-yaml and ConnectionChip theme-token scenarios are marked untested for this round. I took no new screenshots because this round only changed bundling and import paths. I removed the temporary consumer, the tarballs and dist/; the worktree is clean.
await import('@sistent/sistent/dist/index.mjs')under native Node ESM and gets the full export setrequire('@sistent/sistent')after the tsup externals changeEvidence: Native ESM + CJS + SSR in clean consumer, plus the fix-undone check
Evidence: Jest native-ESM guard failing on the fix-undone bundle
Evidence: React 17 install rejected by target tarball
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
package.json:108- Narrowing thereact/react-dompeer range from^17 || ^18 || ^19to^18 || ^19is consumer-visible. CLAUDE.md treats that as aminorrelease in this pre-1.0 package, and.github/release-drafter.ymldefaults topatch. The PR this run opens should carry theminorlabel, or the narrowed range ships as a patch. The source change is correct:React.useIdis already used at module-reachable paths insrc/custom/permissions.tsx:549,GitHubRepositoryPicker.tsx:62, andGitHubFileTree.tsx:125, so React 17 consumers already fail.🔧 **Test** - 3 issues found → auto-fixed ✅
src/__testing__/esmBundleLoads.test.ts- Existing ESM defect, related to the js-yaml fix: native Node ESMimport('@sistent/sistent/dist/index.mjs')fails in both base and change with ERR_MODULE_NOT_FOUND forlodash/debounce(an extensionless deep import that only resolves under CJS or bundlers). Bundlers (esbuild) link fine after this change, but Node-ESM/SSR consumers of index.mjs still break. Fix direction: importlodash/debounce.jsor{ debounce } from 'lodash-es', and extend esmBundleLoads.test.ts with a nativeimport()check.package.json- package.json has noexportsmap andmodulepoints at the CJS./dist/index.js, so by default consumer bundlers never select dist/index.mjs. The js-yaml ESM break only hit consumers who deep-import the .mjs file. Worth deciding whether index.mjs should be wired intomodule/exportsnow that it links.src/custom/ConnectionChip/ConnectionChip.tsx:31- Design nit seen in the screenshots: the dark chip surface (background.card, neutral #212121) sits on a blue-tinted page (#000d12), and the dark-mode delete icon uses MUI's default rgba(255,255,255,0.26), which is low contrast. Both are much better than before, but a tinted card token and a stronger delete-icon color would match the palette more closely.No matching export in js-yaml.mjs for import "default"at both catalog-helper sites; change exits 0. The browser-platform bundle also failed on…CI=1 npx jest src/__testing__/esmBundleLoads.test.tspasses on the changeCannot find module react/jsx-runtimefrom react-dnd (recorded in session transcript; temp consumer removed…npm ci && npm run build(change) andtsupon agit archive e6dd03e5copy (base), thennpm packfor eachClean-consumer installs of each tarball with react@17 and react@18 (npm install, thennpm install --legacy-peer-deps+npm ls react), plus a semver check of the packedpeerDependencies.reactRendered a sistent Button with react-dom/server in a react@17 consumer (base build) to check the React 17 claimesbuild bundle (format=esm, platform=node and browser) of a consumer app importing@sistent/sistent/dist/index.mjs, base vs changeNode native ESMimport('@sistent/sistent/dist/index.mjs'), base vs changeBrowser page (React 18 createRoot, SistentThemeProvider light+dark, ConnectionChip plain/clickable/deletable) bundled from each tarball and rendered in headless Chromium via playwright-core; screenshots + getComputedStyle capturedCI=1 npx jest src/__testing__/ConnectionChip.test.tsx src/__testing__/esmBundleLoads.test.tson the change (pass)CI=1 npx jest src/__testing__/esmBundleLoads.test.tsagainst the base build (fails with the js-yaml default-import error, so the guard reproduces the regression)🔧 Fix applied.
✅ Re-checked - no issues remain.
await import('@sistent/sistent/dist/index.mjs')under native Node ESM and gets the full export setrequire('@sistent/sistent')after the tsup externals changenpm run buildat c153b456, then a check that dist/index.mjs has no__require/'Dynamic require' left, still exports MESHERY_EXTENSION_CONTRACT_VERSION in index.js/index.mjs/index.d.ts/index.d.mts, and has no module-scope import of date-fns or @mui/x-date-pickers (only the lazyimport()remains)npm pack-> throwaway consumernpm install <tgz> react@18 react-dom@18(optional peers checked absent) ->node --input-type=module -e 'await import("@sistent/sistent/dist/index.mjs")'Same consumer:node -e 'require("@sistent/sistent")'(CJS)Same consumer:node ssr.mjs- renderToString of ConnectionChip in dark SistentThemeProvider, SearchBar (lodash/debounce.js) and Button (permissions useId) through the native ESM importAdversarial: same bundle withlodash/debounce.jsrewritten tolodash/debounce-> native import fails with ERR_MODULE_NOT_FOUNDAdversarial: dist/index.mjs in the worktree mutated the same way ->CI=true npx jest src/__testing__/esmBundleLoads.test.ts -t nativefails (1 failed), then restoredCI=true npx jest src/__testing__/esmBundleLoads.test.ts src/__testing__/ConnectionChip.test.tsx src/__testing__/declarationRuntimeExportParity.test.ts src/__testing__/optionalPeerDependencies.test.ts(36 passed)npm install --dry-run <target tgz> react@17 react-dom@17-> ERESOLVE; packed peer range is ^18.0.0 || ^19.0.0Compared against published @sistent/sistent@0.23.0: its index.mjs already imports node builtins path/process/url, so that is not new✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
Summary by CodeRabbit