Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
key: ${{ runner.os }}-stack-${{ hashFiles('stack.yaml.lock') }}-${{ hashFiles('trypurescript.cabal') }}

- name: Build server code
run: stack --no-terminal -j1 build
run: stack --no-terminal build

- name: Build server assets
if: github.event_name == 'release'
Expand All @@ -62,7 +62,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "22"

- name: Build client code
run: |
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ New features:
Bugfixes:

Other improvements:
- Update the PureScript compiler to [0.15.16](https://github.com/purescript/purescript/releases/tag/v0.15.16) and the package set to `psc-0.15.15-20260701` (#320 by @thomashoneyman)
- Since 0.15.16 was not published to Hackage, `stack.yaml` now pins the `v0.15.16` release tag on GitHub instead of a Hackage version.
- Modernize the Haskell toolchain from Stackage `lts-20.9` (GHC 9.2.5) to `lts-23.18` (GHC 9.8.4), matching the upstream `purescript` repository (#320 by @thomashoneyman)
- Modernize the server for scotty 0.22 and GHC 9.8, build with `-Wall`, prune unused dependencies, and update the cabal file to `cabal-version: 2.4` (#320 by @thomashoneyman)
- Update the CI client build to Node 22, as Node 20 reached end of life in April 2026 (#320 by @thomashoneyman)
- Raise the server's RTS heap cap from 3G to 6G to accommodate the larger package set; deploying this requires resizing the try.purescript.org droplet beyond 4GB of RAM (#320 by @thomashoneyman)

## [v2026-07-03.1](https://github.com/purescript/trypurescript/releases/tag/v2026-07-03.1)

Expand Down
2 changes: 0 additions & 2 deletions Setup.hs

This file was deleted.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"devDependencies": {
"esbuild": "^0.14.43",
"http-server": "^14.1.0",
"purescript": "^0.15.2",
"purescript": "^0.15.16",
"purescript-psa": "^0.8.2",
"rimraf": "^2.5.4",
"spago": "^0.20.9"
Expand Down
4 changes: 2 additions & 2 deletions client/src/Try/SharedConfig.purs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ module Try.SharedConfig where
import Prelude

pursVersion :: String
pursVersion = "v0.15.13"
pursVersion = "v0.15.16"

pursReleaseUrl :: String
pursReleaseUrl = "https://github.com/purescript/purescript/releases/tag/" <> pursVersion

packageSetVersion :: String
packageSetVersion = "0.15.13-20231219"
packageSetVersion = "0.15.15-20260701"

packageSetPackageJsonUrl :: String
packageSetPackageJsonUrl = "https://github.com/purescript/package-sets/blob/psc-" <> packageSetVersion <> "/packages.json"
26 changes: 17 additions & 9 deletions client/updateSharedConfigVersions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,23 @@ const stagingPackagesDhallPath = path.join("..", "staging", "packages.dhall");
const stackYamlContent = fs.readFileSync(stackYamlPath, "utf-8");
const packagesContent = fs.readFileSync(stagingPackagesDhallPath, "utf-8");

const pursVersion = stackYamlContent.split("\n")
.reduce((acc, nextLine) => {
if (acc.found) return acc;
const matchResult = nextLine.match(/ +- purescript-(.+)/);
return matchResult
? { found: true, value: matchResult[1] }
: acc;
}, { found: false })
.value;
// The `purescript` extra-dep is either a Hackage dependency, e.g.
// - purescript-0.15.13
// or a GitHub dependency pinned to a release tag, e.g.
// - github: purescript/purescript
// commit: v0.15.16
const pursVersion = (() => {
const lines = stackYamlContent.split("\n");
for (let i = 0; i < lines.length; i++) {
const hackageMatch = lines[i].match(/ +- purescript-(.+)/);
if (hackageMatch) return hackageMatch[1];
if (/ +- github: purescript\/purescript\s*$/.test(lines[i])) {
const commitMatch = (lines[i + 1] ?? "").match(/ +commit: v(.+)/);
if (commitMatch) return commitMatch[1];
}
}
return undefined;
})();

const packageSetVersion = packagesContent
.match(/https:\/\/github.com\/purescript\/package-sets\/releases\/download\/psc-([^\/]+)\/packages.dhall/)[1];
Expand Down
5 changes: 4 additions & 1 deletion deploy/start
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ set -ex
set -o noglob
export XDG_CACHE_HOME="$PWD/.spago-cache"
spago install
exec trypurescript +RTS -N2 -A128m -M3G -RTS 8081 $(spago sources)
# Note: the heap cap below must fit within the droplet's RAM; the package set
# as of psc-0.15.15-20260701 (641 packages) needs more than the 3G that
# sufficed for psc-0.15.13-20231219 (459 packages).
exec trypurescript +RTS -N2 -A128m -M6G -RTS 8081 $(spago sources)
67 changes: 35 additions & 32 deletions server/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,20 @@

module Main (main) where

import Control.Monad (unless, foldM)
import Control.Monad.Error.Class (throwError)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger (runLogger')
import Control.Monad (foldM)
import qualified Control.Monad.State as State
import Control.Monad.Trans (lift)
import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
import Control.Monad.Trans.Reader (runReaderT)
import Control.Monad.Writer.Strict (runWriterT)
import qualified Data.Aeson as A
import Data.Aeson ((.=))
import Data.Bifunctor (first, second, bimap)
import Data.Bifunctor (second, bimap)
import qualified Data.ByteString.Lazy as BL
import Data.Default (def)
import Data.Function (on)
import qualified Data.IORef as IORef
import Data.List (nubBy)
import qualified Data.List.NonEmpty as NE
import qualified Data.Map as M
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
Expand All @@ -50,6 +44,7 @@ import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.FilePath.Glob (glob)
import qualified System.IO as IO
import Text.Read (readMaybe)
import Web.Scotty
import qualified Web.Scotty as Scotty

Expand Down Expand Up @@ -162,7 +157,7 @@ server allModuleNames externs initNamesEnv initEnv port = do

post "/compile" $ do
code <- T.decodeUtf8 . BL.toStrict <$> body
response <- lift $ compile code
response <- liftIO $ compile code
Scotty.setHeader "Access-Control-Allow-Origin" "*"
case response of
Left err ->
Expand All @@ -171,7 +166,7 @@ server allModuleNames externs initNamesEnv initEnv port = do
Scotty.json $ A.object [ "js" .= comp, "warnings" .= warnings ]

get "/search" $ do
query <- param "q"
query <- queryParam "q"
Scotty.setHeader "Access-Control-Allow-Origin" "*"
Scotty.setHeader "Content-Type" "application/json"
case tryParseType query of
Expand All @@ -191,7 +186,7 @@ server allModuleNames externs initNamesEnv initEnv port = do
]

getOpts :: Int -> Scotty.Options
getOpts port = def
getOpts port = Scotty.defaultOptions
{ settings =
Warp.setHost "127.0.0.1"
$ Warp.setPort port
Expand All @@ -204,9 +199,9 @@ lookupAllConstructors env = P.everywhereOnTypesM $ \case
other -> pure other
where
lookupConstructor :: P.Environment -> P.ProperName 'P.TypeName -> [P.Qualified (P.ProperName 'P.TypeName)]
lookupConstructor env nm =
lookupConstructor env' nm =
[ q
| (q@(P.Qualified (N.ByModuleName _) thisNm), _) <- M.toList (P.types env)
| (q@(P.Qualified (N.ByModuleName _) thisNm), _) <- M.toList (P.types env')
, thisNm == nm
]

Expand All @@ -216,15 +211,15 @@ lookupAllConstructors env = P.everywhereOnTypesM $ \case
replaceTypeVariablesAndDesugar :: (Text -> Int -> P.SourceType) -> P.SourceType -> P.SourceType
replaceTypeVariablesAndDesugar f ty = State.evalState (P.everywhereOnTypesM go ty) (0, M.empty) where
go = \case
P.ParensInType _ ty -> pure ty
P.ParensInType _ inner -> pure inner
P.TypeVar _ s -> do
(next, m) <- State.get
(n, m) <- State.get
case M.lookup s m of
Nothing -> do
let ty = f s next
State.put (next + 1, M.insert s ty m)
pure ty
Just ty -> pure ty
let unknown = f s n
State.put (n + 1, M.insert s unknown m)
pure unknown
Just unknown -> pure unknown
other -> pure other

tryParseType :: Text -> Maybe P.SourceType
Expand All @@ -242,16 +237,24 @@ main :: IO ()
main = do
-- Stop mangled "Compiling ModuleName" text
IO.hSetBuffering IO.stderr IO.LineBuffering
(portString : inputGlobs) <- getArgs
let port = read portString
inputFiles <- concat <$> traverse glob inputGlobs
e <- runExceptT $ do
modules <- ExceptT $ I.loadAllModules inputFiles
(exts, env) <- ExceptT . I.runMake . I.make $ map (second CST.pureResult) modules
namesEnv <- fmap fst . runWriterT $ foldM P.externsEnv P.primEnv exts
let
allModuleNames = fmap (P.getModuleName . snd) modules
pure (allModuleNames, exts, namesEnv, env)
case e of
Left err -> print err >> exitFailure
Right (allModuleNames, exts, namesEnv, env) -> server allModuleNames exts namesEnv env port
args <- getArgs
case args of
portString : inputGlobs
| Just port <- readMaybe portString -> run port inputGlobs
_ -> do
IO.hPutStrLn IO.stderr "Usage: trypurescript PORT INPUT_GLOB..."
exitFailure
where
run :: Int -> [String] -> IO ()
run port inputGlobs = do
inputFiles <- concat <$> traverse glob inputGlobs
e <- runExceptT $ do
modules <- ExceptT $ I.loadAllModules inputFiles
(exts, env) <- ExceptT . I.runMake . I.make $ map (second CST.pureResult) modules
namesEnv <- fmap fst . runWriterT $ foldM P.externsEnv P.primEnv exts
let
allModuleNames = fmap (P.getModuleName . snd) modules
pure (allModuleNames, exts, namesEnv, env)
case e of
Left err -> print err >> exitFailure
Right (allModuleNames, exts, namesEnv, env) -> server allModuleNames exts namesEnv env port
26 changes: 17 additions & 9 deletions stack.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
resolver: lts-20.9
resolver: lts-23.18

packages:
- "."

extra-deps:
- purescript-0.15.13
# purescript 0.15.16 was not uploaded to Hackage, so we pin its release tag
# on GitHub instead. Note that `client/updateSharedConfigVersions.mjs`
# derives the compiler version from the `commit` value below.
- github: purescript/purescript
commit: v0.15.16

# The extra dependencies below mirror the `extra-deps` listed in the
# purescript repository's stack.yaml at the version pinned above.
- language-javascript-0.7.0.0
- process-1.6.13.1
# The Cabal library is not in Stackage
- Cabal-3.6.3.0
# Protolude is not yet in resolver snapshot
- protolude-0.3.1
- bower-json-1.1.0.0
- these-1.2.1
- aeson-better-errors-0.9.1.3
- github: purescript/cheapskate
commit: 633c69024e061ad956f1aecfc137fb99a7a7a20b

flags:
these:
assoc: false
aeson-pretty:
lib-only: true
57 changes: 36 additions & 21 deletions stack.yaml.lock
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
# https://docs.haskellstack.org/en/stable/topics/lock_files

packages:
- completed:
hackage: purescript-0.15.13@sha256:ed7e4d3561ff6cbc7f950af2450a51f71648c47fece8b9a2b5100f0157a47615,21378
name: purescript
pantry-tree:
sha256: f91a02104c2bb596613dca4cf460e8e218488791b8d2f1d0641cd0e73c9eb072
size: 159072
sha256: c16a7cd421dd7b39a4cd19e062bc5243e4573ce29531e8c6734c1e50c107be07
size: 149027
sha256: 36abaef46aa3cd0316d924c872987aa186d95654d05aa66060948ab47b161f18
size: 891651
url: https://github.com/purescript/purescript/archive/v0.15.16.tar.gz
version: 0.15.16
original:
hackage: purescript-0.15.13
url: https://github.com/purescript/purescript/archive/v0.15.16.tar.gz
- completed:
hackage: language-javascript-0.7.0.0@sha256:3eab0262b8ac5621936a4beab6a0f97d0e00a63455a8b0e3ac1547b4088dae7d,3898
pantry-tree:
Expand All @@ -19,29 +23,40 @@ packages:
original:
hackage: language-javascript-0.7.0.0
- completed:
hackage: process-1.6.13.1@sha256:c8bb8b7c993ff72d771381b3b56852dd154bce51880a24789c11f57b0688d353,2963
hackage: bower-json-1.1.0.0@sha256:a136aaca67bf0d15c336f5864f7e9d40ebe046ca2cb4b25bc4895617ea35f9f6,1864
pantry-tree:
sha256: 58117b15fa330c79b3bca6b29c65f815e45840f79cc0915d3434f25e54ac8fa5
size: 1543
sha256: 3acd48e7012f246ad44c7c17cd6340362b1dc448c1d93156280814e76d9e0589
size: 419
original:
hackage: process-1.6.13.1
hackage: bower-json-1.1.0.0
- completed:
hackage: Cabal-3.6.3.0@sha256:ff97c442b0c679c1c9876acd15f73ac4f602b973c45bde42b43ec28265ee48f4,12459
hackage: these-1.2.1@sha256:35c57aede96c15ea1fed559ac287b1168eb2b2869d79e62ed8c845780b7ea136,2294
pantry-tree:
sha256: b250a53bdb56844f047a2927833bb565b936a289abfa85dfc2a63148d776368a
size: 19757
sha256: dc6366ac715dfdf5338a615f71b9ed0542c403a6afcbedcddbc879e947aea6b3
size: 351
original:
hackage: Cabal-3.6.3.0
hackage: these-1.2.1
- completed:
hackage: protolude-0.3.1@sha256:1cc9e5a5c26c33a43c52b554443dd9779fef13974eaa0beec7ca6d2551b400da,2647
hackage: aeson-better-errors-0.9.1.3@sha256:1bfdda3982368cafc7317b9f0c1f7267a6b0bbac9515ae1fad37f2b19178f567,2071
pantry-tree:
sha256: 6452a6ca8d395f7d810139779bb0fd16fc1dbb00f1862630bc08ef5a100430f9
size: 1645
sha256: 1c14247866dfb8052506c179e4725b8a7ce1472a4fb227d61576d862d9494551
size: 492
original:
hackage: protolude-0.3.1
hackage: aeson-better-errors-0.9.1.3
- completed:
name: cheapskate
pantry-tree:
sha256: b130a35ad29a61ac64c2d29bb09309ddf07b139342c67ef01ccc59ad4167d529
size: 12069
sha256: 2b495e2b6d571c33b91ebb76c1b7fe9c9b56ff90ca0804106a3260f2bbdc9a9a
size: 62489
url: https://github.com/purescript/cheapskate/archive/633c69024e061ad956f1aecfc137fb99a7a7a20b.tar.gz
version: 0.1.1.2
original:
url: https://github.com/purescript/cheapskate/archive/633c69024e061ad956f1aecfc137fb99a7a7a20b.tar.gz
snapshots:
- completed:
sha256: c11fcbeb1aa12761044755b1109d16952ede2cb6147ebde777dd5cb38f784501
size: 649333
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/9.yaml
original: lts-20.9
sha256: d133abe75e408a407cce3f032c96ac1bbadf474a93b5156ebf4135b53382d56b
size: 683827
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/18.yaml
original: lts-23.18
6 changes: 3 additions & 3 deletions staging/packages.dhall
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.15.13-20231219/packages.dhall
sha256:35b9271b0a49390a9681995c609dbf7357402a1f209e0549d840bca295abe57b
https://github.com/purescript/package-sets/releases/download/psc-0.15.15-20260701/packages.dhall
sha256:bb62858371c55d439baa6bcf463ab70cfe8753d5e1f0520b0955468c018213d6

in upstream
with metadata.version = "v0.15.13"
with metadata.version = "v0.15.16"
Loading
Loading