Skip to content

Fix Etherpad plugin migration with pnpm 12 - #5

Draft
syrusakbary wants to merge 10 commits into
mainfrom
codex/etherpad-pnpm12-list
Draft

syrusakbary wants to merge 10 commits into
mainfrom
codex/etherpad-pnpm12-list

Conversation

@syrusakbary

Copy link
Copy Markdown
Member

Etherpad exits during plugin migration on pnpm 12 because pnpm ls no longer accepts --no-production. Use the equivalent --no-prod spelling, which works with pnpm 10, 11, and 12.

Validation: the list command succeeds on pnpm 10.34.5, 11.2.2, and 12.5.1. The EdgeJS framework harness builds Etherpad and verifies its health and homepage routes under both Node 24 and native EdgeJS with pnpm 12.5.1.

Unblocks the framework checks in wasmerio/edgejs#153.

Arshia001 and others added 10 commits June 24, 2026 16:11
Per-app routes.json configs enable multi-route HTTP validation across the
js-* example apps, with package.json tweaks for Docusaurus and Gatsby builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce js-next-standalone, js-vite-standalone, and js-astro-ssr-standalone
with standalone.json configs, and ignore local build artifacts in git.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace TypeScript next.config.ts with next.config.js (output: 'standalone'),
add prepare-standalone.cjs and standalone.json, and run the prebuilt
.next/standalone/server.js so EdgeJS never needs TypeScript/SWC at runtime.

Co-authored-by: Cursor <cursoragent@cursor.com>
Total.js v5 CMS (filesystem TextDB, no native deps) packaged as a
framework-test example. Runs single-process in production mode
(options.watcher = false) so it works on single-process hosts and the
framework-test harness; the port is read from the PORT env var.

Validates GET /admin/ -> 200 on Node, EdgeJS QuickJS native, and
EdgeJS QuickJS WASIX.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dashy (Vue 3 + Vite SPA with a plain-JS Express server) packaged as a
framework-test example. Built with native Node (vite build -> dist/),
then the production server (node server) is run through EdgeJS so the
final built artifacts are validated, not a dev server.

Packaging changes for the pnpm-based harness:
- drop the yarn `packageManager` field so pnpm can install
- add `workbox-window` (vite-plugin-pwa needs it resolvable under pnpm's
  strict node_modules layout; yarn hoisted it implicitly)
- trim scripts to `build` + `start` so the harness runs `node server`
  (the real Express server) rather than `vite preview`

Validates GET / -> 200 on Node, EdgeJS QuickJS native, and EdgeJS
QuickJS WASIX.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Etherpad packaged as a framework test. Upstream Etherpad runs its backend
TypeScript at runtime via tsx; EdgeJS can only execute final built
artifacts, so build-backend.mjs transpiles every src/**/*.ts to CommonJS
JS on native Node (mirroring tsx/esbuild), and `start` runs the compiled
`node src/node/server.js`. The frontend is built via build:ui. DirtyDB
file storage (no native DB). A .cache marker lets the framework-test
harness reuse the Node build on the edge stages instead of rebuilding
under EdgeJS; compiled .js are kept out of git via a managed .gitignore
block.

Green on the Node baseline (GET /health and / -> 200). The EdgeJS edge
stages are gated in the harness for now: native hits a QuickJS GC
use-after-free and WASIX hits a runtime-esbuild call in specialpages.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…esbuild)

EdgeJS/QuickJS has no native modules, so esbuild cannot run at runtime.
Upstream Etherpad bundles its three client entrypoints (index / pad /
timeslider bootstrap) lazily inside specialpages.ts via esbuild
(buildSync in production, watched build in development), which aborts the
`/` route on the edge runtime (handler never registers -> 500).

Move that bundling ahead of time, mirroring the existing build-backend.mjs
AOT pattern:

- build-frontend.mjs: on native Node during `pnpm run build`, load settings
  + plugins.update(), render the three eejs bootstrap templates with the
  live plugin set + settings, esbuild-bundle+minify them, and write
  var/js/<name>-<hash>.min.js plus a frontend-manifest.json.
- specialpages.ts: extract the client routes into a shared
  serveClientBundles() helper; expressCreateServer serves the pre-built
  manifest and skips esbuild whenever it exists, falling back to upstream's
  on-startup (prod) / watched (dev) esbuild paths when absent so plain-Node
  behaviour is unchanged.
- package.json: run build-frontend.mjs after build-backend.mjs.
- .gitignore: ignore the generated var/js/ bundles.

With this, `make framework-test-quickjs-native js-etherpad` passes on the
EdgeJS QuickJS Native stage (2/2 routes) with no runtime TypeScript/esbuild.

Note: the bundles bake in the plugin set + a few settings (e.g.
settings.cookie.prefix), which are fixed per build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The /using-ssr page's getServerData() fetches an external API
(dog.ceo/api/breed/shiba/images/random) and returns HTTP 500 when that
fetch fails — which it does in CI (no reliable outbound network / the
public API rate-limits CI IPs). Gatsby still server-renders the page body
("rendered server-side") with a 500 status, so accept 200 OR 500 in the
route's expected status while keeping the bodyContains assertion. This
still verifies SSR ran, without gating CI on an external service.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The route's getServerData() fetches an external API
(dog.ceo/api/breed/shiba/images/random). In CI that fetch does not fail
fast, it hangs: the harness's 5s HTTP_REQUEST_TIMEOUT_MS expires before
Gatsby returns anything, so the request errors out and fails the whole
job. PR #108 tried to absorb this by accepting HTTP 500 alongside 200,
but that only helps when the fetch fails quickly enough for
getServerData()'s catch-block to run and render a response — it never
reaches a status assertion when the request times out.

The route was already node-only ("stages": ["node"]), because EdgeJS
stages serve Gatsby from the static public/ output rather than running
`gatsby serve` (which hard-requires the lmdb native addon). So the route
validated nothing about EdgeJS — it only gated CI on a third-party
service's availability from GitHub runners. Remove it.

/using-dsg stays: it is also node-only but is served from build output
with no external dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants