diff --git a/.github/workflows/check-js.yaml b/.github/workflows/check-js.yaml index 21368019..017bd65d 100644 --- a/.github/workflows/check-js.yaml +++ b/.github/workflows/check-js.yaml @@ -4,13 +4,13 @@ on: push: branches: [main] paths: - - "js/**/*" + - "pkg-js/**/*" - "pkg-py/src/shinyreact/www/**" - "pkg-r/inst/lib/shiny/**" - ".github/workflows/check-js.yaml" pull_request: paths: - - "js/**/*" + - "pkg-js/**/*" - "pkg-py/src/shinyreact/www/**" - "pkg-r/inst/lib/shiny/**" - ".github/workflows/check-js.yaml" @@ -27,7 +27,7 @@ jobs: - name: 🔎 Extract node version from .nvmrc id: nvm - working-directory: js + working-directory: pkg-js run: | echo "version=$(cat .nvmrc)" >> $GITHUB_OUTPUT @@ -57,7 +57,7 @@ jobs: - name: 🔎 Extract node version from .nvmrc id: nvm - working-directory: js + working-directory: pkg-js run: | echo "version=$(cat .nvmrc)" >> $GITHUB_OUTPUT diff --git a/.gitignore b/.gitignore index 618723e3..b27ab688 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ __pycache__/ build/ develop-eggs/ dist/ -!js/dist/ +!pkg-js/dist/ downloads/ eggs/ .eggs/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7c43f4f0..ad7359f7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,9 +3,9 @@ repos: rev: v6.0.0 hooks: - id: trailing-whitespace - exclude: ^(js/dist/|pkg-py/src/shinyreact/www/|pkg-r/inst/lib/shiny/) + exclude: ^(pkg-js/dist/|pkg-py/src/shinyreact/www/|pkg-r/inst/lib/shiny/) - id: end-of-file-fixer - exclude: ^(js/dist/|pkg-py/src/shinyreact/www/|pkg-r/inst/lib/shiny/) + exclude: ^(pkg-js/dist/|pkg-py/src/shinyreact/www/|pkg-r/inst/lib/shiny/) - id: check-yaml - id: check-merge-conflict - id: check-added-large-files diff --git a/CLAUDE.md b/CLAUDE.md index affa259c..ae49e832 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,7 +19,7 @@ The repo ships one first-class pattern: the **`ui.tsx` pattern** — `set_react_ ## Repo structure ``` -js/ # TypeScript/React Vite IIFE bundle +pkg-js/ # TypeScript/React Vite IIFE bundle src/ # index.ts, global.ts, shiny-output.tsx, shiny.d.ts, shinyreact.css dist/ # Built assets (committed to repo) src/shiny-react/ # Vendored @posit/shiny-react source (hooks, registries) @@ -43,11 +43,11 @@ Makefile # All build/check/format commands ```bash # Initial setup uv sync --all-extras --all-groups # Python env -make js-setup # JS deps (cd js && npm install) +make js-setup # JS deps (cd pkg-js && npm install) pre-commit install # Pre-commit hooks # Build -make js-build # Build JS bundle (js/dist/) +make js-build # Build JS bundle (pkg-js/dist/) make update-dist # Build JS + copy to pkg-py/www/ and pkg-r/inst/lib/shiny/ # Python checks (run all before committing) @@ -78,7 +78,7 @@ Run `make help` to see all targets. ### JS bundle -The JS output (`js/dist/shinyreact.js`) is a self-contained IIFE that bundles React 19 and vendored `@posit/shiny-react`, and installs the public API at `window.shinyreact`. +The JS output (`pkg-js/dist/shinyreact.js`) is a self-contained IIFE that bundles React 19 and vendored `@posit/shiny-react`, and installs the public API at `window.shinyreact`. **Global API exposed at `window.shinyreact`:** - `useShinyInput`, `useShinyInputValue`, `useSetShinyInput`, `useShinyOutputValue`, `useShinyOutputStatus`, `useShinyMessageHandler`, `useShinyInitialized`, `useShinyBusy` — re-exported shiny-react hooks @@ -109,7 +109,7 @@ The deliberate remaining divergences (decided in #184) are recorded in `decision ### Built assets -`js/dist/` and `pkg-py/src/shinyreact/www/` are both committed to the repo. After changing JS source, run `make update-dist` to rebuild and copy. `pkg-r/inst/lib/shiny/` is the R counterpart (same flow). +`pkg-js/dist/` and `pkg-py/src/shinyreact/www/` are both committed to the repo. After changing JS source, run `make update-dist` to rebuild and copy. `pkg-r/inst/lib/shiny/` is the R counterpart (same flow). ### Build backend @@ -271,7 +271,7 @@ When fixing a bug, add or update unit tests to cover the fix whenever possible. - **Python tests:** `pkg-py/tests/` — run with `make py-check-tests` - **R tests:** `pkg-r/tests/testthat/` — run with `make r-check-tests` -- **JS tests:** `js/src/shiny-react/__tests__/` — run with `cd js && npx vitest run` +- **JS tests:** `pkg-js/src/shiny-react/__tests__/` — run with `cd pkg-js && npx vitest run` - **Playwright e2e tests:** `pkg-py/tests/playwright/` — run with `make py-test-e2e`. The `[tool.pytest.ini_options]` block ignores this subtree by default so `make py-check-tests` stays fast; `py-test-e2e` clears that with `-o addopts=`. **Adding a new e2e test:** see [`.claude/references/playwright-e2e-tests.md`](.claude/references/playwright-e2e-tests.md) for the fixture-app layout, the four traps that bit us while writing the suite, and the canonical assertion patterns. ### Cover both R and Python @@ -301,5 +301,5 @@ R currently has no e2e suite; that gap is tracked in #194, so Playwright tests a ## Key decisions - `decisions/` contains architecture decision records. `decisions/2026-03-17-playwright-testing-architecture.md` documents the recommended approach (code-gen from TypeScript) for future browser testing — not yet implemented. -- `shiny-react` is vendored at `js/src/shiny-react/` rather than installed as an npm dependency (commit `4137071`). +- `shiny-react` is vendored at `pkg-js/src/shiny-react/` rather than installed as an npm dependency (commit `4137071`). - The app.py pattern (server-side JSON-spec rendering: `Node`/`node()`, `render_react`, `output_react`, `page_react`, the JS renderer/registry, and the `shinyui` prototype) was removed in #168. History pointers live in a comment on #167. diff --git a/Makefile b/Makefile index 91098c9e..fe03b5ae 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ QUARTO_VERSION ?= 1.8.27 QUARTO_PATH = ~/.local/share/qvm/versions/v${QUARTO_VERSION}/bin/quarto PATH_PKG_R := pkg-r PATH_PKG_PY := pkg-py -PATH_PKG_JS := js +PATH_PKG_JS := pkg-js .PHONY: install-quarto install-quarto: diff --git a/README.md b/README.md index 01ffc09d..2cb446fa 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The bundle re-exports these hooks from `@posit/shiny-react`: ## Architecture -- **JS bundle** (`js/dist/shinyreact.js`): Self-contained IIFE bundling React 19 and vendored `@posit/shiny-react`, exposing the hook API at `window.shinyreact`. Shared by both language packages. +- **JS bundle** (`pkg-js/dist/shinyreact.js`): Self-contained IIFE bundling React 19 and vendored `@posit/shiny-react`, exposing the hook API at `window.shinyreact`. Shared by both language packages. - **Python package** (`pkg-py/`): `set_react_page()` / `page_react_html()` page entry points, the `reactive_output` renderer, `send_message()`, built-in input handlers, and bookmark restore support. - **R package** (`pkg-r/`): `page_react_html()`, `reactive_output()`, `send_message()`, the same input handlers and bookmark support. Same JS bundle as Python. diff --git a/docs/posit-conf-2026-goals.md b/docs/posit-conf-2026-goals.md index c624c124..5f29f950 100644 --- a/docs/posit-conf-2026-goals.md +++ b/docs/posit-conf-2026-goals.md @@ -43,7 +43,7 @@ Remaining known issues are tracked in the [GitHub issue tracker](https://github. ### 2. Migrate Shiny JavaScript to its own repo -The vendored `shiny-react` code at `js/src/shiny-react/` and the broader Shiny JS infrastructure should live in its own repository, independent of `shinyreact`. This enables: +The vendored `shiny-react` code at `pkg-js/src/shiny-react/` and the broader Shiny JS infrastructure should live in its own repository, independent of `shinyreact`. This enables: - Other packages (not just `shinyreact`) to depend on shiny-react - Independent versioning and release cycle diff --git a/examples/09-hmr/src/shiny-bridge.dev.ts b/examples/09-hmr/src/shiny-bridge.dev.ts index 8f313477..8b412dac 100644 --- a/examples/09-hmr/src/shiny-bridge.dev.ts +++ b/examples/09-hmr/src/shiny-bridge.dev.ts @@ -2,11 +2,11 @@ // with this example's OWN dev React (Fast Refresh needs a dev React build; // window.shinyreact.React is production). `resolve.dedupe` in vite.config keeps // these and App.tsx on a single React copy. The relative path reaches the -// vendored source at the repo's js/src/shiny-react/ (served thanks to +// vendored source at the repo's pkg-js/src/shiny-react/ (served thanks to // server.fs.allow in vite.config). Downstream apps would import a published // @posit/shiny-react instead. export { useShinyInitialized, useShinyInput, useShinyOutputValue, -} from "../../../../js/src/shiny-react/index"; +} from "../../../../pkg-js/src/shiny-react/index"; diff --git a/js/.nvmrc b/pkg-js/.nvmrc similarity index 100% rename from js/.nvmrc rename to pkg-js/.nvmrc diff --git a/js/dist/shinyreact.css b/pkg-js/dist/shinyreact.css similarity index 100% rename from js/dist/shinyreact.css rename to pkg-js/dist/shinyreact.css diff --git a/js/dist/shinyreact.js b/pkg-js/dist/shinyreact.js similarity index 100% rename from js/dist/shinyreact.js rename to pkg-js/dist/shinyreact.js diff --git a/js/package-lock.json b/pkg-js/package-lock.json similarity index 100% rename from js/package-lock.json rename to pkg-js/package-lock.json diff --git a/js/package.json b/pkg-js/package.json similarity index 100% rename from js/package.json rename to pkg-js/package.json diff --git a/js/src/.gitkeep b/pkg-js/src/.gitkeep similarity index 100% rename from js/src/.gitkeep rename to pkg-js/src/.gitkeep diff --git a/js/src/__tests__/shiny-output.test.tsx b/pkg-js/src/__tests__/shiny-output.test.tsx similarity index 100% rename from js/src/__tests__/shiny-output.test.tsx rename to pkg-js/src/__tests__/shiny-output.test.tsx diff --git a/js/src/global.ts b/pkg-js/src/global.ts similarity index 100% rename from js/src/global.ts rename to pkg-js/src/global.ts diff --git a/js/src/index.ts b/pkg-js/src/index.ts similarity index 100% rename from js/src/index.ts rename to pkg-js/src/index.ts diff --git a/js/src/shiny-output.tsx b/pkg-js/src/shiny-output.tsx similarity index 100% rename from js/src/shiny-output.tsx rename to pkg-js/src/shiny-output.tsx diff --git a/js/src/shiny-react/ImageOutput.tsx b/pkg-js/src/shiny-react/ImageOutput.tsx similarity index 100% rename from js/src/shiny-react/ImageOutput.tsx rename to pkg-js/src/shiny-react/ImageOutput.tsx diff --git a/js/src/shiny-react/LICENSE b/pkg-js/src/shiny-react/LICENSE similarity index 100% rename from js/src/shiny-react/LICENSE rename to pkg-js/src/shiny-react/LICENSE diff --git a/js/src/shiny-react/ShinyModuleContext.tsx b/pkg-js/src/shiny-react/ShinyModuleContext.tsx similarity index 100% rename from js/src/shiny-react/ShinyModuleContext.tsx rename to pkg-js/src/shiny-react/ShinyModuleContext.tsx diff --git a/js/src/shiny-react/ShinyReactComponentElement.tsx b/pkg-js/src/shiny-react/ShinyReactComponentElement.tsx similarity index 100% rename from js/src/shiny-react/ShinyReactComponentElement.tsx rename to pkg-js/src/shiny-react/ShinyReactComponentElement.tsx diff --git a/js/src/shiny-react/__tests__/ImageOutput.test.tsx b/pkg-js/src/shiny-react/__tests__/ImageOutput.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/ImageOutput.test.tsx rename to pkg-js/src/shiny-react/__tests__/ImageOutput.test.tsx diff --git a/js/src/shiny-react/__tests__/ShinyModuleContext.test.tsx b/pkg-js/src/shiny-react/__tests__/ShinyModuleContext.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/ShinyModuleContext.test.tsx rename to pkg-js/src/shiny-react/__tests__/ShinyModuleContext.test.tsx diff --git a/js/src/shiny-react/__tests__/ShinyReactComponentElement.test.tsx b/pkg-js/src/shiny-react/__tests__/ShinyReactComponentElement.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/ShinyReactComponentElement.test.tsx rename to pkg-js/src/shiny-react/__tests__/ShinyReactComponentElement.test.tsx diff --git a/js/src/shiny-react/__tests__/input-registry.test.ts b/pkg-js/src/shiny-react/__tests__/input-registry.test.ts similarity index 100% rename from js/src/shiny-react/__tests__/input-registry.test.ts rename to pkg-js/src/shiny-react/__tests__/input-registry.test.ts diff --git a/js/src/shiny-react/__tests__/output-registry.test.ts b/pkg-js/src/shiny-react/__tests__/output-registry.test.ts similarity index 100% rename from js/src/shiny-react/__tests__/output-registry.test.ts rename to pkg-js/src/shiny-react/__tests__/output-registry.test.ts diff --git a/js/src/shiny-react/__tests__/use-shiny-busy.test.tsx b/pkg-js/src/shiny-react/__tests__/use-shiny-busy.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/use-shiny-busy.test.tsx rename to pkg-js/src/shiny-react/__tests__/use-shiny-busy.test.tsx diff --git a/js/src/shiny-react/__tests__/use-shiny-initialized.test.tsx b/pkg-js/src/shiny-react/__tests__/use-shiny-initialized.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/use-shiny-initialized.test.tsx rename to pkg-js/src/shiny-react/__tests__/use-shiny-initialized.test.tsx diff --git a/js/src/shiny-react/__tests__/use-shiny-input-type.test.tsx b/pkg-js/src/shiny-react/__tests__/use-shiny-input-type.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/use-shiny-input-type.test.tsx rename to pkg-js/src/shiny-react/__tests__/use-shiny-input-type.test.tsx diff --git a/js/src/shiny-react/__tests__/use-shiny-namespace.test.tsx b/pkg-js/src/shiny-react/__tests__/use-shiny-namespace.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/use-shiny-namespace.test.tsx rename to pkg-js/src/shiny-react/__tests__/use-shiny-namespace.test.tsx diff --git a/js/src/shiny-react/__tests__/use-shiny-restore.test.tsx b/pkg-js/src/shiny-react/__tests__/use-shiny-restore.test.tsx similarity index 100% rename from js/src/shiny-react/__tests__/use-shiny-restore.test.tsx rename to pkg-js/src/shiny-react/__tests__/use-shiny-restore.test.tsx diff --git a/js/src/shiny-react/__tests__/utils.test.ts b/pkg-js/src/shiny-react/__tests__/utils.test.ts similarity index 100% rename from js/src/shiny-react/__tests__/utils.test.ts rename to pkg-js/src/shiny-react/__tests__/utils.test.ts diff --git a/js/src/shiny-react/bookmark.ts b/pkg-js/src/shiny-react/bookmark.ts similarity index 100% rename from js/src/shiny-react/bookmark.ts rename to pkg-js/src/shiny-react/bookmark.ts diff --git a/js/src/shiny-react/get-shiny.ts b/pkg-js/src/shiny-react/get-shiny.ts similarity index 100% rename from js/src/shiny-react/get-shiny.ts rename to pkg-js/src/shiny-react/get-shiny.ts diff --git a/js/src/shiny-react/index.ts b/pkg-js/src/shiny-react/index.ts similarity index 100% rename from js/src/shiny-react/index.ts rename to pkg-js/src/shiny-react/index.ts diff --git a/js/src/shiny-react/input-registry.ts b/pkg-js/src/shiny-react/input-registry.ts similarity index 100% rename from js/src/shiny-react/input-registry.ts rename to pkg-js/src/shiny-react/input-registry.ts diff --git a/js/src/shiny-react/lifecycle-store.ts b/pkg-js/src/shiny-react/lifecycle-store.ts similarity index 100% rename from js/src/shiny-react/lifecycle-store.ts rename to pkg-js/src/shiny-react/lifecycle-store.ts diff --git a/js/src/shiny-react/message-registry.ts b/pkg-js/src/shiny-react/message-registry.ts similarity index 100% rename from js/src/shiny-react/message-registry.ts rename to pkg-js/src/shiny-react/message-registry.ts diff --git a/js/src/shiny-react/missing.ts b/pkg-js/src/shiny-react/missing.ts similarity index 100% rename from js/src/shiny-react/missing.ts rename to pkg-js/src/shiny-react/missing.ts diff --git a/js/src/shiny-react/output-registry.ts b/pkg-js/src/shiny-react/output-registry.ts similarity index 100% rename from js/src/shiny-react/output-registry.ts rename to pkg-js/src/shiny-react/output-registry.ts diff --git a/js/src/shiny-react/react-registry.ts b/pkg-js/src/shiny-react/react-registry.ts similarity index 100% rename from js/src/shiny-react/react-registry.ts rename to pkg-js/src/shiny-react/react-registry.ts diff --git a/js/src/shiny-react/use-shiny.ts b/pkg-js/src/shiny-react/use-shiny.ts similarity index 100% rename from js/src/shiny-react/use-shiny.ts rename to pkg-js/src/shiny-react/use-shiny.ts diff --git a/js/src/shiny-react/utils.ts b/pkg-js/src/shiny-react/utils.ts similarity index 100% rename from js/src/shiny-react/utils.ts rename to pkg-js/src/shiny-react/utils.ts diff --git a/js/src/shiny.d.ts b/pkg-js/src/shiny.d.ts similarity index 100% rename from js/src/shiny.d.ts rename to pkg-js/src/shiny.d.ts diff --git a/js/src/shinyreact.css b/pkg-js/src/shinyreact.css similarity index 100% rename from js/src/shinyreact.css rename to pkg-js/src/shinyreact.css diff --git a/js/tsconfig.json b/pkg-js/tsconfig.json similarity index 100% rename from js/tsconfig.json rename to pkg-js/tsconfig.json diff --git a/js/vite.config.ts b/pkg-js/vite.config.ts similarity index 100% rename from js/vite.config.ts rename to pkg-js/vite.config.ts diff --git a/js/vitest.config.ts b/pkg-js/vitest.config.ts similarity index 100% rename from js/vitest.config.ts rename to pkg-js/vitest.config.ts