diff options
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | src/gleam/javascript.gleam | 36 | ||||
-rw-r--r-- | src/gleam/javascript/map.gleam | 19 | ||||
-rw-r--r-- | src/gleam/javascript/promise.gleam | 96 |
4 files changed, 151 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bfd584..fe4d06e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- The `Reference` type has been deprecated. + ## v0.9.0 - 2024-06-20 - The `promise` module gains the `race2`, `race3`, `race4`, `race5`, `race6`, diff --git a/src/gleam/javascript.gleam b/src/gleam/javascript.gleam index b1c7fd9..9df0828 100644 --- a/src/gleam/javascript.gleam +++ b/src/gleam/javascript.gleam @@ -1,40 +1,72 @@ -// TODO: docs +/// The variants that `type_of` can return. pub type TypeOf { + /// It is the value `undefined`. UndefinedType + /// It is some object, or it is `null`. ObjectType + /// It is either `true` or `false`. BooleanType + /// It is some number, a 64 bit float. NumberType + /// It is a JavaScript big-integer. BigIntType + /// It is a string. StringType + /// It is a JavaScript symbol. SymbolType + /// It is a function of unknown argument types and return type. FunctionType } +/// Symbols are special unique values in JavaScript. +/// +/// For further information view the MDN documentation: +/// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol> +/// pub type Symbol +/// Determine what category of JavaScript type a value belongs to. +/// +/// This uses the JavaScript `typeof` operator and has limited accuracy. It +/// cannot tell you anything about what Gleam type a value has. +/// +/// For further information view the MDN documentation: +/// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol> +/// @external(javascript, "../ffi.mjs", "type_of") pub fn type_of(a: value) -> TypeOf +/// Use the JavaScript `Symbol.for` method to look up a symbol with the given +/// string name, creating a new one if one does exist. +/// +/// For further information see the MDN documentation: +/// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for> +/// @external(javascript, "../ffi.mjs", "get_symbol") pub fn get_symbol(a: String) -> Symbol +@deprecated("The Reference type is being removed from this packge") pub type Reference(value) +@deprecated("The Reference type is being removed from this packge") @external(javascript, "../ffi.mjs", "dereference") pub fn dereference(a: Reference(a)) -> a +@deprecated("The Reference type is being removed from this packge") @external(javascript, "../ffi.mjs", "set_reference") pub fn set_reference(a: Reference(a), b: a) -> a +@deprecated("The Reference type is being removed from this packge") @external(javascript, "../ffi.mjs", "make_reference") pub fn make_reference(a: a) -> Reference(a) -// returns the old value +@deprecated("The Reference type is being removed from this packge") pub fn update_reference(ref: Reference(a), f: fn(a) -> a) -> a { let value = dereference(ref) set_reference(ref, f(value)) value } +@deprecated("The Reference type is being removed from this packge") @external(javascript, "../ffi.mjs", "reference_equal") pub fn reference_equal(a: Reference(a), b: Reference(a)) -> Bool diff --git a/src/gleam/javascript/map.gleam b/src/gleam/javascript/map.gleam index a2fa282..a9dcf2e 100644 --- a/src/gleam/javascript/map.gleam +++ b/src/gleam/javascript/map.gleam @@ -1,13 +1,32 @@ +/// The JavaScript `Map` type, a **mutable** collection of keys and values. +/// +/// Most the time you should use the `Dict` type from `gleam/dict` in the Gleam +/// standard library. This type may still be useful for JavaScript interop. +/// +/// For further information view the MDN documentation: +/// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map> +/// pub type Map(key, value) +/// Create a new `Map` with no contained values. +/// @external(javascript, "../../ffi.mjs", "map_new") pub fn new() -> Map(key, value) +/// Insert a new key and value into the `Map`. +/// +/// **NOTE:** This function will mutate the `Map` rather than immutably +/// updating it. +/// @external(javascript, "../../ffi.mjs", "map_set") pub fn set(a: Map(key, value), b: key, c: value) -> Map(key, value) +/// Get the value for a given key in the `Map`. +/// @external(javascript, "../../ffi.mjs", "map_get") pub fn get(a: Map(key, value), b: key) -> Result(value, Nil) +/// Get the number of key-value pairs in the `Map`. +/// @external(javascript, "../../ffi.mjs", "map_size") pub fn size(a: Map(key, value)) -> Int diff --git a/src/gleam/javascript/promise.gleam b/src/gleam/javascript/promise.gleam index b1893ee..86bd983 100644 --- a/src/gleam/javascript/promise.gleam +++ b/src/gleam/javascript/promise.gleam @@ -1,25 +1,66 @@ import gleam/dynamic.{type Dynamic} import gleam/javascript/array.{type Array} -// TODO: docs -// TODO: labels +/// JavaScript promises represent the result of an asynchronous operation which +/// returns a value, either now or at some point in the future. In practice +/// they are the foundation of concurrency in JavaScript. +/// +/// This library assumes you have some familiarity with JavaScript promises. If +/// you are not then you may want to take the time to learn about them outside of +/// Gleam. +/// +/// The Gleam promise type is generic over the type of value it resolves. It is +/// not generic over the error type as any Gleam panic or JavaScript exception +/// could alter the error value in an way that undermines the type, making it +/// unsound and untypable. +/// If you want to represent success and failure with promises use a Gleam +/// `Result` inside of a promise. +/// +/// For further information view the MDN documentation: +/// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise> +/// pub type Promise(value) +/// Create a new promise from a callback function. The callback function itself +/// takes a second function as an argument, and when that second function is +/// called with a value then the promise resolves with that value. +/// +/// This function is useful for converting code that uses callbacks into code +/// that uses promises. +/// @external(javascript, "../../ffi.mjs", "newPromise") pub fn new(a: fn(fn(value) -> Nil) -> Nil) -> Promise(value) +/// Create a promise that resolves immediately. +/// @external(javascript, "../../ffi.mjs", "resolve") pub fn resolve(a: value) -> Promise(value) +/// If the promise is in an error state then apply a function to convert the +/// error value back into valid value, making the promise healthy again. +/// +/// This is the equivilent of the `promise.catch` JavaScript method. +/// @external(javascript, "../../ffi.mjs", "rescue") pub fn rescue(a: Promise(value), b: fn(Dynamic) -> value) -> Promise(value) +/// Chain a second asynchronous operation onto a promise, so it runs after the +/// promise has resolved. +/// +/// This is the equivilent of the `promise.then` JavaScript method. +/// @external(javascript, "../../ffi.mjs", "then") pub fn await(a: Promise(a), b: fn(a) -> Promise(b)) -> Promise(b) +/// Run a function on the value a promise resolves to, after it has resolved. +/// The value returned becomes the new value contained by the promise. +/// @external(javascript, "../../ffi.mjs", "map_promise") pub fn map(a: Promise(a), b: fn(a) -> b) -> Promise(b) +/// Run a function on the value a promise resolves to, after it has resolved. +/// The value returned is discarded. +/// pub fn tap(promise: Promise(a), callback: fn(a) -> b) -> Promise(a) { promise |> map(fn(a) { @@ -28,6 +69,13 @@ pub fn tap(promise: Promise(a), callback: fn(a) -> b) -> Promise(a) { }) } +/// Run a function on the value a promise resolves to, after it has resolved. +/// +/// The function is only called if the value is `Ok`, and the returned becomes +/// the new value contained by the promise. +/// +/// This is a convenience functin that combines the `map` function with `result.try`. +/// pub fn map_try( promise: Promise(Result(a, e)), callback: fn(a) -> Result(b, e), @@ -41,6 +89,15 @@ pub fn map_try( }) } +/// Run a promise returning function on the value a promise resolves to, after +/// it has resolved. +/// +/// The function is only called if the value is `Ok`, and the returned becomes +/// the new value contained by the promise. +/// +/// This is a convenience functin that combines the `await` function with +/// `result.try`. +/// pub fn try_await( promise: Promise(Result(a, e)), callback: fn(a) -> Promise(Result(b, e)), @@ -54,9 +111,19 @@ pub fn try_await( }) } +/// Chain an asynchronous operation onto 2 promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// @external(javascript, "../../ffi.mjs", "all_promises") pub fn await2(a: Promise(a), b: Promise(b)) -> Promise(#(a, b)) +/// Chain an asynchronous operation onto 3 promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// @external(javascript, "../../ffi.mjs", "all_promises") pub fn await3( a: Promise(a), @@ -64,6 +131,11 @@ pub fn await3( c: Promise(c), ) -> Promise(#(a, b, c)) +/// Chain an asynchronous operation onto 4 promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// @external(javascript, "../../ffi.mjs", "all_promises") pub fn await4( a: Promise(a), @@ -72,6 +144,11 @@ pub fn await4( d: Promise(d), ) -> Promise(#(a, b, c, d)) +/// Chain an asynchronous operation onto 5 promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// @external(javascript, "../../ffi.mjs", "all_promises") pub fn await5( a: Promise(a), @@ -81,6 +158,11 @@ pub fn await5( e: Promise(e), ) -> Promise(#(a, b, c, d, e)) +/// Chain an asynchronous operation onto 6 promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// @external(javascript, "../../ffi.mjs", "all_promises") pub fn await6( a: Promise(a), @@ -91,9 +173,19 @@ pub fn await6( f: Promise(f), ) -> Promise(#(a, b, c, d, e, f)) +/// Chain an asynchronous operation onto an array of promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// @external(javascript, "../../ffi.mjs", "all_promises") pub fn await_array(a: Array(Promise(a))) -> Promise(Array(a)) +/// Chain an asynchronous operation onto an list of promises, so it runs after the +/// promises have resolved. +/// +/// This is the equivilent of the `Promise.all` JavaScript static method. +/// pub fn await_list(xs: List(Promise(a))) -> Promise(List(a)) { xs |> do_await_list |