diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a91f92..cad8670 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI on: push: + branches: [main] pull_request: branches: [main] @@ -37,8 +38,8 @@ jobs: - name: Run tests run: spago -x spago-dev.dhall test --no-install - # - name: Check formatting - # run: purs-tidy check src test + - name: Check formatting + run: purs-tidy check src test - name: Verify Bower & Pulp run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index d1f8e8c..6259475 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ Bugfixes: Other improvements: +* Transferred to https://github.com/purescript-node org (#7 by @jamesdbrock) + ## v4.0.0 Bugfixes: diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..79ea364 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2022 PureScript, James Dawson Brock + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README.md b/README.md index 4e6c8a4..8a3d9f6 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,20 @@ -# node-streams-aff +# purescript-node-streams-aff -[![CI](https://github.com/jamesdbrock/purescript-node-streams-aff/workflows/CI/badge.svg?branch=main)](https://github.com/jamesdbrock/purescript-node-streams-aff/actions?query=workflow%3ACI+branch%3Amain) +[![Latest release](http://img.shields.io/github/release/purescript-node/purescript-node-streams-aff.svg)](https://github.com/purescript-node/purescript-node-streams-aff/releases) +[![CI](https://github.com/purescript-node/purescript-node-streams-aff/workflows/CI/badge.svg?branch=main)](https://github.com/purescript-node/purescript-node-streams-aff/actions?query=workflow%3ACI+branch%3Amain) [![Pursuit](https://pursuit.purescript.org/packages/purescript-node-streams-aff/badge)](https://pursuit.purescript.org/packages/purescript-node-streams-aff) -Asynchronous PureScript API for [*Node.js* Stream](https://nodejs.org/docs/latest/api/stream.html). +Asynchronous PureScript [`Aff`](https://pursuit.purescript.org/packages/purescript-aff) API for [*Node.js* Stream](https://nodejs.org/docs/latest/api/stream.html). + +## Installation + +``` +spago install node-streams-aff +``` + +## Documentation + +Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-node-streams-aff). -## Prior art -* https://pursuit.purescript.org/packages/purescript-node-fs-aff/docs/Node.FS.Aff -* https://pursuit.purescript.org/packages/purescript-node-fs/docs/Node.FS.Async -* https://pursuit.purescript.org/packages/purescript-node-coroutines -* https://pursuit.purescript.org/packages/purescript-idiomatic-node-stream -* https://dgopsq.space/blog/reading-from-stdin-using-purescript -* https://github.com/purescript-contrib/pulp/blob/master/src/Pulp/System/Stream.purs diff --git a/packages.dhall b/packages.dhall index 51e69de..9e56005 100644 --- a/packages.dhall +++ b/packages.dhall @@ -99,7 +99,7 @@ in upstream ------------------------------- -} let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.15.0-20220516/packages.dhall - sha256:b0bf932de16a10b7d69c6bbbb31ec9ca575237c43a999fa32e59e35eb8c024a1 + https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20221013/packages.dhall + sha256:21000b190e1ef14c92feb1400816022319bc40a30280d20f24c0dcacfb85e966 in upstream diff --git a/spago.dhall b/spago.dhall index ffa6127..43bb5e4 100644 --- a/spago.dhall +++ b/spago.dhall @@ -29,5 +29,5 @@ to generate this file without the comments in this block. , packages = ./packages.dhall , sources = [ "src/**/*.purs" ] , license = "MIT" -, repository = "https://github.com/jamesdbrock/purescript-node-streams-aff.git" +, repository = "https://github.com/purescript-node/purescript-node-streams-aff.git" } diff --git a/src/Node/Stream/Aff.purs b/src/Node/Stream/Aff.purs index 71e21bc..42cbe3c 100644 --- a/src/Node/Stream/Aff.purs +++ b/src/Node/Stream/Aff.purs @@ -81,8 +81,7 @@ module Node.Stream.Aff , end , toStringUTF8 , fromStringUTF8 - ) - where + ) where import Prelude @@ -105,7 +104,6 @@ import Node.Stream (Readable, Writable) import Node.Stream as Stream import Node.Stream.Aff.Internal (onceDrain, onceEnd, onceError, onceReadable, readable) - -- | Wait until there is some data available from the stream, then read it. -- | -- | This function is useful for streams like __stdin__ which never @@ -140,36 +138,36 @@ readSome r = liftAff <<< makeAff $ \res -> do removeEnd res (Right (Tuple [] false)) - ret1 <- liftST $ Array.ST.unsafeFreeze bufs readagain <- readable r - removeReadable <- if readagain && Array.length ret1 == 0 then do - -- if still readable and we couldn't read anything right away, - -- then wait for the readable event. - -- “The 'readable' event will also be emitted once the end of the - -- stream data has been reached but before the 'end' event is emitted.” - -- if not readable then this was a zero-length Readable stream. - -- https://nodejs.org/api/stream.html#event-readable - onceReadable r do - catchException (res <<< Left) do - untilE do - Stream.read r Nothing >>= case _ of - Nothing -> pure true - Just chunk -> do - void $ liftST $ Array.ST.push chunk bufs - pure false - ret2 <- liftST $ Array.ST.unsafeFreeze bufs - removeError - removeEnd - readagain2 <- readable r - res (Right (Tuple ret2 readagain2)) + removeReadable <- + if readagain && Array.length ret1 == 0 then do + -- if still readable and we couldn't read anything right away, + -- then wait for the readable event. + -- “The 'readable' event will also be emitted once the end of the + -- stream data has been reached but before the 'end' event is emitted.” + -- if not readable then this was a zero-length Readable stream. + -- https://nodejs.org/api/stream.html#event-readable + onceReadable r do + catchException (res <<< Left) do + untilE do + Stream.read r Nothing >>= case _ of + Nothing -> pure true + Just chunk -> do + void $ liftST $ Array.ST.push chunk bufs + pure false + ret2 <- liftST $ Array.ST.unsafeFreeze bufs + removeError + removeEnd + readagain2 <- readable r + res (Right (Tuple ret2 readagain2)) -- return what we read right away - else do - removeError - removeEnd - res (Right (Tuple ret1 readagain)) - pure (pure unit) -- dummy canceller + else do + removeError + removeEnd + res (Right (Tuple ret1 readagain)) + pure (pure unit) -- dummy canceller -- canceller might by called while waiting for `onceReadable` pure $ effectCanceler do @@ -177,7 +175,6 @@ readSome r = liftAff <<< makeAff $ \res -> do removeEnd removeReadable - -- | Read all data until the end of the stream. -- | -- | Note that __stdin__ will never end. @@ -243,7 +240,6 @@ readAll r = liftAff <<< makeAff $ \res -> do removeEnd join $ Ref.read removeReadable - -- | Wait for *N* bytes to become available from the stream. -- | -- | If more than *N* bytes are available on the stream, then @@ -288,12 +284,12 @@ readN r n = liftAff <<< makeAff $ \res -> do -- “If size bytes are not available to be read, null will be returned -- unless the stream has ended, in which case all of the data remaining -- in the internal buffer will be returned.” - Stream.read r (Just (n-red)) >>= case _ of + Stream.read r (Just (n - red)) >>= case _ of Nothing -> pure true Just chunk -> do _ <- liftST $ Array.ST.push chunk bufs s <- Buffer.size chunk - red' <- Ref.modify (_+s) redRef + red' <- Ref.modify (_ + s) redRef if red' >= n then pure true else @@ -331,7 +327,6 @@ readN r n = liftAff <<< makeAff $ \res -> do removeEnd join $ Ref.read removeReadable - -- | Write to a stream. -- | -- | Will complete after the data is flushed to the stream. @@ -368,7 +363,7 @@ write w bs = liftAff <<< makeAff $ \res -> do Nothing -> do pure true Just chunk -> do - isLast <- liftST $ (_==0) <$> Array.length <$> Array.ST.unsafeFreeze bufs + isLast <- liftST $ (_ == 0) <$> Array.length <$> Array.ST.unsafeFreeze bufs nobackpressure <- Stream.write w chunk (if isLast then callbackLast else callback) if nobackpressure then do pure false @@ -403,7 +398,7 @@ end w = liftAff <<< makeAff $ \res -> do Just err -> res (Left err) pure $ nonCanceler - -- | Concatenate an `Array` of UTF-8 encoded `Buffer`s into a `String`. +-- | Concatenate an `Array` of UTF-8 encoded `Buffer`s into a `String`. toStringUTF8 :: forall m. MonadEffect m => Array Buffer -> m String toStringUTF8 bs = liftEffect $ Buffer.toString Encoding.UTF8 =<< Buffer.concat bs diff --git a/src/Node/Stream/Internal.purs b/src/Node/Stream/Internal.purs index acc00aa..c79b2fc 100644 --- a/src/Node/Stream/Internal.purs +++ b/src/Node/Stream/Internal.purs @@ -10,8 +10,7 @@ module Node.Stream.Aff.Internal , push , newReadable , newReadableStringUTF8 - ) - where + ) where import Prelude @@ -77,7 +76,6 @@ foreign import readable . Readable r -> Effect Boolean - -- | [`readable.push(chunk[, encoding])`](https://nodejs.org/api/stream.html#readablepushchunk-encoding) foreign import push :: forall r diff --git a/test/Main.purs b/test/Main.purs index 936ca6c..77c72eb 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -30,7 +30,7 @@ import Test.Spec.Runner (defaultConfig, runSpec') main :: Effect Unit main = unsafePartial $ do launchAff_ do - runSpec' (defaultConfig {timeout = Just (Milliseconds 20000.0)}) [consoleReporter] do + runSpec' (defaultConfig { timeout = Just (Milliseconds 40000.0) }) [ consoleReporter ] do describe "Node.Stream.Aff" do it "writes and reads" do let outfilename = "/tmp/test1.txt" @@ -54,9 +54,9 @@ main = unsafePartial $ do let outfilename = "/tmp/test2.txt" outfile <- liftEffect $ createWriteStream outfilename b <- liftEffect $ Buffer.fromString "test" UTF8 - write outfile [b] + write outfile [ b ] end outfile - expectError $ write outfile [b] + expectError $ write outfile [ b ] it "reads from a zero-length Readable" do r <- liftEffect $ newReadableStringUTF8 "" b1 <- toStringUTF8 =<< (fst <$> readSome r) diff --git a/test/Main2.purs b/test/Main2.purs index 7696611..0d4cf15 100644 --- a/test/Main2.purs +++ b/test/Main2.purs @@ -25,7 +25,6 @@ completion = case _ of Left e -> Console.error (unsafeCoerce e) Right f -> f - main :: Effect Unit main = unsafePartial $ do runAff_ completion do diff --git a/test/Main3.purs b/test/Main3.purs index d2ac9b3..d96092c 100644 --- a/test/Main3.purs +++ b/test/Main3.purs @@ -34,12 +34,12 @@ completion = case _ of main :: Effect Unit main = unsafePartial $ do runAff_ completion do - runSpec [consoleReporter] do + runSpec [ consoleReporter ] do describe "Node.Stream.Aff" do it "reads 1" do infile <- liftEffect $ createReadStream =<< pure <<< flip Array.unsafeIndex 2 =<< argv Tuple inputs1 _ <- readN infile 500000 - bytesRead1 :: Int <- liftEffect $ Array.foldM (\a b -> (a+_) <$> Buffer.size b) 0 inputs1 + bytesRead1 :: Int <- liftEffect $ Array.foldM (\a b -> (a + _) <$> Buffer.size b) 0 inputs1 shouldEqual 500000 bytesRead1 Tuple inputs2 _ <- readSome infile Tuple inputs3 _ <- readAll infile @@ -49,8 +49,7 @@ main = unsafePartial $ do -- inputs4 <- readSome infile -- inputs4 <- readN infile 10 -- let inputs = inputs1 <> inputs2 <> inputs3 <> inputs4 - bytesRead :: Int - <- liftEffect $ Array.foldM (\a b -> (a+_) <$> Buffer.size b) 0 inputs + bytesRead :: Int <- liftEffect $ Array.foldM (\a b -> (a + _) <$> Buffer.size b) 0 inputs shouldEqual 1000000 bytesRead input :: Buffer <- liftEffect $ concat inputs inputSize <- liftEffect $ Buffer.size input diff --git a/test/Main4.purs b/test/Main4.purs index d6cc496..9f4b13d 100644 --- a/test/Main4.purs +++ b/test/Main4.purs @@ -28,11 +28,10 @@ completion = case _ of Left e -> Console.error (unsafeCoerce e) Right f -> f - main :: Effect Unit main = unsafePartial $ do runAff_ completion do - runSpec [consoleReporter] do + runSpec [ consoleReporter ] do describe "Node.Stream.Aff" do it "reads 1" do sequential $ alt