Sync JavaScript packages alongside Python and Rust members - #30
Draft
ncoop57 wants to merge 4 commits into
Draft
Conversation
A package.json in a workspace repo dir, or in an immediate subdirectory of one, makes that dir a JS member (felt/package.json, mdhtml/wasm/package.json); node_modules, pkg, and _-prefixed dirs are skipped. Each sync regenerates the workspaces list in the root package.json, creating it the first time a member exists and keeping entries that point outside the root or use globs, then runs the package manager's install at the root after uv sync so members resolve their siblings through the root node_modules symlinks: the npm analog of editable installs. A member with a Cargo.toml beside its package.json is a native package. Sync runs its build script when pkg/ is missing or older than any source in the member's repo, the parent crate included: the JS analog of maturin develop. The package manager is npm unless [tool.fastws] sets js = "bun" or "pnpm". A checkout that is only a JS package is a valid member: it is auto-excluded from the uv workspace like a Cargo-only crate and never counts as a pending scaffold, which is what stopped sync early on felt. _fastws_cfg moves from releases to core so both read the table the same way. Claude-Session: https://claude.ai/code/session_01KCKXyYZu5R6fnPbTx3pMmo
A subdirectory of a repo dir joins the JS workspace only when a Cargo.toml sits beside its package.json, so example and frontend folders inside other repos (ghapi/examples, solveit/frontend) stay out, and `[tool.fastws].exclude` now applies to JS members too. `_js_tool` accepts npm or bun only, `_sync_js` stops with a message when the tool is not installed, and the package.json docstring says that only the list form of `workspaces` is managed. On the real workspace, `_npm_dirs` returns exactly felt and mdhtml/wasm. Claude-Session: https://claude.ai/code/session_01KCKXyYZu5R6fnPbTx3pMmo
A subdirectory package is a member unless it has its own lockfile or matches an exclude path. The Cargo.toml check now only decides which members get a build. Claude-Session: https://claude.ai/code/session_01KCKXyYZu5R6fnPbTx3pMmo
A Vite app in the workspace must set server.fs.allow to the workspace root when a linked package fetches a file at runtime, such as a .wasm. The symlink resolves to the sibling checkout, which SvelteKit's default allow list does not cover.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft until Nathan has reviewed it.
ws-syncnow brings JavaScript packages into the workspace the way it brings in Python projects and Rust crates.Discovery
package.jsonin a workspace repo dir makes that dir a member (felt/package.json).package.jsonis also a member (mdhtml/wasm), unless it has its own lockfile (bun.lock,package-lock.json,yarn.lock, orpnpm-lock.yaml, a package that manages itself) or its root-relative path matches[tool.fastws].exclude(ghapi/examples).node_modules,pkg, and_-prefixed dirs. Sync prints the members it adds, which makes a stray package visible the first time.Sync
workspaceslist in the rootpackage.json. It creates the file the first time a member exists and keeps entries that point outside the root or use globs.uv syncit runs the package manager'sinstallat the root. Every member then resolves its siblings through the rootnode_modulessymlinks, the npm analog of editable installs.Cargo.tomlbeside itspackage.jsonis a native package (a wasm build). Sync runs itsbuildscript whenpkg/is missing or older than any source in the member's repo, the parent crate included. This is the JS analog ofmaturin develop.npmunless[tool.fastws]setsjs = "bun". Both read the sameworkspacesfield. Sync stops with a message when the chosen tool is not installed.Refactors
_fastws_cfgmoves fromreleases.pytocore.py. Both modules share it._src_mtimetakes askipset. The JS staleness check uses it to ignorenode_modulesandpkg._pending_dirsextracts the pending-scaffold check that guardsuv sync.New tests in
tests/test_sync.pycover discovery, excludes, tool selection,package.jsonregeneration, and the install-then-build pass.