diff --git a/CHANGELOG.md b/CHANGELOG.md index b670bed..b2dd40c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v1.0.0 - 2025-01-03 +- The symbol type and functions have been moved to a new `symbol` module. - Removed the `raceN` and `awaitN` functions from the `promise` module. - Removed the `map` module. - Removed the `type_of` function and `TypeOf` type from the `javascript` module. diff --git a/src/gleam/javascript.gleam b/src/gleam/javascript.gleam deleted file mode 100644 index 4dfa828..0000000 --- a/src/gleam/javascript.gleam +++ /dev/null @@ -1,15 +0,0 @@ -/// Symbols are special unique values in JavaScript. -/// -/// For further information view the MDN documentation: -/// -/// -pub type Symbol - -/// 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: -/// -/// -@external(javascript, "../gleam_javascript_ffi.mjs", "get_symbol") -pub fn get_symbol(a: String) -> Symbol diff --git a/src/gleam/javascript/symbol.gleam b/src/gleam/javascript/symbol.gleam new file mode 100644 index 0000000..2c7ea62 --- /dev/null +++ b/src/gleam/javascript/symbol.gleam @@ -0,0 +1,41 @@ +/// Symbols are special unique values in JavaScript. +/// +/// For further information view the MDN documentation: +/// +/// +pub type Symbol + +/// Creates a new symbol with the given description. +/// +/// Symbols created with this function are "local", they are not in the global +/// symbol registry. +/// +/// For further information see the MDN documentation: +/// +/// +@external(javascript, "../../gleam_javascript_ffi.mjs", "new_symbol") +pub fn new(description: String) -> Symbol + +/// Returns the symbol for the given key from the global symbol registry, +/// creating and registering a new one if one did not already exist. +/// +/// Uses the JavaScript `Symbol.for` internally. +/// +/// For further information see the MDN documentation: +/// +/// +@external(javascript, "../../gleam_javascript_ffi.mjs", "get_symbol") +pub fn get_or_create_global(key: String) -> Symbol + +/// Get the description of the symbol, if it has one. +/// +/// # Examples +/// +/// ```gleam +/// symbol.new("wibble") +/// |> symbol.description +/// // -> Ok("wibble") +/// ``` +/// +@external(javascript, "../../gleam_javascript_ffi.mjs", "symbol_description") +pub fn description(symbol: Symbol) -> Result(String, Nil) diff --git a/src/gleam_javascript_ffi.mjs b/src/gleam_javascript_ffi.mjs index 83e5f59..80bd3b9 100644 --- a/src/gleam_javascript_ffi.mjs +++ b/src/gleam_javascript_ffi.mjs @@ -27,9 +27,17 @@ export function object_from_entries(entries) { return Object.fromEntries(entries); } +export function new_symbol(name) { + return Symbol(name); +} export function get_symbol(name) { return Symbol.for(name); } +export function symbol_description(symbol) { + const description = symbol.description; + if (symbol.description === undefined) return new Error(undefined); + return new Ok(description); +} // A wrapper around a promise to prevent `Promise>` collapsing into // `Promise`. diff --git a/test/gleam/javascript/symbol_test.gleam b/test/gleam/javascript/symbol_test.gleam new file mode 100644 index 0000000..055244e --- /dev/null +++ b/test/gleam/javascript/symbol_test.gleam @@ -0,0 +1,25 @@ +import gleam/javascript/symbol +import gleeunit/should + +pub fn new_test() { + let name = "same name" + + symbol.new(name) + |> should.not_equal(symbol.new(name)) +} + +pub fn get_or_create_global_test() { + let name = "same name" + + symbol.get_or_create_global(name) + |> should.equal(symbol.get_or_create_global(name)) + + symbol.get_or_create_global(name) + |> should.not_equal(symbol.new(name)) +} + +pub fn description_test() { + symbol.new("wibble") + |> symbol.description + |> should.equal(Ok("wibble")) +}