-
Notifications
You must be signed in to change notification settings - Fork 2
Add WriteableStream support #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export function error(error) { | ||
return function(controller) { | ||
return function() { | ||
return controller.error(error); | ||
}; | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. closed, desiredSize, abort, and releaseLock are all not implemented here. If you don't want to add those now, could you open an issue after this PR is merged to track that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm happy to add them; do we want to backfill the full spec on Reader too? I noticed that the implementation here is missing a few methods/properties. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean https://streams.spec.whatwg.org/#default-reader-class? Perhaps as a separate PR. |
||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the readonly attribute
signal
is missing here. If it's not added in this PR, we should open an issue tracking that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my other comment on filling out the spec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah; it appears that the returned
AbortSignal
type is currently defined in the web-fetch package, and it needs be moved to somewhere more centralized to avoid a circular dependency. A new "web-abort-signal" package seems somewhat overkill, but given its inclusion in the DOM standard rather than the fetch or stream standard I'm not sure what the best course of action would be. I'll leave this out of the next revision for now.