From 5f0a9f9710a7826c3063e2f635b039b27d655885 Mon Sep 17 00:00:00 2001 From: YourFin Date: Tue, 5 Jul 2022 23:22:23 -0700 Subject: [PATCH] Add WriteableStream support --- CHANGELOG.md | 1 + src/Web/Streams/Sink.js | 24 ++++++++++ src/Web/Streams/Sink.purs | 26 ++++++++++ src/Web/Streams/WritableStream.js | 33 +++++++++++++ src/Web/Streams/WritableStream.purs | 40 ++++++++++++++++ src/Web/Streams/WritableStreamController.js | 7 +++ src/Web/Streams/WritableStreamController.purs | 9 ++++ src/Web/Streams/Writer.js | 47 +++++++++++++++++++ src/Web/Streams/Writer.purs | 47 +++++++++++++++++++ 9 files changed, 234 insertions(+) create mode 100644 src/Web/Streams/Sink.js create mode 100644 src/Web/Streams/Sink.purs create mode 100644 src/Web/Streams/WritableStream.js create mode 100644 src/Web/Streams/WritableStream.purs create mode 100644 src/Web/Streams/WritableStreamController.js create mode 100644 src/Web/Streams/WritableStreamController.purs create mode 100644 src/Web/Streams/Writer.js create mode 100644 src/Web/Streams/Writer.purs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bf756d..4f6993d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Notable changes to this project are documented in this file. The format is based Breaking changes: New features: + - Add WriteableStream support (#9) Bugfixes: diff --git a/src/Web/Streams/Sink.js b/src/Web/Streams/Sink.js new file mode 100644 index 0000000..23460d4 --- /dev/null +++ b/src/Web/Streams/Sink.js @@ -0,0 +1,24 @@ +export function _make(options) { + var newOptions = {}; + if (options.start) { + newOptions.start = function(controller) { + return options.start(controller)(); + }; + } + if (options.write) { + newOptions.write = function(chunk, controller) { + return options.write(chunk)(controller)(); + }; + } + if (options.close) { + newOptions.close = function(controller) { + return options.close(controller)(); + }; + } + if (options.abort) { + newOptions.abort = function(reason) { + return options.abort(reason)(); + }; + } + return newOptions; +} diff --git a/src/Web/Streams/Sink.purs b/src/Web/Streams/Sink.purs new file mode 100644 index 0000000..050baf6 --- /dev/null +++ b/src/Web/Streams/Sink.purs @@ -0,0 +1,26 @@ +module Web.Streams.Sink + ( Sink + , Optional + , make + ) where + +import Effect (Effect) +import Effect.Exception (Error) +import Prelude (Unit) +import Prim.Row as Row +import Web.Promise (Promise) +import Web.Streams.WritableStreamController (WritableStreamController) + +type Optional chunk = + ( start :: WritableStreamController chunk -> Effect (Promise Unit) + , write :: chunk -> WritableStreamController chunk -> Effect (Promise Unit) + , close :: WritableStreamController chunk -> Effect (Promise Unit) + , abort :: Error -> Effect (Promise Unit) + ) + +foreign import data Sink :: Type -> Type + +make :: forall r rx chunk. Row.Union r rx (Optional chunk) => { | r } -> Sink chunk +make = _make + +foreign import _make :: forall r chunk. { | r } -> Sink chunk diff --git a/src/Web/Streams/WritableStream.js b/src/Web/Streams/WritableStream.js new file mode 100644 index 0000000..db6f27a --- /dev/null +++ b/src/Web/Streams/WritableStream.js @@ -0,0 +1,33 @@ +export function _new(source, strategy) { + return new WritableStream(source, strategy); +} + +export function close(stream) { + return function() { + return stream.close(); + }; +} + +export function _abortErr(stream, reason) { + return function() { + return stream.abort(reason); + }; +} + +export function abort(stream) { + return function() { + return stream.abort(); + }; +} + +export function locked(stream) { + return function() { + return stream.locked; + }; +} + +export function getWriter(stream) { + return function() { + return stream.getWriter(); + }; +} diff --git a/src/Web/Streams/WritableStream.purs b/src/Web/Streams/WritableStream.purs new file mode 100644 index 0000000..1f20668 --- /dev/null +++ b/src/Web/Streams/WritableStream.purs @@ -0,0 +1,40 @@ +module Web.Streams.WritableStream + ( WritableStream + , new + , abort + , abortErr + , close + , getWriter + , locked + ) where + +import Data.Maybe (Maybe) +import Data.Nullable (Nullable, toNullable) +import Effect (Effect) +import Effect.Exception (Error) +import Effect.Uncurried (EffectFn2, runEffectFn2) +import Prelude (Unit) +import Web.Promise (Promise) +import Web.Streams.QueuingStrategy (QueuingStrategy) +import Web.Streams.Sink (Sink) +import Web.Streams.Writer (Writer) + +foreign import data WritableStream :: Type -> Type + +foreign import _new :: forall chunk. EffectFn2 (Nullable (Sink chunk)) (Nullable (QueuingStrategy chunk)) (WritableStream chunk) + +new :: forall chunk. Maybe (Sink chunk) -> Maybe (QueuingStrategy chunk) -> Effect (WritableStream chunk) +new source strategy = runEffectFn2 _new (toNullable source) (toNullable strategy) + +foreign import _abortErr :: forall chunk. EffectFn2 (WritableStream chunk) Error (Promise Error) + +abortErr :: forall chunk. WritableStream chunk -> Error -> Effect (Promise Error) +abortErr = runEffectFn2 _abortErr + +foreign import abort :: forall chunk. WritableStream chunk -> Effect (Promise Unit) + +foreign import close :: forall chunk. WritableStream chunk -> Effect (Promise Unit) + +foreign import getWriter :: forall chunk. WritableStream chunk -> Effect (Writer chunk) + +foreign import locked :: forall chunk. WritableStream chunk -> Effect Boolean diff --git a/src/Web/Streams/WritableStreamController.js b/src/Web/Streams/WritableStreamController.js new file mode 100644 index 0000000..c88931c --- /dev/null +++ b/src/Web/Streams/WritableStreamController.js @@ -0,0 +1,7 @@ +export function error(error) { + return function(controller) { + return function() { + return controller.error(error); + }; + }; +} diff --git a/src/Web/Streams/WritableStreamController.purs b/src/Web/Streams/WritableStreamController.purs new file mode 100644 index 0000000..10c32d9 --- /dev/null +++ b/src/Web/Streams/WritableStreamController.purs @@ -0,0 +1,9 @@ +module Web.Streams.WritableStreamController where + +import Effect (Effect) +import Effect.Exception (Error) +import Prelude (Unit) + +foreign import data WritableStreamController :: Type -> Type + +foreign import error :: forall chunk. WritableStreamController chunk -> Error -> Effect Unit diff --git a/src/Web/Streams/Writer.js b/src/Web/Streams/Writer.js new file mode 100644 index 0000000..86c53cf --- /dev/null +++ b/src/Web/Streams/Writer.js @@ -0,0 +1,47 @@ +export function _write(writer, chunk) { + return function() { + return writer.write(chunk); + }; +} + +export function close(writer) { + return function() { + return writer.close(); + }; +} + +export function closed(writer) { + return function() { + return writer.closed; + }; +} + +export function _desiredSize(writer) { + return function() { + return writer.desiredSize; + }; +} + +export function ready(writer) { + return function() { + return writer.ready; + }; +} + +export function releaseLock(writer) { + return function() { + return writer.releaseLock(); + }; +} + +export function abort(writer) { + return function() { + return writer.abort(); + }; +} + +export function _abortErr(writer, err) { + return function() { + return writer.abort(err); + }; +} diff --git a/src/Web/Streams/Writer.purs b/src/Web/Streams/Writer.purs new file mode 100644 index 0000000..93b11f3 --- /dev/null +++ b/src/Web/Streams/Writer.purs @@ -0,0 +1,47 @@ +module Web.Streams.Writer + ( Writer + , abort + , abortErr + , close + , closed + , desiredSize + , ready + , write + ) where + +import Prelude + +import Data.Maybe (Maybe) +import Data.Nullable (Nullable) +import Data.Nullable as Nullable +import Effect (Effect) +import Effect.Exception (Error) +import Effect.Uncurried (EffectFn2, runEffectFn2) +import Web.Promise (Promise) + +foreign import data Writer :: Type -> Type + +foreign import _write :: forall chunk. EffectFn2 (Writer chunk) chunk (Promise Unit) + +write :: forall chunk. Writer chunk -> chunk -> Effect (Promise Unit) +write = runEffectFn2 _write + +foreign import ready :: forall chunk. Writer chunk -> Effect (Promise Unit) + +foreign import close :: forall chunk. Writer chunk -> Effect (Promise Unit) + +foreign import closed :: forall chunk. Writer chunk -> Effect (Promise Unit) + +foreign import _desiredSize :: forall chunk. Writer chunk -> Effect (Nullable Int) + +desiredSize :: forall chunk. Writer chunk -> Effect (Maybe Int) +desiredSize = map (Nullable.toMaybe) <<< _desiredSize + +foreign import releaseLock :: forall chunk. Writer chunk -> Effect Unit + +foreign import abort :: forall chunk. Writer chunk -> Promise (Effect Unit) + +foreign import _abortErr :: forall chunk. EffectFn2 (Writer chunk) Error (Promise Error) + +abortErr :: forall chunk. Writer chunk -> Error -> Effect (Promise Error) +abortErr = runEffectFn2 _abortErr