Package surface cleanup: remove deprecated exports, split @xstate/scxml, fix files/exports and @xstate/svelte ESM - #5739
davidkpiano wants to merge 10 commits into
Conversation
…tStateNodes; add check:files
🦋 Changeset detectedLatest commit: 10a596a The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| const { createFSM } = require( | ||
| xstatePath.replace(/xstate(\.[^/\\]*)$/, 'xstate-fsm$1') | ||
| ); |
There was a problem hiding this comment.
🟡 Custom benchmark bundles lose FSM support
When --xstate has a nonstandard basename, the regex reloads that root bundle for createFSM. Root no longer exports createFSM, so every FSM benchmark fails.
Learn more
The benchmark accepts --xstate=<path> as its runtime input. Previously that file supplied every benchmark API, including createFSM. After the root export removal, the script derives a second path by rewriting only filenames beginning with xstate. Any otherwise valid custom bundle named index.js, core.js, or similar remains unchanged, so the script requires the root bundle twice and receives no createFSM.
Example: With --xstate=/tmp/candidate/index.js, the replacement still yields /tmp/candidate/index.js. The root APIs load, but makeFSMTarget() calls undefined and aborts the run.
Recommended fix: Add an explicit --xstate-fsm option or resolve the xstate/fsm subpath from a package directory. Keep filename rewriting only as a documented fallback, and fail early with a clear message when the FSM entry cannot be resolved.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const name = normalize(entry).replace(/\/$/, ''); | ||
| const fullPath = join(packagesDir, dir, name); | ||
| if (name === 'dist' || binDirs.has(name)) continue; | ||
| if (!existsSync(fullPath) || !statSync(fullPath).isDirectory()) continue; |
There was a problem hiding this comment.
🟡 Missing package paths bypass validation
When a listed package path is absent, check:files skips it instead of rejecting the stale manifest. Existing missing @xstate/store entries therefore pass the new gate.
Learn more
The files array controls what npm includes in a published tarball. A stale path is silently omitted by npm. The checker currently ignores the same absent path, so it cannot detect this package-surface drift. The repository already contains absent undo, persist, reset, and validate paths in the store manifest.
Example: @xstate/store lists undo, but no packages/xstate-store/undo directory exists. check:files exits successfully instead of identifying the stale entry.
Recommended fix: Report every nonexistent literal files path before checking whether an existing path is a directory. If glob patterns become supported later, expand them explicitly and reject patterns with no matches.
| if (!existsSync(fullPath) || !statSync(fullPath).isDirectory()) continue; | |
| if (!existsSync(fullPath)) { | |
| errors.push(`${pkg.name}: "files" includes missing path "${name}"`); | |
| continue; | |
| } | |
| if (!statSync(fullPath).isDirectory()) continue; |
Was this helpful? React with 👍 or 👎 to provide feedback.
Beta blocker B5. Four commits, one per item.
1. Deprecated exports removed
getInitialSnapshot,getNextSnapshot,NoInfer,AnyInterpreter,ResolvedStateMachineTypes.src/getNextSnapshot.ts→src/inertActorScope.ts(onlycreateInertActorScoperemained). Docs and the migration guide (§16) updated. Changesetxstateminor ("Removed").2.
files⊆exportsactions,invoke,guards,dev(and a staleactor/) were stub folders with no source and no importers; deleted and removed fromfiles. Newscripts/check-package-files.mjs(pnpm check:files) asserts every directory infileshas anexportsentry; CI step snippet in the PR notes below.createFSMis now exported only fromxstate/fsm(was also root). Rename for review:xstate/graph'sgetStateNodes(returns all descendants) collided with the rootgetStateNodes(stateNode, stateValue); the graph one is nowgetDescendantStateNodes. Changesetxstateminor.3.
@xstate/scxml(decided: split)New
packages/xstate-scxml(@xstate/scxml, peerxstate, dependencysaxes), laid out like@xstate/react. All SCXML source, tests (356), fixtures, and the SCION framework devDependency moved. Core loses./scxmlfromexports/files/preconstruct entrypoints, plussaxes,@scion-scxml/test-framework,pkg-up. Core is now dependency-free, so thebin/xstate.jsclaim is true. Core exposes_parseDelayToMilliseconds(@experimental) and_microstepHooksmoves from@internalto@experimentalso the package typechecks against built types.xstate/scxmlnow fails withERR_PACKAGE_PATH_NOT_EXPORTED. Changesetsxstateminor,@xstate/scxmlminor (first publish will be1.0.0-alpha.1).4.
@xstate/svelteexports map (#5243)Copying React's map would not fix it (same
import→ CJS-wrapper shape, and preconstruct cannot emit real ESM next to CJS). Svelte 5 is ESM-only, so the package is now ESM-only ("type": "module"), matching@xstate/store-svelte.require()works viarequire(esm)on Node 20.19+/22.12+. Verified by packing and importing/requiring from a temp dir;svelte-check0 errors. Changeset@xstate/sveltepatch.CI step to add (after #5735 lands)
Verification
pnpm build,pnpm test(3293),@xstate/scxmltests (356), typecheck (+ adapter-consumers, fsm-only, examples), check-built-types, lint, format, knip, check:files all pass. Bundle thresholds fail onnexttoday (pre-existing); this branch is within 2 B ofnext; #5735 resets them.