patch-next-ws-first-upgrade.mjs 1.5 KB

1234567891011121314151617181920212223242526272829303132
  1. /**
  2. * Make next-ws wait for a route module before reading its exports.
  3. *
  4. * Next 16.3 loads route modules lazily: `routeModule.userland` throws
  5. * "The lazy module is still loading" until `ensureUserland()` has resolved.
  6. * next-ws 2.2.14 reads `userland` the moment an upgrade request arrives, so
  7. * the first WebSocket connection after every boot died as an unhandled
  8. * rejection and the browser had to reconnect. This runs after `next-ws patch`,
  9. * both locally and in the runtime image, and fails loudly when the code it
  10. * expects is not there, so a next-ws bump cannot skip it quietly.
  11. */
  12. import { readFileSync, writeFileSync } from 'node:fs'
  13. import { createRequire } from 'node:module'
  14. const require = createRequire(`${process.cwd()}/`)
  15. const file = require.resolve('next-ws/server')
  16. const source = readFileSync(file, 'utf8')
  17. const anchor = ' const handleUpgrade = module2.userland.UPGRADE;\n'
  18. const fix = ' if (typeof module2.ensureUserland === "function") await module2.ensureUserland();\n'
  19. if (source.includes(fix)) {
  20. console.log(`[next-ws] first-upgrade fix already applied to ${file}`)
  21. } else if (source.includes(anchor)) {
  22. writeFileSync(file, source.replace(anchor, fix + anchor))
  23. console.log(`[next-ws] first-upgrade fix applied to ${file}`)
  24. } else {
  25. console.error(
  26. `[next-ws] could not apply the first-upgrade fix: ${file} no longer contains the expected upgrade handler. Check whether the installed next-ws already awaits ensureUserland() and update scripts/patch-next-ws-first-upgrade.mjs.`
  27. )
  28. process.exit(1)
  29. }