diff --git a/core/src/Core__Array.res b/core/src/Core__Array.res index 312d3ca..9cba129 100644 --- a/core/src/Core__Array.res +++ b/core/src/Core__Array.res @@ -4,9 +4,9 @@ external getUnsafe: (array<'a>, int) => 'a = "%array_unsafe_get" external setUnsafe: (array<'a>, int, 'a) => unit = "%array_unsafe_set" @val external fromIterator: Core__Iterator.t<'a> => array<'a> = "Array.from" -@val external fromArrayLike: Js_types.arrayLike<'a> => array<'a> = "Array.from" +@val external fromArrayLike: Runtime_types.arrayLike<'a> => array<'a> = "Array.from" @val -external fromArrayLikeWithMap: (Js_types.arrayLike<'a>, 'a => 'b) => array<'b> = "Array.from" +external fromArrayLikeWithMap: (Runtime_types.arrayLike<'a>, 'a => 'b) => array<'b> = "Array.from" @send external fillAll: (array<'a>, 'a) => unit = "fill" diff --git a/core/src/Core__Array.resi b/core/src/Core__Array.resi index 1fff314..19cd8c7 100644 --- a/core/src/Core__Array.resi +++ b/core/src/Core__Array.resi @@ -13,11 +13,11 @@ external fromIterator: Core__Iterator.t<'a> => array<'a> = "Array.from" // TODO: Docs -@val external fromArrayLike: Js_types.arrayLike<'a> => array<'a> = "Array.from" +@val external fromArrayLike: Runtime_types.arrayLike<'a> => array<'a> = "Array.from" // TODO: Docs @val -external fromArrayLikeWithMap: (Js_types.arrayLike<'a>, 'a => 'b) => array<'b> = "Array.from" +external fromArrayLikeWithMap: (Runtime_types.arrayLike<'a>, 'a => 'b) => array<'b> = "Array.from" /** `make(~length, init)` diff --git a/core/src/Core__ArrayBuffer.res b/core/src/Core__ArrayBuffer.res index b091d82..10ae0ba 100644 --- a/core/src/Core__ArrayBuffer.res +++ b/core/src/Core__ArrayBuffer.res @@ -1,4 +1,4 @@ -type t = Js_types.arrayBuffer +type t = Runtime_types.arrayBuffer @new external make: int => t = "ArrayBuffer" @get external byteLength: t => int = "byteLength" diff --git a/core/src/Core__Date.res b/core/src/Core__Date.res index 7dc579b..7d63591 100644 --- a/core/src/Core__Date.res +++ b/core/src/Core__Date.res @@ -1,4 +1,4 @@ -type t = Js_types.date +type t = Runtime_types.date type msSinceEpoch = float diff --git a/core/src/Core__Date.resi b/core/src/Core__Date.resi index e547d7b..1fdb281 100644 --- a/core/src/Core__Date.resi +++ b/core/src/Core__Date.resi @@ -5,7 +5,7 @@ /** A type representing a JavaScript date. */ -type t = Js_types.date +type t = Runtime_types.date /** Time, in milliseconds, since / until the UNIX epoch (January 1, 1970 00:00:00 UTC). diff --git a/core/src/Core__Error.res b/core/src/Core__Error.res index 056e4d1..9764a30 100644 --- a/core/src/Core__Error.res +++ b/core/src/Core__Error.res @@ -1,4 +1,4 @@ -type t = Js_types.jsExn +type t = Runtime_types.jsExn external fromException: exn => option = "?as_js_exn" external toException: t => exn = "%identity" diff --git a/core/src/Core__Error.resi b/core/src/Core__Error.resi index b7f45ee..b34019b 100644 --- a/core/src/Core__Error.resi +++ b/core/src/Core__Error.resi @@ -5,7 +5,7 @@ See [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ */ /** Represents a JavaScript exception. */ -type t = Js_types.jsExn +type t = Runtime_types.jsExn external fromException: exn => option = "?as_js_exn" diff --git a/core/src/Core__Global.res b/core/src/Core__Global.res index 9039c21..cad7aaa 100644 --- a/core/src/Core__Global.res +++ b/core/src/Core__Global.res @@ -1,10 +1,10 @@ -type timeoutId = Js_types.timeoutId +type timeoutId = Runtime_types.timeoutId @val external setTimeout: (unit => unit, int) => timeoutId = "setTimeout" @val external setTimeoutFloat: (unit => unit, float) => timeoutId = "setTimeout" @val external clearTimeout: timeoutId => unit = "clearTimeout" -type intervalId = Js_types.intervalId +type intervalId = Runtime_types.intervalId @val external setInterval: (unit => unit, int) => intervalId = "setInterval" @val external setIntervalFloat: (unit => unit, float) => intervalId = "setInterval" diff --git a/core/src/Core__Global.resi b/core/src/Core__Global.resi index 50b6db0..5025079 100644 --- a/core/src/Core__Global.resi +++ b/core/src/Core__Global.resi @@ -7,7 +7,7 @@ An `id` representing a timeout started via `setTimeout`. See [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) on MDN. */ -type timeoutId = Js_types.timeoutId +type timeoutId = Runtime_types.timeoutId /** `setTimeout(callback, durationInMilliseconds)` starts a timer that will execute `callback` after `durationInMilliseconds`. @@ -66,7 +66,7 @@ An `id` representing an interval started via `setInterval`. See [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) on MDN. */ -type intervalId = Js_types.intervalId +type intervalId = Runtime_types.intervalId /** `setInterval(callback, intervalInMilliseconds)` starts an interval that will execute `callback` every `durationInMilliseconds` milliseconds. diff --git a/core/src/Core__JSON.res b/core/src/Core__JSON.res index e4998c9..50b513e 100644 --- a/core/src/Core__JSON.res +++ b/core/src/Core__JSON.res @@ -1,5 +1,5 @@ @unboxed -type rec t = Js_types.json = +type rec t = Runtime_types.json = | Boolean(bool) | @as(null) Null | String(string) @@ -54,8 +54,8 @@ module Classify = { external _asBool: 'a => bool = "%identity" external _asString: 'a => string = "%identity" external _asFloat: 'a => float = "%identity" - external _asArray: 'a => array = "%identity" - external _asDict: 'a => Core__Dict.t = "%identity" + external _asArray: 'a => array = "%identity" + external _asDict: 'a => Core__Dict.t = "%identity" let classify = value => { switch _internalClass(value) { diff --git a/core/src/Core__JSON.resi b/core/src/Core__JSON.resi index 97c50fa..0cb3546 100644 --- a/core/src/Core__JSON.resi +++ b/core/src/Core__JSON.resi @@ -6,7 +6,7 @@ Functions for interacting with JSON. A type representing a JSON object. */ @unboxed -type rec t = Js_types.json = +type rec t = Runtime_types.json = | Boolean(bool) | @as(null) Null | String(string) diff --git a/core/src/Core__Map.res b/core/src/Core__Map.res index 8f04f88..3bc464a 100644 --- a/core/src/Core__Map.res +++ b/core/src/Core__Map.res @@ -1,4 +1,4 @@ -type t<'k, 'v> = Js_types.map<'k, 'v> +type t<'k, 'v> = Runtime_types.map<'k, 'v> @new external make: unit => t<'k, 'v> = "Map" @new external fromArray: array<('k, 'v)> => t<'k, 'v> = "Map" diff --git a/core/src/Core__Map.resi b/core/src/Core__Map.resi index 3199ed3..a99b937 100644 --- a/core/src/Core__Map.resi +++ b/core/src/Core__Map.resi @@ -7,7 +7,7 @@ See [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Gl /** Type representing an instance of `Map`. */ -type t<'k, 'v> = Js_types.map<'k, 'v> +type t<'k, 'v> = Runtime_types.map<'k, 'v> /** Creates a new, mutable JavaScript `Map`. A `Map` can have any values as both keys and values. diff --git a/core/src/Core__Null.res b/core/src/Core__Null.res index 800807b..ae87762 100644 --- a/core/src/Core__Null.res +++ b/core/src/Core__Null.res @@ -1,5 +1,5 @@ @unboxed -type t<'a> = Js_types.null<'a> = +type t<'a> = Runtime_types.null<'a> = | Value('a) | @as(null) Null diff --git a/core/src/Core__Null.resi b/core/src/Core__Null.resi index 19be817..adc9259 100644 --- a/core/src/Core__Null.resi +++ b/core/src/Core__Null.resi @@ -8,7 +8,7 @@ If you also need to cover `undefined`, check out `Nullable` instead. A type representing a value that can be either `'a` or `null`. */ @unboxed -type t<'a> = Js_types.null<'a> = +type t<'a> = Runtime_types.null<'a> = | Value('a) | @as(null) Null diff --git a/core/src/Core__Nullable.res b/core/src/Core__Nullable.res index 2c60435..ec12cc1 100644 --- a/core/src/Core__Nullable.res +++ b/core/src/Core__Nullable.res @@ -1,5 +1,5 @@ @unboxed -type t<'a> = Js_types.nullable<'a> = +type t<'a> = Runtime_types.nullable<'a> = | Value('a) | @as(null) Null | @as(undefined) Undefined diff --git a/core/src/Core__Nullable.resi b/core/src/Core__Nullable.resi index 3b90286..af1851c 100644 --- a/core/src/Core__Nullable.resi +++ b/core/src/Core__Nullable.resi @@ -9,7 +9,7 @@ Type representing a nullable value. A nullable value can be the value `'a`, `null` or `undefined`. */ @unboxed -type t<'a> = Js_types.nullable<'a> = +type t<'a> = Runtime_types.nullable<'a> = | Value('a) | @as(null) Null | @as(undefined) Undefined diff --git a/core/src/Core__RegExp.res b/core/src/Core__RegExp.res index 4f224a5..8243438 100644 --- a/core/src/Core__RegExp.res +++ b/core/src/Core__RegExp.res @@ -1,4 +1,4 @@ -type t = Js_types.regExp +type t = Runtime_types.regExp module Result = { type t = array> diff --git a/core/src/Core__RegExp.resi b/core/src/Core__RegExp.resi index 318b4dc..fa95b6d 100644 --- a/core/src/Core__RegExp.resi +++ b/core/src/Core__RegExp.resi @@ -7,7 +7,7 @@ See [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /** Type representing an instantiated `RegExp`. */ -type t = Js_types.regExp +type t = Runtime_types.regExp module Result: { /** diff --git a/core/src/Core__Set.res b/core/src/Core__Set.res index 33c4405..bd6c3f3 100644 --- a/core/src/Core__Set.res +++ b/core/src/Core__Set.res @@ -1,4 +1,4 @@ -type t<'a> = Js_types.set<'a> +type t<'a> = Runtime_types.set<'a> @new external make: unit => t<'a> = "Set" @new external fromArray: array<'a> => t<'a> = "Set" diff --git a/core/src/Core__Set.resi b/core/src/Core__Set.resi index c7ddd53..e332151 100644 --- a/core/src/Core__Set.resi +++ b/core/src/Core__Set.resi @@ -7,7 +7,7 @@ See [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Gl /** Type representing an instance of `Set`. */ -type t<'a> = Js_types.set<'a> +type t<'a> = Runtime_types.set<'a> /** Creates a new, mutable JavaScript `Set`. A `Set` is a collection of unique values. diff --git a/core/src/Core__Symbol.res b/core/src/Core__Symbol.res index 863f787..f946640 100644 --- a/core/src/Core__Symbol.res +++ b/core/src/Core__Symbol.res @@ -1,4 +1,4 @@ -type t = Js_types.symbol +type t = Runtime_types.symbol @val external make: string => t = "Symbol" @val external getFor: string => t = "Symbol.for" diff --git a/core/src/Core__WeakMap.res b/core/src/Core__WeakMap.res index d6a30d7..1fada23 100644 --- a/core/src/Core__WeakMap.res +++ b/core/src/Core__WeakMap.res @@ -1,4 +1,4 @@ -type t<'k, 'v> = Js_types.weakMap<'k, 'v> +type t<'k, 'v> = Runtime_types.weakMap<'k, 'v> @new external make: unit => t<'k, 'v> = "WeakMap" diff --git a/core/src/Core__WeakSet.res b/core/src/Core__WeakSet.res index 9ca597b..f7ef863 100644 --- a/core/src/Core__WeakSet.res +++ b/core/src/Core__WeakSet.res @@ -1,4 +1,4 @@ -type t<'a> = Js_types.weakSet<'a> +type t<'a> = Runtime_types.weakSet<'a> @new external make: unit => t<'a> = "WeakSet" diff --git a/core/src/RescriptCore.res b/core/src/RescriptCore.res index d3b36d1..a976662 100644 --- a/core/src/RescriptCore.res +++ b/core/src/RescriptCore.res @@ -44,8 +44,8 @@ module BigUint64Array = Core__BigUint64Array module Intl = Core__Intl -@val external window: Js_types.window = "window" -@val external document: Js_types.document = "document" +@val external window: Runtime_types.window = "window" +@val external document: Runtime_types.document = "document" @val external globalThis: {..} = "globalThis" external null: Core__Nullable.t<'a> = "#null" @@ -105,10 +105,10 @@ module Option = Core__Option module List = Core__List module Result = Core__Result -type null<+'a> = Js_types.null<'a> +type null<+'a> = Runtime_types.null<'a> -type undefined<+'a> = Js_types.undefined<'a> +type undefined<+'a> = Runtime_types.undefined<'a> -type nullable<+'a> = Js_types.nullable<'a> +type nullable<+'a> = Runtime_types.nullable<'a> let panic = Core__Error.panic diff --git a/js/package.json b/js/package.json new file mode 100644 index 0000000..a8ab47c --- /dev/null +++ b/js/package.json @@ -0,0 +1,4 @@ +{ + "name": "js", + "version": "0.0.0" +} diff --git a/js/rescript.json b/js/rescript.json new file mode 100644 index 0000000..f8caa51 --- /dev/null +++ b/js/rescript.json @@ -0,0 +1,9 @@ +{ + "name": "js", + "sources": { + "dir": "src", + "subdirs": true + }, + "bs-dependencies": ["stdlib-mini"], + "bsc-flags": ["-nostdlib", "-nopervasives", "-open Stdlib_mini"] +} diff --git a/js/src/js.js b/js/src/js.js new file mode 100644 index 0000000..a10b6b4 --- /dev/null +++ b/js/src/js.js @@ -0,0 +1,114 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var Internal = {}; + +var Null; + +var Undefined; + +var Nullable; + +var Null_undefined; + +var Exn; + +var $$Array; + +var Array2; + +var $$String; + +var String2; + +var Re; + +var $$Promise; + +var Promise2; + +var $$Date; + +var Dict; + +var Global; + +var Json; + +var $$Math; + +var Obj; + +var Typed_array; + +var TypedArray2; + +var Types; + +var Float; + +var Int; + +var $$BigInt; + +var $$File; + +var $$Blob; + +var $$Option; + +var Result; + +var List; + +var Vector; + +var Console; + +var $$Set; + +var $$WeakSet; + +var $$Map; + +var $$WeakMap; + +export { + Internal , + Null , + Undefined , + Nullable , + Null_undefined , + Exn , + $$Array , + Array2 , + $$String , + String2 , + Re , + $$Promise , + Promise2 , + $$Date , + Dict , + Global , + Json , + $$Math , + Obj , + Typed_array , + TypedArray2 , + Types , + Float , + Int , + $$BigInt , + $$File , + $$Blob , + $$Option , + Result , + List , + Vector , + Console , + $$Set , + $$WeakSet , + $$Map , + $$WeakMap , +} +/* No side effect */ diff --git a/js/src/js.res b/js/src/js.res new file mode 100644 index 0000000..88682d9 --- /dev/null +++ b/js/src/js.res @@ -0,0 +1,281 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@@config({flags: ["-unboxed-types", "-w", "-49"]}) +/* DESIGN: + - It does not have any code, all its code will be inlined so that + there will never be + {[ require('js')]} + - Its interface should be minimal + */ + +/** +The Js module mostly contains ReScript bindings to _standard JavaScript APIs_ +like [console.log](https://developer.mozilla.org/en-US/docs/Web/API/Console/log), +or the JavaScript +[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), +[Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), and +[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) +classes. + +It is meant as a zero-abstraction interop layer and directly exposes JavaScript functions as they are. If you can find your API in this module, prefer this over an equivalent Belt helper. For example, prefer [Js.Array2](js/array2) over [Belt.Array](belt/array) + +## Argument Order + +For historical reasons, some APIs in the Js namespace (e.g. [Js.String](js/string)) are +using the data-last argument order whereas others (e.g. [Js.Date](js/date)) are using data-first. + +For more information about these argument orders and the trade-offs between them, see +[this blog post](https://www.javierchavarri.com/data-first-and-data-last-a-comparison/). + +_Eventually, all modules in the Js namespace are going to be migrated to data-first though._ + +In the meantime, there are several options for dealing with the data-last APIs: + +## Examples + +```rescript +/* Js.String (data-last API used with pipe last operator) */ +Js.log("2019-11-10" |> Js.String.split("-")) +Js.log("ReScript" |> Js.String.startsWith("Re")) + +/* Js.String (data-last API used with pipe first operator) */ +Js.log("2019-11-10"->Js.String.split("-", _)) +Js.log("ReScript"->Js.String.startsWith("Re", _)) + +/* Js.String (data-last API used without any piping) */ +Js.log(Js.String.split("-", "2019-11-10")) +Js.log(Js.String.startsWith("Re", "ReScript")) +``` +## Js.Xxx2 Modules + +Prefer `Js.Array2` over `Js.Array`, `Js.String2` over `Js.String`, etc. The latters are old modules. +*/ +/** JS object type */ +type t<'a> = {..} as 'a + +module Internal = { + external opaqueFullApply: 'a => 'a = "%uncurried_apply" + + /* Use opaque instead of [._n] to prevent some optimizations happening */ + external run: (unit => 'a) => 'a = "#run" + external opaque: 'a => 'a = "%opaque" +} + +/** + Nullable value of this type can be either null or 'a. This type is equivalent to Js.Null.t. +*/ +type null<+'a> = Js_null.t<'a> + +/** + A value of this type can be either undefined or 'a. This type is equivalent to Js.Undefined.t. +*/ +type undefined<+'a> = Js_undefined.t<'a> + +type nullable<+'a> = Js_nullable.t<'a> + +/** + A value of this type can be undefined, null or 'a. This type is equivalent to Js.Null_undefined.t. +*/ +type null_undefined<+'a> = nullable<'a> + +external toOption: nullable<'a> => option<'a> = "#nullable_to_opt" +external undefinedToOption: undefined<'a> => option<'a> = "#undefined_to_opt" +external nullToOption: null<'a> => option<'a> = "#null_to_opt" +external isNullable: nullable<'a> => bool = "#is_nullable" +external import: 'a => promise<'a> = "#import" + +/** The same as {!test} except that it is more permissive on the types of input */ +external testAny: 'a => bool = "#is_nullable" + +/** + The promise type, defined here for interoperation across packages. +*/ +type promise<+'a, +'e> + +/** + The same as empty in `Js.Null`. Compiles to `null`. +*/ +external null: null<'a> = "#null" + +/** + The same as empty `Js.Undefined`. Compiles to `undefined`. +*/ +external undefined: undefined<'a> = "#undefined" + +/** +`typeof x` will be compiled as `typeof x` in JS. Please consider functions in +`Js.Types` for a type safe way of reflection. +*/ +external typeof: 'a => string = "#typeof" + +/** Equivalent to console.log any value. */ +@val +@scope("console") +external log: 'a => unit = "log" + +@val @scope("console") external log2: ('a, 'b) => unit = "log" +@val @scope("console") external log3: ('a, 'b, 'c) => unit = "log" +@val @scope("console") external log4: ('a, 'b, 'c, 'd) => unit = "log" + +/** A convenience function to console.log more than 4 arguments */ +@val +@scope("console") +@variadic +external logMany: array<'a> => unit = "log" + +external eqNull: ('a, null<'a>) => bool = "%bs_equal_null" +external eqUndefined: ('a, undefined<'a>) => bool = "%bs_equal_undefined" +external eqNullable: ('a, nullable<'a>) => bool = "%bs_equal_nullable" + +/** ## Operators */ +/** + `unsafe_lt(a, b)` will be compiled as `a < b`. + It is marked as unsafe, since it is impossible + to give a proper semantics for comparision which applies to any type +*/ +external unsafe_lt: ('a, 'a) => bool = "#unsafe_lt" + +/** + `unsafe_le(a, b)` will be compiled as `a <= b`. + See also `Js.unsafe_lt`. +*/ +external unsafe_le: ('a, 'a) => bool = "#unsafe_le" + +/** + `unsafe_gt(a, b)` will be compiled as `a > b`. + See also `Js.unsafe_lt`. +*/ +external unsafe_gt: ('a, 'a) => bool = "#unsafe_gt" + +/** + `unsafe_ge(a, b)` will be compiled as `a >= b`. + See also `Js.unsafe_lt`. +*/ +external unsafe_ge: ('a, 'a) => bool = "#unsafe_ge" + +/** ## Nested Modules */ +/** Provide utilities for `Js.null<'a>` */ +module Null = Js_null + +/** Provide utilities for `Js.undefined<'a>` */ +module Undefined = Js_undefined + +/** Provide utilities for `Js.null_undefined` */ +module Nullable = Js_null_undefined + +module Null_undefined = Js_null_undefined + +/** Provide utilities for dealing with Js exceptions */ +module Exn = Js_exn + +/** Provide bindings to JS array*/ +module Array = Js_array + +/** Provide bindings to JS array*/ +module Array2 = Js_array2 + +/** Provide bindings to JS string */ +module String = Js_string + +/** Provide bindings to JS string */ +module String2 = Js_string2 + +/** Provide bindings to JS regex expression */ +module Re = Js_re + +/** Provide bindings to JS Promise */ +module Promise = Js_promise + +/** Provide bindings to JS Promise */ +module Promise2 = Js_promise2 + +/** Provide bindings for JS Date */ +module Date = Js_date + +/** Provide utilities for JS dictionary object */ +module Dict = Js_dict + +/** Provide bindings to JS global functions in global namespace*/ +module Global = Js_global + +/** Provide utilities for json */ +module Json = Js_json + +/** Provide bindings for JS `Math` object */ +module Math = Js_math + +/** Provide utilities for `Js.t` */ +module Obj = Js_obj + +/** Provide bindings for JS typed array */ +module Typed_array = Js_typed_array + +/** Provide bindings for JS typed array */ +module TypedArray2 = Js_typed_array2 + +/** Provide utilities for manipulating JS types */ +module Types = Js_types + +/** Provide utilities for JS float */ +module Float = Js_float + +/** Provide utilities for int */ +module Int = Js_int + +/** Provide utilities for bigint */ +module BigInt = Js_bigint + +/** Provide utilities for File */ +module File = Js_file + +/** Provide utilities for Blob */ +module Blob = Js_blob + +/** Provide utilities for option */ +module Option = Js_option + +/** Define the interface for result */ +module Result = Js_result + +/** Provide utilities for list */ +module List = Js_list + +/** Provides bindings for JS Vector */ +module Vector = Js_vector + +/** Provides bindings for console */ +module Console = Js_console + +/** Provides bindings for ES6 Set */ +module Set = Js_set + +/** Provides bindings for ES6 WeakSet */ +module WeakSet = Js_weakset + +/** Provides bindings for ES6 Map */ +module Map = Js_map + +/** Provides bindings for ES6 WeakMap */ +module WeakMap = Js_weakmap diff --git a/js/src/js_OO.res b/js/src/js_OO.res new file mode 100644 index 0000000..033ab69 --- /dev/null +++ b/js/src/js_OO.res @@ -0,0 +1,52 @@ +/* Copyright (C) 2020- Hongbo Zhang, Authors of ReScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@@config({flags: ["-unboxed-types"]}) + +external unsafe_to_method: 'a => 'a = "#fn_method" + +module Callback = { + type arity1<'a> = {@internal i1: 'a} + type arity2<'a> = {@internal i2: 'a} + type arity3<'a> = {@internal i3: 'a} + type arity4<'a> = {@internal i4: 'a} + type arity5<'a> = {@internal i5: 'a} + type arity6<'a> = {@internal i6: 'a} + type arity7<'a> = {@internal i7: 'a} + type arity8<'a> = {@internal i8: 'a} + type arity9<'a> = {@internal i9: 'a} + type arity10<'a> = {@internal i10: 'a} + type arity11<'a> = {@internal i11: 'a} + type arity12<'a> = {@internal i12: 'a} + type arity13<'a> = {@internal i13: 'a} + type arity14<'a> = {@internal i14: 'a} + type arity15<'a> = {@internal i15: 'a} + type arity16<'a> = {@internal i16: 'a} + type arity17<'a> = {@internal i17: 'a} + type arity18<'a> = {@internal i18: 'a} + type arity19<'a> = {@internal i19: 'a} + type arity20<'a> = {@internal i20: 'a} + type arity21<'a> = {@internal i21: 'a} + type arity22<'a> = {@internal i22: 'a} +} diff --git a/stdlib-mini/src/js_types.js b/js/src/js_array.js similarity index 100% rename from stdlib-mini/src/js_types.js rename to js/src/js_array.js diff --git a/js/src/js_array.res b/js/src/js_array.res new file mode 100644 index 0000000..ff469e9 --- /dev/null +++ b/js/src/js_array.res @@ -0,0 +1,1087 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provides bindings to JavaScript’s `Array` functions. These bindings are +optimized for pipe-last (`|>`), where the array to be processed is the last +parameter in the function. + +Here is an example to find the sum of squares of all even numbers in an array. +Without pipe last, we must call the functions in reverse order: + +## Examples + +```rescript +let isEven = x => mod(x, 2) == 0 +let square = x => x * x +let result = { + open Js.Array + reduce(\"+", 0, map(square, filter(isEven, [5, 2, 3, 4, 1]))) +} +``` + +With pipe last, we call the functions in the “natural” order: + +```rescript +let isEven = x => mod(x, 2) == 0 +let square = x => x * x +let result = { + open Js.Array + [5, 2, 3, 4, 1] |> filter(isEven) |> map(square) |> reduce("+", 0) +} +``` +*/ + +@@warning("-103") + +/** +The type used to describe a JavaScript array. +*/ +type t<'a> = array<'a> + +/** +A type used to describe JavaScript objects that are like an array or are iterable. +*/ +type array_like<'a> = Js_array2.array_like<'a> + +/* commented out until bs has a plan for iterators + type 'a array_iter = 'a array_like +*/ + +@val +/** +Creates a shallow copy of an array from an array-like object. See [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) on MDN. + +## Examples + +```rescript +let strArr = Js.String.castToArrayLike("abcd") +Js.Array.from(strArr) == ["a", "b", "c", "d"] +``` +*/ +external from: array_like<'a> => array<'a> = "Array.from" + +/* ES2015 */ + +@val +/** +Creates a new array by applying a function (the second argument) to each item +in the `array_like` first argument. See +[`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) +on MDN. + +## Examples + +```rescript +let strArr = Js.String.castToArrayLike("abcd") +let code = s => Js.String.charCodeAt(0, s) +Js.Array.fromMap(strArr, code) == [97.0, 98.0, 99.0, 100.0] +``` +*/ +external fromMap: (array_like<'a>, ('a => 'b)) => array<'b> = "Array.from" + +/* ES2015 */ + +@val external isArray: 'a => bool = "Array.isArray" +/* ES2015 */ +/* +Returns `true` if its argument is an array; `false` otherwise. This is a +runtime check, which is why the second example returns `true` — a list is +internally represented as a nested JavaScript array. + +## Examples + +```rescript +Js.Array.isArray([5, 2, 3, 1, 4]) == true +Js.Array.isArray(list{5, 2, 3, 1, 4}) == true +Js.Array.isArray("abcd") == false +``` +*/ + +@get +/** +Returns the number of elements in the array. See [`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) on MDN. +*/ +external length: array<'a> => int = "length" + +/* Mutator functions */ + +@send.pipe(: t<'a> as 'this) +/** +Copies from the first element in the given array to the designated `~to_` position, returning the resulting array. *This function modifies the original array.* See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.copyWithin(~to_=2, arr) == [100, 101, 100, 101, 102] +arr == [100, 101, 100, 101, 102] +``` +*/ +external copyWithin: (~to_: int) => 'this = "copyWithin" + +/* ES2015 */ + +@send.pipe(: t<'a> as 'this) +/** +Copies starting at element `~from` in the given array to the designated `~to_` position, returning the resulting array. *This function modifies the original array.* See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.copyWithinFrom(~from=2, ~to_=0, arr) == [102, 103, 104, 103, 104] +arr == [102, 103, 104, 103, 104] +``` +*/ +external copyWithinFrom: (~to_: int, ~from: int) => 'this = "copyWithin" + +/* ES2015 */ + +@send.pipe(: t<'a> as 'this) +/** +Copies starting at element `~start` in the given array up to but not including `~end_` to the designated `~to_` position, returning the resulting array. *This function modifies the original array.* See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104, 105] +Js.Array.copyWithinFromRange(~start=2, ~end_=5, ~to_=1, arr) == [100, 102, 103, 104, 104, 105] +arr == [100, 102, 103, 104, 104, 105] +``` +*/ +external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => 'this = "copyWithin" + +/* ES2015 */ + +@send.pipe(: t<'a> as 'this) +/** +Sets all elements of the given array (the second arumgent) to the designated value (the first argument), returning the resulting array. *This function modifies the original array.* See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.fillInPlace(99, arr) == [99, 99, 99, 99, 99] +arr == [99, 99, 99, 99, 99] +``` +*/ +external fillInPlace: 'a => 'this = "fill" + +/* ES2015 */ + +@send.pipe(: t<'a> as 'this) +/** +Sets all elements of the given array (the last arumgent) from position `~from` to the end to the designated value (the first argument), returning the resulting array. *This function modifies the original array.* See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.fillFromInPlace(99, ~from=2, arr) == [100, 101, 99, 99, 99] +arr == [100, 101, 99, 99, 99] +``` +*/ +external fillFromInPlace: ('a, ~from: int) => 'this = "fill" + +/* ES2015 */ + +@send.pipe(: t<'a> as 'this) +/** +Sets the elements of the given array (the last arumgent) from position `~start` up to but not including position `~end_` to the designated value (the first argument), returning the resulting array. *This function modifies the original array.* See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.fillRangeInPlace(99, ~start=1, ~end_=4, arr) == [100, 99, 99, 99, 104] +arr == [100, 99, 99, 99, 104] +``` +*/ +external fillRangeInPlace: ('a, ~start: int, ~end_: int) => 'this = "fill" + +/* ES2015 */ + +@send.pipe(: t<'a> as 'this) +@return(nullable) +/** +If the array is not empty, removes the last element and returns it as `Some(value)`; returns `None` if the array is empty. *This function modifies the original array.* See [`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.pop(arr) == Some(104) +arr == [100, 101, 102, 103] + +let empty: array = [] +Js.Array.pop(empty) == None +``` +*/ +external pop: option<'a> = "pop" + +@send.pipe(: t<'a> as 'this) +/** +Appends the given value to the array, returning the number of elements in the updated array. *This function modifies the original array.* See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN. + +## Examples + +```rescript +let arr = ["ant", "bee", "cat"] +Js.Array.push("dog", arr) == 4 +arr == ["ant", "bee", "cat", "dog"] +``` +*/ +external push: 'a => int = "push" + +@send.pipe(: t<'a> as 'this) +@variadic +/** +Appends the values from one array (the first argument) to another (the second argument), returning the number of elements in the updated array. *This function modifies the original array.* See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN. + +## Examples + +```rescript +let arr = ["ant", "bee", "cat"] +Js.Array.pushMany(["dog", "elk"], arr) == 5 +arr == ["ant", "bee", "cat", "dog", "elk"] +``` +*/ +external pushMany: array<'a> => int = "push" + +@send.pipe(: t<'a> as 'this) +/** +Returns an array with the elements of the input array in reverse order. *This function modifies the original array.* See [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN. + +## Examples + +```rescript +let arr = ["ant", "bee", "cat"] +Js.Array.reverseInPlace(arr) == ["cat", "bee", "ant"] +arr == ["cat", "bee", "ant"] +``` +*/ +external reverseInPlace: 'this = "reverse" + +@send.pipe(: t<'a> as 'this) +@return(nullable) +/** +If the array is not empty, removes the first element and returns it as `Some(value)`; returns `None` if the array is empty. *This function modifies the original array.* See [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array.shift(arr) == Some(100) +arr == [101, 102, 103, 104] + +let empty: array = [] +Js.Array.shift(empty) == None +``` +*/ +external shift: option<'a> = "shift" + +@send.pipe(: t<'a> as 'this) +/** +Sorts the given array in place and returns the sorted array. JavaScript sorts the array by converting the arguments to UTF-16 strings and sorting them. See the second example with sorting numbers, which does not do a numeric sort. *This function modifies the original array.* See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN. + +## Examples + +```rescript +let words = ["bee", "dog", "ant", "cat"] +Js.Array.sortInPlace(words) == ["ant", "bee", "cat", "dog"] +words == ["ant", "bee", "cat", "dog"] + +let numbers = [3, 30, 10, 1, 20, 2] +Js.Array.sortInPlace(numbers) == [1, 10, 2, 20, 3, 30] +numbers == [1, 10, 2, 20, 3, 30] +``` +*/ +external sortInPlace: 'this = "sort" + +@send.pipe(: t<'a> as 'this) +/** +Sorts the given array in place and returns the sorted array. *This function modifies the original array.* + +The first argument to `sortInPlaceWith()` is a function that compares two items from the array and returns: + +* an integer less than zero if the first item is less than the second item +* zero if the items are equal +* an integer greater than zero if the first item is greater than the second item + +See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN. + +## Examples + +```rescript +// sort by word length +let words = ["horse", "aardvark", "dog", "camel"] +let byLength = (s1, s2) => Js.String.length(s1) - Js.String.length(s2) + +Js.Array.sortInPlaceWith(byLength, words) == ["dog", "horse", "camel", "aardvark"] + +// sort in reverse numeric order +let numbers = [3, 30, 10, 1, 20, 2] +let reverseNumeric = (n1, n2) => n2 - n1 +Js.Array.sortInPlaceWith(reverseNumeric, numbers) == [30, 20, 10, 3, 2, 1] +``` +*/ +external sortInPlaceWith: (('a, 'a) => int) => 'this = "sort" + +@send.pipe(: t<'a> as 'this) +@variadic +/** +Starting at position `~pos`, remove `~remove` elements and then add the +elements from the `~add` array. Returns an array consisting of the removed +items. *This function modifies the original array.* See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +## Examples + +```rescript +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array.spliceInPlace(~pos=2, ~remove=2, ~add=["x", "y", "z"], arr) == ["c", "d"] +arr == ["a", "b", "x", "y", "z", "e", "f"] + +let arr2 = ["a", "b", "c", "d"] +Js.Array.spliceInPlace(~pos=3, ~remove=0, ~add=["x", "y"], arr2) == [] +arr2 == ["a", "b", "c", "x", "y", "d"] + +let arr3 = ["a", "b", "c", "d", "e", "f"] +Js.Array.spliceInPlace(~pos=9, ~remove=2, ~add=["x", "y", "z"], arr3) == [] +arr3 == ["a", "b", "c", "d", "e", "f", "x", "y", "z"] +``` +*/ +external spliceInPlace: (~pos: int, ~remove: int, ~add: array<'a>) => 'this = "splice" + +@send.pipe(: t<'a> as 'this) +/** +Removes elements from the given array starting at position `~pos` to the end +of the array, returning the removed elements. *This function modifies the +original array.* See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +## Examples + +```rescript +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array.removeFromInPlace(~pos=4, arr) == ["e", "f"] +arr == ["a", "b", "c", "d"] +``` +*/ +external removeFromInPlace: (~pos: int) => 'this = "splice" + +@send.pipe(: t<'a> as 'this) +/** +Removes `~count` elements from the given array starting at position `~pos`, +returning the removed elements. *This function modifies the original array.* +See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +## Examples + +```rescript +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array.removeCountInPlace(~pos=2, ~count=3, arr) == ["c", "d", "e"] +arr == ["a", "b", "f"] +``` +*/ +external removeCountInPlace: (~pos: int, ~count: int) => 'this = "splice" + +@send.pipe(: t<'a> as 'this) +/** +Adds the given element to the array, returning the new number of elements in +the array. *This function modifies the original array.* See +[`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) +on MDN. + +## Examples + +```rescript +let arr = ["b", "c", "d"] +Js.Array.unshift("a", arr) == 4 +arr == ["a", "b", "c", "d"] +``` +*/ +external unshift: 'a => int = "unshift" + +@send.pipe(: t<'a> as 'this) +@variadic +/** +Adds the elements in the first array argument at the beginning of the second +array argument, returning the new number of elements in the array. *This +function modifies the original array.* See +[`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) +on MDN. + +## Examples + +```rescript +let arr = ["d", "e"] +Js.Array.unshiftMany(["a", "b", "c"], arr) == 5 +arr == ["a", "b", "c", "d", "e"] +``` +*/ +external unshiftMany: array<'a> => int = "unshift" + +/* Accessor functions + */ +@send.pipe(: t<'a> as 'this) +/** +Concatenates the first array argument to the second array argument, returning +a new array. The original arrays are not modified. See +[`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) +on MDN. + +## Examples + +```rescript +Js.Array.concat(["c", "d", "e"], ["a", "b"]) == ["a", "b", "c", "d", "e"] +``` +*/ +external concat: 'this => 'this = "concat" + +@send.pipe(: t<'a> as 'this) +@variadic +/** +The first argument to `concatMany()` is an array of arrays; these are added +at the end of the second argument, returning a new array. See +[`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) +on MDN. + +## Examples + +```rescript +Js.Array.concatMany([["d", "e"], ["f", "g", "h"]], ["a", "b", "c"]) == [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + ] +``` +*/ +external concatMany: array<'this> => 'this = "concat" + +/* ES2016 */ +@send.pipe(: t<'a> as 'this) +/** +Returns true if the given value is in the array, `false` otherwise. See +[`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) +on MDN. + +## Examples + +```rescript +Js.Array.includes("b", ["a", "b", "c"]) == true +Js.Array.includes("x", ["a", "b", "c"]) == false +``` +*/ +external includes: 'a => bool = "includes" + +@send.pipe(: t<'a> as 'this) +/** +Returns the index of the first element in the array that has the given value. +If the value is not in the array, returns -1. See +[`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) +on MDN. + +## Examples + +```rescript +Js.Array.indexOf(102, [100, 101, 102, 103]) == 2 +Js.Array.indexOf(999, [100, 101, 102, 103]) == -1 +``` +*/ +external indexOf: 'a => int = "indexOf" + +@send.pipe(: t<'a> as 'this) +/** +Returns the index of the first element in the array with the given value. The +search starts at position `~from`. See +[`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) +on MDN. + +## Examples + +```rescript +Js.Array.indexOfFrom("a", ~from=2, ["a", "b", "a", "c", "a"]) == 2 +Js.Array.indexOfFrom("a", ~from=3, ["a", "b", "a", "c", "a"]) == 4 +Js.Array.indexOfFrom("b", ~from=2, ["a", "b", "a", "c", "a"]) == -1 +``` +*/ +external indexOfFrom: ('a, ~from: int) => int = "indexOf" + +@send @deprecated("please use joinWith instead") +external join: t<'a> => string = "join" + +@send.pipe(: t<'a> as 'this) +/** +This function converts each element of the array to a string (via JavaScript) +and concatenates them, separated by the string given in the first argument, +into a single string. See +[`Array.join`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) +on MDN. + +## Examples + +```rescript +Js.Array.joinWith("--", ["ant", "bee", "cat"]) == "ant--bee--cat" +Js.Array.joinWith("", ["door", "bell"]) == "doorbell" +Js.Array.joinWith("/", [2020, 9, 4]) == "2020/9/4" +Js.Array.joinWith(";", [2.5, 3.6, 3e-2]) == "2.5;3.6;0.03" +``` +*/ +external joinWith: string => string = "join" + +@send.pipe(: t<'a> as 'this) +/** +Returns the index of the last element in the array that has the given value. +If the value is not in the array, returns -1. See +[`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.Array.lastIndexOf("a", ["a", "b", "a", "c"]) == 2 +Js.Array.lastIndexOf("x", ["a", "b", "a", "c"]) == -1 +``` +*/ +external lastIndexOf: 'a => int = "lastIndexOf" + +@send.pipe(: t<'a> as 'this) +/** +Returns the index of the last element in the array that has the given value, +searching from position `~from` down to the start of the array. If the value +is not in the array, returns -1. See +[`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.Array.lastIndexOfFrom("a", ~from=3, ["a", "b", "a", "c", "a", "d"]) == 2 +Js.Array.lastIndexOfFrom("c", ~from=2, ["a", "b", "a", "c", "a", "d"]) == -1 +``` +*/ +external lastIndexOfFrom: ('a, ~from: int) => int = "lastIndexOf" + +@send.pipe(: t<'a> as 'this) +/** +Returns a shallow copy of the given array from the `~start` index up to but +not including the `~end_` position. Negative numbers indicate an offset from +the end of the array. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104, 105, 106] +Js.Array.slice(~start=2, ~end_=5, arr) == [102, 103, 104] +Js.Array.slice(~start=-3, ~end_=-1, arr) == [104, 105] +Js.Array.slice(~start=9, ~end_=10, arr) == [] +``` +*/ +external slice: (~start: int, ~end_: int) => 'this = "slice" + +@send.pipe(: t<'a> as 'this) +/** +Returns a copy of the entire array. Same as `Js.Array.Slice(~start=0, +~end_=Js.Array.length(arr), arr)`. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. +*/ +external copy: 'this = "slice" + +@send.pipe(: t<'a> as 'this) +/** +Returns a shallow copy of the given array from the given index to the end. +See [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN. + +## Examples + +```rescript +Js.Array.sliceFrom(2, [100, 101, 102, 103, 104]) == [102, 103, 104] +``` +*/ +external sliceFrom: int => 'this = "slice" + +@send.pipe(: t<'a> as 'this) +/** +Converts the array to a string. Each element is converted to a string using +JavaScript. Unlike the JavaScript `Array.toString()`, all elements in a +ReasonML array must have the same type. See +[`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) +on MDN. + +## Examples + +```rescript +Js.Array.toString([3.5, 4.6, 7.8]) == "3.5,4.6,7.8" +Js.Array.toString(["a", "b", "c"]) == "a,b,c" +``` +*/ +external toString: string = "toString" + +@send.pipe(: t<'a> as 'this) +/** +Converts the array to a string using the conventions of the current locale. +Each element is converted to a string using JavaScript. Unlike the JavaScript +`Array.toLocaleString()`, all elements in a ReasonML array must have the same +type. See +[`Array.toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString) +on MDN. + +## Examples + +```rescript +Js.Array.toLocaleString([Js.Date.make()]) +// returns "3/19/2020, 10:52:11 AM" for locale en_US.utf8 +// returns "2020-3-19 10:52:11" for locale de_DE.utf8 +``` +*/ +external toLocaleString: string = "toLocaleString" + +/* Iteration functions + */ +/* commented out until bs has a plan for iterators + external entries : (int * 'a) array_iter = "" [@@send.pipe: 'a t as 'this] (* ES2015 *) +*/ + +@send.pipe(: t<'a> as 'this) +/** +The first argument to `every()` is a predicate function that returns a boolean. The `every()` function returns `true` if the predicate function is true for all items in the given array. If given an empty array, returns `true`. See [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN. + +## Examples + +```rescript +let isEven = x => mod(x, 2) == 0 +Js.Array.every(isEven, [6, 22, 8, 4]) == true +Js.Array.every(isEven, [6, 22, 7, 4]) == false +``` +*/ +external every: (('a => bool)) => bool = "every" + +@send.pipe(: t<'a> as 'this) +/** +The first argument to `everyi()` is a predicate function with two arguments: an array element and that element’s index; it returns a boolean. The `everyi()` function returns `true` if the predicate function is true for all items in the given array. If given an empty array, returns `true`. See [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN. + +## Examples + +```rescript +// determine if all even-index items are positive +let evenIndexPositive = (item, index) => mod(index, 2) == 0 ? item > 0 : true + +Js.Array.everyi(evenIndexPositive, [6, -3, 5, 8]) == true +Js.Array.everyi(evenIndexPositive, [6, 3, -5, 8]) == false +``` +*/ +external everyi: (('a, int) => bool) => bool = "every" + +@send.pipe(: t<'a> as 'this) +/** +Applies the given predicate function to each element in the array; the result is an array of those elements for which the predicate function returned `true`. See [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN. + +## Examples + +```rescript +let nonEmpty = s => s != "" +Js.Array.filter(nonEmpty, ["abc", "", "", "def", "ghi"]) == ["abc", "def", "ghi"] +``` +*/ +external filter: (('a => bool)) => 'this = "filter" + +@send.pipe(: t<'a> as 'this) +/** +Each element of the given array are passed to the predicate function. The +return value is an array of all those elements for which the predicate +function returned `true`. See +[`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) +on MDN. + +## Examples + +```rescript +// keep only positive elements at odd indices +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array.filteri(positiveOddElement, [6, 3, 5, 8, 7, -4, 1]) == [3, 8] +``` +*/ +external filteri: (('a, int) => bool) => 'this = "filter" + +@send.pipe(: t<'a> as 'this) +@return(nullable) +/** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. +See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +## Examples + +```rescript +// find first negative element +Js.Array.find(x => x < 0, [33, 22, -55, 77, -44]) == Some(-55) +Js.Array.find(x => x < 0, [33, 22, 55, 77, 44]) == None +``` +*/ +external find: (('a => bool)) => option<'a> = "find" + +@send.pipe(: t<'a> as 'this) +@return(nullable) +/** +Returns `Some(value)` for the first element in the array that satisifies the given predicate function, or `None` if no element satisifies the predicate. The predicate function takes an array element and an index as its parameters. See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. + +## Examples + +```rescript +// find first positive item at an odd index +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array.findi(positiveOddElement, [66, -33, 55, 88, 22]) == Some(88) +Js.Array.findi(positiveOddElement, [66, -33, 55, -88, 22]) == None +``` +*/ +external findi: (('a, int) => bool) => option<'a> = "find" + +@send.pipe(: t<'a> as 'this) +/** +Returns the index of the first element in the array that satisifies the given predicate function, or -1 if no element satisifies the predicate. See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. + +## Examples + +```rescript +Js.Array.findIndex(x => x < 0, [33, 22, -55, 77, -44]) == 2 +Js.Array.findIndex(x => x < 0, [33, 22, 55, 77, 44]) == -1 +``` +*/ +external findIndex: (('a => bool)) => int = "findIndex" + +@send.pipe(: t<'a> as 'this) +/** +Returns `Some(value)` for the first element in the array that satisifies the given predicate function, or `None` if no element satisifies the predicate. The predicate function takes an array element and an index as its parameters. See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. + +## Examples + +```rescript +// find index of first positive item at an odd index +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array.findIndexi(positiveOddElement, [66, -33, 55, 88, 22]) == 3 +Js.Array.findIndexi(positiveOddElement, [66, -33, 55, -88, 22]) == -1 +``` +*/ +external findIndexi: (('a, int) => bool) => int = "findIndex" + +@send.pipe(: t<'a> as 'this) +/** +The `forEach()` function applies the function given as the first argument to each element in the array. The function you provide returns `unit`, and the `forEach()` function also returns `unit`. You use `forEach()` when you need to process each element in the array but not return any new array or value; for example, to print the items in an array. See [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN. + +## Examples + +```rescript +// display all elements in an array +Js.Array.forEach(x => Js.log(x), ["a", "b", "c"]) == () +``` +*/ +external forEach: (('a => unit)) => unit = "forEach" + +@send.pipe(: t<'a> as 'this) +/** +The `forEachi()` function applies the function given as the first argument to each element in the array. The function you provide takes an item in the array and its index number, and returns `unit`. The `forEachi()` function also returns `unit`. You use `forEachi()` when you need to process each element in the array but not return any new array or value; for example, to print the items in an array. See [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN. + +## Examples + +```rescript +// display all elements in an array as a numbered list +Js.Array.forEachi((item, index) => Js.log2(index + 1, item), ["a", "b", "c"]) == () +``` +*/ +external forEachi: (('a, int) => unit) => unit = "forEach" + +/* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@send.pipe: 'a t as 'this] (* ES2015 *) +*/ + +@send.pipe(: t<'a> as 'this) +/** +Applies the function (given as the first argument) to each item in the array, +returning a new array. The result array does not have to have elements of the +same type as the input array. See +[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) +on MDN. + +## Examples + +```rescript +Js.Array.map(x => x * x, [12, 4, 8]) == [144, 16, 64] +Js.Array.map(Js.String.length, ["animal", "vegetable", "mineral"]) == [6, 9, 7] +``` +*/ +external map: (('a => 'b)) => t<'b> = "map" + +@send.pipe(: t<'a> as 'this) +/** +Applies the function (given as the first argument) to each item in the array, +returning a new array. The function acceps two arguments: an item from the +array and its index number. The result array does not have to have elements +of the same type as the input array. See +[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) +on MDN. + +## Examples + +```rescript +// multiply each item in array by its position +let product = (item, index) => item * index +Js.Array.mapi(product, [10, 11, 12]) == [0, 11, 24] +``` +*/ +external mapi: (('a, int) => 'b) => t<'b> = "map" + +@send.pipe(: t<'a> as 'this) +/** +The `reduce()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has two +parameters: an accumulated value and an element of the array. + +`reduce()` first calls the reducer function with the beginning value and the +first element in the array. The result becomes the new accumulator value, which +is passed in to the reducer function along with the second element in the +array. `reduce()` proceeds through the array, passing in the result of each +stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduce()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +## Examples + +```rescript +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array.reduce(sumOfSquares, 0, [10, 2, 4]) == 120 +Js.Array.reduce(\"*", 1, [10, 2, 4]) == 80 +Js.Array.reduce( + (acc, item) => acc + Js.String.length(item), + 0, + ["animal", "vegetable", "mineral"], +) == 22 // 6 + 9 + 7 +Js.Array.reduce((acc, item) => item /. acc, 1.0, [2.0, 4.0]) == 2.0 // 4.0 / (2.0 / 1.0) +``` +*/ +external reduce: (('b, 'a) => 'b, 'b) => 'b = "reduce" + +@send.pipe(: t<'a> as 'this) +/** +The `reducei()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. + +`reducei()` first calls the reducer function with the beginning value, the +first element in the array, and zero (its index). The result becomes the new +accumulator value, which is passed to the reducer function along with the +second element in the array and one (its index). `reducei()` proceeds from left +to right through the array, passing in the result of each stage as the +accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reducei()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +## Examples + +```rescript +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array.reducei(sumOfEvens, 0, [2, 5, 1, 4, 3]) == 6 +``` +*/ +external reducei: (('b, 'a, int) => 'b, 'b) => 'b = "reduce" + +@send.pipe(: t<'a> as 'this) +/** +The `reduceRight()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has two +parameters: an accumulated value and an element of the array. + +`reduceRight()` first calls the reducer function with the beginning value and +the last element in the array. The result becomes the new accumulator value, +which is passed in to the reducer function along with the next-to-last element +in the array. `reduceRight()` proceeds from right to left through the array, +passing in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRight()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reduce()` and `reduceRight()` give the same result. However, see the last example here and compare it to the example from `reduce()`, where order makes a difference. + +## Examples + +```rescript +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array.reduceRight(sumOfSquares, 0, [10, 2, 4]) == 120 +Js.Array.reduceRight((acc, item) => item /. acc, 1.0, [2.0, 4.0]) == 0.5 // 2.0 / (4.0 / 1.0) +``` +*/ +external reduceRight: (('b, 'a) => 'b, 'b) => 'b = "reduceRight" + +@send.pipe(: t<'a> as 'this) +/** +The `reduceRighti()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. `reduceRighti()` first calls the reducer function with the +beginning value, the last element in the array, and its index (length of array +minus one). The result becomes the new accumulator value, which is passed in to +the reducer function along with the second element in the array and one (its +index). `reduceRighti()` proceeds from right to left through the array, passing +in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRighti()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reducei()` and `reduceRighti()` give the same result. +However, there are cases where the order in which items are processed makes a +difference. + +## Examples + +```rescript +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array.reduceRighti(sumOfEvens, 0, [2, 5, 1, 4, 3]) == 6 +``` +*/ +external reduceRighti: (('b, 'a, int) => 'b, 'b) => 'b = "reduceRight" + +@send.pipe(: t<'a> as 'this) +/** +Returns `true` if the predicate function given as the first argument to +`some()` returns `true` for any element in the array; `false` otherwise. + +## Examples + +```rescript +let isEven = x => mod(x, 2) == 0 + +Js.Array.some(isEven, [3, 7, 5, 2, 9]) == true +Js.Array.some(isEven, [3, 7, 5, 1, 9]) == false +``` +*/ +external some: (('a => bool)) => bool = "some" + +@send.pipe(: t<'a> as 'this) +/** +Returns `true` if the predicate function given as the first argument to +`somei()` returns `true` for any element in the array; `false` otherwise. The +predicate function has two arguments: an item from the array and the index +value + +## Examples + +```rescript +// Does any string in the array +// have the same length as its index? + +let sameLength = (str, index) => Js.String.length(str) == index + +// "ef" has length 2 and is it at index 2 +Js.Array.somei(sameLength, ["ab", "cd", "ef", "gh"]) == true +// no item has the same length as its index +Js.Array.somei(sameLength, ["a", "bc", "def", "gh"]) == false +``` +*/ +external somei: (('a, int) => bool) => bool = "some" + +/* commented out until bs has a plan for iterators + external values : 'a array_iter = "" [@@send.pipe: 'a t as 'this] (* ES2015 *) +*/ +/** +Returns the value at the given position in the array if the position is in +bounds; returns the JavaScript value `undefined` otherwise. + +## Examples + +```rescript +let arr = [100, 101, 102, 103] +Js.Array.unsafe_get(arr, 3) == 103 +Js.Array.unsafe_get(arr, 4) // returns undefined +``` +*/ +external unsafe_get: (array<'a>, int) => 'a = "%array_unsafe_get" + +/** +Sets the value at the given position in the array if the position is in bounds. +If the index is out of bounds, well, “here there be dragons.“ *This function + modifies the original array.* + +## Examples + +```rescript +let arr = [100, 101, 102, 103] +Js.Array.unsafe_set(arr, 3, 99) +// result is [100, 101, 102, 99] + +Js.Array.unsafe_set(arr, 4, 88) +// result is [100, 101, 102, 99, 88] + +Js.Array.unsafe_set(arr, 6, 77) +// result is [100, 101, 102, 99, 88, <1 empty item>, 77] + +Js.Array.unsafe_set(arr, -1, 66) +// you don't want to know. +``` +*/ +external unsafe_set: (array<'a>, int, 'a) => unit = "%array_unsafe_set" diff --git a/js/src/js_array2.res b/js/src/js_array2.res new file mode 100644 index 0000000..2b40210 --- /dev/null +++ b/js/src/js_array2.res @@ -0,0 +1,1185 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provides bindings to JavaScript’s `Array` functions. These bindings are optimized for pipe-first (`->`), where the array to be processed is the first parameter in the function. + +Here is an example to find the sum of squares of all even numbers in an array. +Without pipe first, we must call the functions in reverse order: + +## Examples + +```rescript +let isEven = x => mod(x, 2) == 0 +let square = x => x * x +let result = { + open Js.Array2 + reduce(map(filter([5, 2, 3, 4, 1], isEven), square), "+", 0) +} +``` + +With pipe first, we call the functions in the “natural” order: + +```rescript +let isEven = x => mod(x, 2) == 0 +let square = x => x * x +let result = { + open Js.Array2 + [5, 2, 3, 4, 1]->filter(isEven)->map(square)->reduce("+", 0) +} +``` +*/ + +/** +The type used to describe a JavaScript array. +*/ +type t<'a> = array<'a> + +/** +A type used to describe JavaScript objects that are like an array or are iterable. +*/ +type array_like<'a> + +/* commented out until bs has a plan for iterators + type 'a array_iter = 'a array_like +*/ + +@val +/** +Creates a shallow copy of an array from an array-like object. See +[`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) +on MDN. + +## Examples + +```rescript +let strArr = Js.String.castToArrayLike("abcd") +Js.Array2.from(strArr) == ["a", "b", "c", "d"] +``` +*/ +external from: array_like<'a> => array<'a> = "Array.from" + +/* ES2015 */ + +@val +/** +Creates a new array by applying a function (the second argument) to each item +in the `array_like` first argument. See +[`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) +on MDN. + +## Examples + +```rescript +let strArr = Js.String.castToArrayLike("abcd") +let code = s => Js.String.charCodeAt(0, s) +Js.Array2.fromMap(strArr, code) == [97.0, 98.0, 99.0, 100.0] +``` +*/ +external fromMap: (array_like<'a>, @uncurry ('a => 'b)) => array<'b> = "Array.from" + +/* ES2015 */ + +@val +/** +Returns `true` if its argument is an array; `false` otherwise. This is a runtime check, which is why the second example returns `true`---a list is internally represented as a nested JavaScript array. + +## Examples + +```rescript +Js.Array2.isArray([5, 2, 3, 1, 4]) == true +Js.Array2.isArray(list{5, 2, 3, 1, 4}) == true +Js.Array2.isArray("abcd") == false +``` +*/ +external isArray: 'a => bool = "Array.isArray" + +@get +/** +Returns the number of elements in the array. See +[`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) +on MDN. +*/ +external length: array<'a> => int = "length" + +/* Mutator functions */ + +@send +/** +Copies from the first element in the given array to the designated `~to_` +position, returning the resulting array. *This function modifies the original +array.* See +[`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.copyWithin(arr, ~to_=2) == [100, 101, 100, 101, 102] +arr == [100, 101, 100, 101, 102] +``` +*/ +external copyWithin: (t<'a>, ~to_: int) => t<'a> = "copyWithin" + +/* ES2015 */ + +@send +/** +Copies starting at element `~from` in the given array to the designated `~to_` +position, returning the resulting array. *This function modifies the original +array.* See +[`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.copyWithinFrom(arr, ~from=2, ~to_=0) == [102, 103, 104, 103, 104] +arr == [102, 103, 104, 103, 104] +``` +*/ +external copyWithinFrom: (t<'a>, ~to_: int, ~from: int) => t<'a> = "copyWithin" + +/* ES2015 */ + +@send +/** +Copies starting at element `~start` in the given array up to but not including +`~end_` to the designated `~to_` position, returning the resulting array. *This +function modifies the original array.* See +[`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104, 105] +Js.Array2.copyWithinFromRange(arr, ~start=2, ~end_=5, ~to_=1) == [100, 102, 103, 104, 104, 105] +arr == [100, 102, 103, 104, 104, 105] +``` +*/ +external copyWithinFromRange: (t<'a>, ~to_: int, ~start: int, ~end_: int) => t<'a> = "copyWithin" + +/* ES2015 */ + +@send +/** +Sets all elements of the given array (the first arumgent) to the designated +value (the secon argument), returning the resulting array. *This function + modifies the original array.* + +See +[`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.fillInPlace(arr, 99) == [99, 99, 99, 99, 99] +arr == [99, 99, 99, 99, 99] +``` +*/ +external fillInPlace: (t<'a>, 'a) => t<'a> = "fill" + +/* ES2015 */ + +@send +/** +Sets all elements of the given array (the first arumgent) from position `~from` +to the end to the designated value (the second argument), returning the +resulting array. *This function modifies the original array.* See +[`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.fillFromInPlace(arr, 99, ~from=2) == [100, 101, 99, 99, 99] +arr == [100, 101, 99, 99, 99] +``` +*/ +external fillFromInPlace: (t<'a>, 'a, ~from: int) => t<'a> = "fill" + +/* ES2015 */ + +@send +/** +Sets the elements of the given array (the first arumgent) from position +`~start` up to but not including position `~end_` to the designated value (the +second argument), returning the resulting array. *This function modifies the +original array.* See +[`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.fillRangeInPlace(arr, 99, ~start=1, ~end_=4) == [100, 99, 99, 99, 104] +arr == [100, 99, 99, 99, 104] +``` +*/ +external fillRangeInPlace: (t<'a>, 'a, ~start: int, ~end_: int) => t<'a> = "fill" + +/* ES2015 */ + +@send +@return(undefined_to_opt) +/** +If the array is not empty, removes the last element and returns it as +`Some(value)`; returns `None` if the array is empty. *This function modifies +the original array.* See +[`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.pop(arr) == Some(104) +arr == [100, 101, 102, 103] + +let empty: array = [] +Js.Array2.pop(empty) == None +``` +*/ +external pop: t<'a> => option<'a> = "pop" + +@send +/** +Appends the given value to the array, returning the number of elements in the +updated array. *This function modifies the original array.* See +[`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) +on MDN. + +## Examples + +```rescript +let arr = ["ant", "bee", "cat"] +Js.Array2.push(arr, "dog") == 4 +arr == ["ant", "bee", "cat", "dog"] +``` +*/ +external push: (t<'a>, 'a) => int = "push" + +@send +@variadic +/** +Appends the values from one array (the second argument) to another (the first +argument), returning the number of elements in the updated array. *This +function modifies the original array.* See +[`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) +on MDN. + +## Examples + +```rescript +let arr = ["ant", "bee", "cat"] +Js.Array2.pushMany(arr, ["dog", "elk"]) == 5 +arr == ["ant", "bee", "cat", "dog", "elk"] +``` +*/ +external pushMany: (t<'a>, array<'a>) => int = "push" + +@send +/** +Returns an array with the elements of the input array in reverse order. *This +function modifies the original array.* See +[`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) +on MDN. + +## Examples + +```rescript +let arr = ["ant", "bee", "cat"] +Js.Array2.reverseInPlace(arr) == ["cat", "bee", "ant"] +arr == ["cat", "bee", "ant"] +``` +*/ +external reverseInPlace: t<'a> => t<'a> = "reverse" + +@send +@return(undefined_to_opt) +/** +If the array is not empty, removes the first element and returns it as +`Some(value)`; returns `None` if the array is empty. *This function modifies +the original array.* See +[`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +Js.Array2.shift(arr) == Some(100) +arr == [101, 102, 103, 104] + +let empty: array = [] +Js.Array2.shift(empty) == None +``` +*/ +external shift: t<'a> => option<'a> = "shift" + +@send +/** +Sorts the given array in place and returns the sorted array. JavaScript sorts +the array by converting the arguments to UTF-16 strings and sorting them. See +the second example with sorting numbers, which does not do a numeric sort. +*This function modifies the original array.* See +[`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) +on MDN. + +## Examples + +```rescript +let words = ["bee", "dog", "ant", "cat"] +Js.Array2.sortInPlace(words) == ["ant", "bee", "cat", "dog"] +words == ["ant", "bee", "cat", "dog"] + +let numbers = [3, 30, 10, 1, 20, 2] +Js.Array2.sortInPlace(numbers) == [1, 10, 2, 20, 3, 30] +numbers == [1, 10, 2, 20, 3, 30] +``` +*/ +external sortInPlace: t<'a> => t<'a> = "sort" + +@send +/** +Sorts the given array in place and returns the sorted array. *This function + modifies the original array.* + +The first argument to `sortInPlaceWith()` is a function that compares two items +from the array and returns: + +* an integer less than zero if the first item is less than the second item * +zero if the items are equal * an integer greater than zero if the first item is +greater than the second item + +See +[`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) +on MDN. + +## Examples + +```rescript +// sort by word length +let words = ["horse", "aardvark", "dog", "camel"] +let byLength = (s1, s2) => Js.String.length(s1) - Js.String.length(s2) + +Js.Array2.sortInPlaceWith(words, byLength) == ["dog", "horse", "camel", "aardvark"] + +// sort in reverse numeric order +let numbers = [3, 30, 10, 1, 20, 2] +let reverseNumeric = (n1, n2) => n2 - n1 +Js.Array2.sortInPlaceWith(numbers, reverseNumeric) == [30, 20, 10, 3, 2, 1] +``` +*/ +external sortInPlaceWith: (t<'a>, @uncurry ('a, 'a) => int) => t<'a> = "sort" + +@send +@variadic +/** +Starting at position `~pos`, remove `~remove` elements and then add the +elements from the `~add` array. Returns an array consisting of the removed +items. *This function modifies the original array.* See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +## Examples + +```rescript +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array2.spliceInPlace(arr, ~pos=2, ~remove=2, ~add=["x", "y", "z"]) == ["c", "d"] +arr == ["a", "b", "x", "y", "z", "e", "f"] + +let arr2 = ["a", "b", "c", "d"] +Js.Array2.spliceInPlace(arr2, ~pos=3, ~remove=0, ~add=["x", "y"]) == [] +arr2 == ["a", "b", "c", "x", "y", "d"] + +let arr3 = ["a", "b", "c", "d", "e", "f"] +Js.Array2.spliceInPlace(arr3, ~pos=9, ~remove=2, ~add=["x", "y", "z"]) == [] +arr3 == ["a", "b", "c", "d", "e", "f", "x", "y", "z"] +``` +*/ +external spliceInPlace: (t<'a>, ~pos: int, ~remove: int, ~add: array<'a>) => t<'a> = "splice" + +@send +/** +Removes elements from the given array starting at position `~pos` to the end of +the array, returning the removed elements. *This function modifies the original +array.* See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +## Examples + +```rescript +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array2.removeFromInPlace(arr, ~pos=4) == ["e", "f"] +arr == ["a", "b", "c", "d"] +``` +*/ +external removeFromInPlace: (t<'a>, ~pos: int) => t<'a> = "splice" + +@send +/** +Removes `~count` elements from the given array starting at position `~pos`, +returning the removed elements. *This function modifies the original array.* +See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +## Examples + +```rescript +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array2.removeCountInPlace(arr, ~pos=2, ~count=3) == ["c", "d", "e"] +arr == ["a", "b", "f"] +``` +*/ +external removeCountInPlace: (t<'a>, ~pos: int, ~count: int) => t<'a> = "splice" + +@send +/** +Adds the given element to the array, returning the new number of elements in +the array. *This function modifies the original array.* See +[`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) +on MDN. + +## Examples + +```rescript +let arr = ["b", "c", "d"] +Js.Array2.unshift(arr, "a") == 4 +arr == ["a", "b", "c", "d"] +``` +*/ +external unshift: (t<'a>, 'a) => int = "unshift" + +@send +@variadic +/** +Adds the elements in the second array argument at the beginning of the first +array argument, returning the new number of elements in the array. *This +function modifies the original array.* See +[`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) +on MDN. + +## Examples + +```rescript +let arr = ["d", "e"] +Js.Array2.unshiftMany(arr, ["a", "b", "c"]) == 5 +arr == ["a", "b", "c", "d", "e"] +``` +*/ +external unshiftMany: (t<'a>, array<'a>) => int = "unshift" + +/* Accessor functions + */ +@send @deprecated("`append` is not type-safe. Use `concat` instead.") +external append: (t<'a>, 'a) => t<'a> = "concat" + +@send +/** +Concatenates the second array argument to the first array argument, returning a +new array. The original arrays are not modified. See +[`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) +on MDN. + +## Examples + +```rescript +Js.Array2.concat(["a", "b"], ["c", "d", "e"]) == ["a", "b", "c", "d", "e"] +``` +*/ +external concat: (t<'a>, t<'a>) => t<'a> = "concat" + +@send +@variadic +/** +The second argument to `concatMany()` is an array of arrays; these are added at +the end of the first argument, returning a new array. See +[`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) +on MDN. + +## Examples + +```rescript +Js.Array2.concatMany(["a", "b", "c"], [["d", "e"], ["f", "g", "h"]]) == [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + ] +``` +*/ +external concatMany: (t<'a>, array>) => t<'a> = "concat" + +@send +/** +Returns true if the given value is in the array, `false` otherwise. See +[`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) +on MDN. + +## Examples + +```rescript +Js.Array2.includes(["a", "b", "c"], "b") == true +Js.Array2.includes(["a", "b", "c"], "x") == false +``` +*/ +external includes: (t<'a>, 'a) => bool = "includes" + +@send +/** +Returns the index of the first element in the array that has the given value. +If the value is not in the array, returns -1. See +[`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) +on MDN. + +## Examples + +```rescript +Js.Array2.indexOf([100, 101, 102, 103], 102) == 2 +Js.Array2.indexOf([100, 101, 102, 103], 999) == -1 +``` +*/ +external indexOf: (t<'a>, 'a) => int = "indexOf" + +@send +/** +Returns the index of the first element in the array with the given value. The +search starts at position `~from`. See +[`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) +on MDN. + +## Examples + +```rescript +Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "a", ~from=2) == 2 +Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "a", ~from=3) == 4 +Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "b", ~from=2) == -1 +``` +*/ +external indexOfFrom: (t<'a>, 'a, ~from: int) => int = "indexOf" + +@send +/** +This function converts each element of the array to a string (via JavaScript) +and concatenates them, separated by the string given in the first argument, +into a single string. See +[`Array.join`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) +on MDN. + +## Examples + +```rescript +Js.Array2.joinWith(["ant", "bee", "cat"], "--") == "ant--bee--cat" +Js.Array2.joinWith(["door", "bell"], "") == "doorbell" +Js.Array2.joinWith([2020, 9, 4], "/") == "2020/9/4" +Js.Array2.joinWith([2.5, 3.6, 3e-2], ";") == "2.5;3.6;0.03" +``` +*/ +external joinWith: (t<'a>, string) => string = "join" + +@send +/** +Returns the index of the last element in the array that has the given value. If +the value is not in the array, returns -1. See +[`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.Array2.lastIndexOf(["a", "b", "a", "c"], "a") == 2 +Js.Array2.lastIndexOf(["a", "b", "a", "c"], "x") == -1 +``` +*/ +external lastIndexOf: (t<'a>, 'a) => int = "lastIndexOf" + +@send +/** +Returns the index of the last element in the array that has the given value, +searching from position `~from` down to the start of the array. If the value is +not in the array, returns -1. See +[`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.Array2.lastIndexOfFrom(["a", "b", "a", "c", "a", "d"], "a", ~from=3) == 2 +Js.Array2.lastIndexOfFrom(["a", "b", "a", "c", "a", "d"], "c", ~from=2) == -1 +``` +*/ +external lastIndexOfFrom: (t<'a>, 'a, ~from: int) => int = "lastIndexOf" + +@send +/** +Returns a shallow copy of the given array from the `~start` index up to but not +including the `~end_` position. Negative numbers indicate an offset from the +end of the array. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104, 105, 106] +Js.Array2.slice(arr, ~start=2, ~end_=5) == [102, 103, 104] +Js.Array2.slice(arr, ~start=-3, ~end_=-1) == [104, 105] +Js.Array2.slice(arr, ~start=9, ~end_=10) == [] +``` +*/ +external slice: (t<'a>, ~start: int, ~end_: int) => t<'a> = "slice" + +@send +/** +Returns a copy of the entire array. Same as `Js.Array2.Slice(arr, ~start=0, +~end_=Js.Array2.length(arr))`. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. +*/ +external copy: t<'a> => t<'a> = "slice" + +@send +/** +Returns a shallow copy of the given array from the given index to the end. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. +*/ +external sliceFrom: (t<'a>, int) => t<'a> = "slice" + +@send +/** +Converts the array to a string. Each element is converted to a string using +JavaScript. Unlike the JavaScript `Array.toString()`, all elements in a +ReasonML array must have the same type. See +[`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) +on MDN. + +## Examples + +```rescript +Js.Array2.toString([3.5, 4.6, 7.8]) == "3.5,4.6,7.8" +Js.Array2.toString(["a", "b", "c"]) == "a,b,c" +``` +*/ +external toString: t<'a> => string = "toString" + +@send +/** +Converts the array to a string using the conventions of the current locale. +Each element is converted to a string using JavaScript. Unlike the JavaScript +`Array.toLocaleString()`, all elements in a ReasonML array must have the same +type. See +[`Array.toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString) +on MDN. + +## Examples + +```rescript +Js.Array2.toLocaleString([Js.Date.make()]) +// returns "3/19/2020, 10:52:11 AM" for locale en_US.utf8 +// returns "2020-3-19 10:52:11" for locale de_DE.utf8 +``` +*/ +external toLocaleString: t<'a> => string = "toLocaleString" + +/* Iteration functions + */ +/* commented out until bs has a plan for iterators + external entries : 'a t -> (int * 'a) array_iter = "" [@@send] (* ES2015 *) +*/ + +@send +/** +The first argument to `every()` is an array. The second argument is a predicate +function that returns a boolean. The `every()` function returns `true` if the +predicate function is true for all items in the given array. If given an empty +array, returns `true`. See +[`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) +on MDN. + +## Examples + +```rescript +let isEven = x => mod(x, 2) == 0 +Js.Array2.every([6, 22, 8, 4], isEven) == true +Js.Array2.every([6, 22, 7, 4], isEven) == false +``` +*/ +external every: (t<'a>, @uncurry ('a => bool)) => bool = "every" + +@send +/** +The first argument to `everyi()` is an array. The second argument is a +predicate function with two arguments: an array element and that element’s +index; it returns a boolean. The `everyi()` function returns `true` if the +predicate function is true for all items in the given array. If given an empty +array, returns `true`. See +[`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) +on MDN. + +## Examples + +```rescript +// determine if all even-index items are positive +let evenIndexPositive = (item, index) => mod(index, 2) == 0 ? item > 0 : true + +Js.Array2.everyi([6, -3, 5, 8], evenIndexPositive) == true +Js.Array2.everyi([6, 3, -5, 8], evenIndexPositive) == false +``` +*/ +external everyi: (t<'a>, @uncurry ('a, int) => bool) => bool = "every" + +@send +/** +Applies the given predicate function (the second argument) to each element in +the array; the result is an array of those elements for which the predicate +function returned `true`. See +[`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) +on MDN. + +## Examples + +```rescript +let nonEmpty = s => s != "" +Js.Array2.filter(["abc", "", "", "def", "ghi"], nonEmpty) == ["abc", "def", "ghi"] +``` +*/ +external filter: (t<'a>, @uncurry ('a => bool)) => t<'a> = "filter" + +@send +/** +Each element of the given array are passed to the predicate function. The +return value is an array of all those elements for which the predicate function +returned `true`. + +See +[`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) +on MDN. + +## Examples + +```rescript +// keep only positive elements at odd indices +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array2.filteri([6, 3, 5, 8, 7, -4, 1], positiveOddElement) == [3, 8] +``` +*/ +external filteri: (t<'a>, @uncurry ('a, int) => bool) => t<'a> = "filter" + +@send +@return({undefined_to_opt: undefined_to_opt}) +/** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +## Examples + +```rescript +// find first negative element +Js.Array2.find([33, 22, -55, 77, -44], x => x < 0) == Some(-55) +Js.Array2.find([33, 22, 55, 77, 44], x => x < 0) == None +``` +*/ +external find: (t<'a>, @uncurry ('a => bool)) => option<'a> = "find" + +/* ES2015 */ + +@send +@return({undefined_to_opt: undefined_to_opt}) +/** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. The +predicate function takes an array element and an index as its parameters. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +## Examples + +```rescript +// find first positive item at an odd index +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array2.findi([66, -33, 55, 88, 22], positiveOddElement) == Some(88) +Js.Array2.findi([66, -33, 55, -88, 22], positiveOddElement) == None +``` +*/ +external findi: (t<'a>, @uncurry ('a, int) => bool) => option<'a> = "find" + +/* ES2015 */ + +@send +/** +Returns the index of the first element in the array that satisifies the given +predicate function, or -1 if no element satisifies the predicate. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +## Examples + +```rescript +Js.Array2.findIndex([33, 22, -55, 77, -44], x => x < 0) == 2 +Js.Array2.findIndex([33, 22, 55, 77, 44], x => x < 0) == -1 +``` +*/ +external findIndex: (t<'a>, @uncurry ('a => bool)) => int = "findIndex" + +/* ES2015 */ + +@send +/** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. The +predicate function takes an array element and an index as its parameters. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +## Examples + +```rescript +// find index of first positive item at an odd index +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array2.findIndexi([66, -33, 55, 88, 22], positiveOddElement) == 3 +Js.Array2.findIndexi([66, -33, 55, -88, 22], positiveOddElement) == -1 +``` +*/ +external findIndexi: (t<'a>, @uncurry ('a, int) => bool) => int = "findIndex" + +/* ES2015 */ + +@send +/** +The `forEach()` function applies the function given as the second argument to +each element in the array. The function you provide returns `unit`, and the +`forEach()` function also returns `unit`. You use `forEach()` when you need to +process each element in the array but not return any new array or value; for +example, to print the items in an array. See +[`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) +on MDN. + +## Examples + +```rescript +// display all elements in an array +Js.Array2.forEach(["a", "b", "c"], x => Js.log(x)) == () +``` +*/ +external forEach: (t<'a>, @uncurry ('a => unit)) => unit = "forEach" + +@send +/** +The `forEachi()` function applies the function given as the second argument to +each element in the array. The function you provide takes an item in the array +and its index number, and returns `unit`. The `forEachi()` function also +returns `unit`. You use `forEachi()` when you need to process each element in +the array but not return any new array or value; for example, to print the +items in an array. See +[`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) +on MDN. + +## Examples + +```rescript +// display all elements in an array as a numbered list +Js.Array2.forEachi(["a", "b", "c"], (item, index) => Js.log2(index + 1, item)) == () +``` +*/ +external forEachi: (t<'a>, @uncurry ('a, int) => unit) => unit = "forEach" + +/* commented out until bs has a plan for iterators + external keys : 'a t -> int array_iter = "" [@@send] (* ES2015 *) +*/ + +@send +/** +Applies the function (the second argument) to each item in the array, returning +a new array. The result array does not have to have elements of the same type +as the input array. See +[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) +on MDN. + +## Examples + +```rescript +Js.Array2.map([12, 4, 8], x => x * x) == [144, 16, 64] +Js.Array2.map(["animal", "vegetable", "mineral"], Js.String.length) == [6, 9, 7] +``` +*/ +external map: (t<'a>, @uncurry ('a => 'b)) => t<'b> = "map" + +@send +/** +Applies the function (the second argument) to each item in the array, returning +a new array. The function acceps two arguments: an item from the array and its +index number. The result array does not have to have elements of the same type +as the input array. See +[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) +on MDN. + +## Examples + +```rescript +// multiply each item in array by its position +let product = (item, index) => item * index +Js.Array2.mapi([10, 11, 12], product) == [0, 11, 24] +``` +*/ +external mapi: (t<'a>, @uncurry ('a, int) => 'b) => t<'b> = "map" + +@send +/** +The `reduce()` function takes three parameters: an array, a *reducer function*, +and a beginning accumulator value. The reducer function has two parameters: an +accumulated value and an element of the array. + +`reduce()` first calls the reducer function with the beginning value and the +first element in the array. The result becomes the new accumulator value, which +is passed in to the reducer function along with the second element in the +array. `reduce()` proceeds through the array, passing in the result of each +stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduce()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +## Examples + +```rescript +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array2.reduce([10, 2, 4], sumOfSquares, 0) == 120 +Js.Array2.reduce([10, 2, 4], "*", 1) == 80 +Js.Array2.reduce( + ["animal", "vegetable", "mineral"], + (acc, item) => acc + Js.String.length(item), + 0, +) == 22 // 6 + 9 + 7 +Js.Array2.reduce([2.0, 4.0], (acc, item) => item /. acc, 1.0) == 2.0 // 4.0 / (2.0 / 1.0) +``` +*/ +external reduce: (t<'a>, @uncurry ('b, 'a) => 'b, 'b) => 'b = "reduce" + +@send +/** +The `reducei()` function takes three parameters: an array, a *reducer +function*, and a beginning accumulator value. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. + +`reducei()` first calls the reducer function with the beginning value, the +first element in the array, and zero (its index). The result becomes the new +accumulator value, which is passed to the reducer function along with the +second element in the array and one (its index). `reducei()` proceeds from left +to right through the array, passing in the result of each stage as the +accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reducei()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +## Examples + +```rescript +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array2.reducei([2, 5, 1, 4, 3], sumOfEvens, 0) == 6 +``` +*/ +external reducei: (t<'a>, @uncurry ('b, 'a, int) => 'b, 'b) => 'b = "reduce" + +@send +/** +The `reduceRight()` function takes three parameters: an array, a *reducer +function*, and a beginning accumulator value. The reducer function has two +parameters: an accumulated value and an element of the array. + +`reduceRight()` first calls the reducer function with the beginning value and +the last element in the array. The result becomes the new accumulator value, +which is passed in to the reducer function along with the next-to-last element +in the array. `reduceRight()` proceeds from right to left through the array, +passing in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRight()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reduce()` and `reduceRight()` give the same result. +However, see the last example here and compare it to the example from +`reduce()`, where order makes a difference. + +## Examples + +```rescript +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array2.reduceRight([10, 2, 4], sumOfSquares, 0) == 120 +Js.Array2.reduceRight([2.0, 4.0], (acc, item) => item /. acc, 1.0) == 0.5 // 2.0 / (4.0 / 1.0) +``` +*/ +external reduceRight: (t<'a>, @uncurry ('b, 'a) => 'b, 'b) => 'b = "reduceRight" + +@send +/** +The `reduceRighti()` function takes three parameters: an array, a *reducer +function*, and a beginning accumulator value. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. `reduceRighti()` first calls the reducer function with the +beginning value, the last element in the array, and its index (length of array +minus one). The result becomes the new accumulator value, which is passed in to +the reducer function along with the second element in the array and one (its +index). `reduceRighti()` proceeds from right to left through the array, passing +in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRighti()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reducei()` and `reduceRighti()` give the same result. +However, there are cases where the order in which items are processed makes a +difference. + +## Examples + +```rescript +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array2.reduceRighti([2, 5, 1, 4, 3], sumOfEvens, 0) == 6 +``` +*/ +external reduceRighti: (t<'a>, @uncurry ('b, 'a, int) => 'b, 'b) => 'b = "reduceRight" + +@send +/** +Returns `true` if the predicate function given as the second argument to +`some()` returns `true` for any element in the array; `false` otherwise. + +## Examples + +```rescript +let isEven = x => mod(x, 2) == 0 + +Js.Array2.some([3, 7, 5, 2, 9], isEven) == true +Js.Array2.some([3, 7, 5, 1, 9], isEven) == false +``` +*/ +external some: (t<'a>, @uncurry ('a => bool)) => bool = "some" + +@send +/** +Returns `true` if the predicate function given as the second argument to +`somei()` returns `true` for any element in the array; `false` otherwise. The +predicate function has two arguments: an item from the array and the index +value + +## Examples + +```rescript +// Does any string in the array +// have the same length as its index? + +let sameLength = (str, index) => Js.String.length(str) == index + +// "ef" has length 2 and is it at index 2 +Js.Array2.somei(["ab", "cd", "ef", "gh"], sameLength) == true +// no item has the same length as its index +Js.Array2.somei(["a", "bc", "def", "gh"], sameLength) == false +``` +*/ +external somei: (t<'a>, @uncurry ('a, int) => bool) => bool = "some" + +/* commented out until bs has a plan for iterators + external values : 'a t -> 'a array_iter = "" [@@send] (* ES2015 *) +*/ + +/** +Returns the value at the given position in the array if the position is in +bounds; returns the JavaScript value `undefined` otherwise. + +## Examples + +```rescript +let arr = [100, 101, 102, 103] +Js.Array2.unsafe_get(arr, 3) == 103 +Js.Array2.unsafe_get(arr, 4) // returns undefined +``` +*/ +external unsafe_get: (array<'a>, int) => 'a = "%array_unsafe_get" + +/** +Sets the value at the given position in the array if the position is in bounds. +If the index is out of bounds, well, “here there be dragons.“ + +*This function modifies the original array.* + +## Examples + +```rescript +let arr = [100, 101, 102, 103] +Js.Array2.unsafe_set(arr, 3, 99) +// result is [100, 101, 102, 99]; + +Js.Array2.unsafe_set(arr, 4, 88) +// result is [100, 101, 102, 99, 88] + +Js.Array2.unsafe_set(arr, 6, 77) +// result is [100, 101, 102, 99, 88, <1 empty item>, 77] + +Js.Array2.unsafe_set(arr, -1, 66) +// you don't want to know. +``` +*/ +external unsafe_set: (array<'a>, int, 'a) => unit = "%array_unsafe_set" diff --git a/js/src/js_bigint.res b/js/src/js_bigint.res new file mode 100644 index 0000000..4288f1a --- /dev/null +++ b/js/src/js_bigint.res @@ -0,0 +1,81 @@ +/*** JavaScript BigInt API */ + +@val +/** +Parses the given `string` into a `bigint` using JavaScript semantics. Return the +number as a `bigint` if successfully parsed. Uncaught syntax exception otherwise. + +## Examples + +```rescript +/* returns 123n */ +Js.BigInt.fromStringExn("123") + +/* returns 0n */ +Js.BigInt.fromStringExn("") + +/* returns 17n */ +Js.BigInt.fromStringExn("0x11") + +/* returns 3n */ +Js.BigInt.fromStringExn("0b11") + +/* returns 9n */ +Js.BigInt.fromStringExn("0o11") + +/* catch exception */ +try { + Js.BigInt.fromStringExn("a") +} catch { +| _ => ... +} +``` +*/ +external fromStringExn: string => bigint = "BigInt" + +// Operations + +external \"~-": bigint => bigint = "%negbigint" +external \"~+": bigint => bigint = "%identity" +external \"+": (bigint, bigint) => bigint = "%addbigint" +external \"-": (bigint, bigint) => bigint = "%subbigint" +external \"*": (bigint, bigint) => bigint = "%mulbigint" +external \"/": (bigint, bigint) => bigint = "%divbigint" +external mod: (bigint, bigint) => bigint = "%modbigint" +external \"**": (bigint, bigint) => bigint = "%powbigint" + +external land: (bigint, bigint) => bigint = "%andbigint" +external lor: (bigint, bigint) => bigint = "%orbigint" +external lxor: (bigint, bigint) => bigint = "%xorbigint" + +let lnot = x => lxor(x, -1n) + +external lsl: (bigint, bigint) => bigint = "%lslbigint" +external asr: (bigint, bigint) => bigint = "%asrbigint" + +@send +/** +Formats a `bigint` as a string. Return a `string` representing the given value. +See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) on MDN. + +## Examples + +```rescript +/* prints "123" */ +Js.BigInt.toString(123n)->Js.log +``` +*/ +external toString: bigint => string = "toString" + +@send +/** +Returns a string with a language-sensitive representation of this BigInt value. + +## Examples + +```rescript +/* prints "123" */ +Js.BigInt.toString(123n)->Js.log +``` +*/ +external toLocaleString: bigint => string = "toLocaleString" diff --git a/js/src/js_blob.res b/js/src/js_blob.res new file mode 100644 index 0000000..969208c --- /dev/null +++ b/js/src/js_blob.res @@ -0,0 +1,3 @@ +/*** JavaScript Blob API */ + +type t diff --git a/js/src/js_cast.res b/js/src/js_cast.res new file mode 100644 index 0000000..0713541 --- /dev/null +++ b/js/src/js_cast.res @@ -0,0 +1,27 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +external intOfBool: bool => int = "%identity" + +external floatOfInt: int => float = "%identity" diff --git a/js/src/js_cast.resi b/js/src/js_cast.resi new file mode 100644 index 0000000..8ef323b --- /dev/null +++ b/js/src/js_cast.resi @@ -0,0 +1,48 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Safe cast between OCaml values which share the same +runtime representation + +Different OCaml types might share the same represention in the +ReScript runtime; while this is a compiler internal knowledge, +applications might benefit from having a safe and zero cost +conversion between those types. + +This modules acts as the **single place** for such conversion. + +If for any reason, the runtime representation changes, those function +will be modified accordingly. +*/ + +/** +`intOfBool(b)` returns `1` for when `b` is `true` and `0` when `b` is `false` +*/ +external intOfBool: bool => int = "%identity" + +/** +`floatOfInt(i)` returns the float value of `i` +*/ +external floatOfInt: int => float = "%identity" diff --git a/js/src/js_console.res b/js/src/js_console.res new file mode 100644 index 0000000..9e0eda9 --- /dev/null +++ b/js/src/js_console.res @@ -0,0 +1,29 @@ +@val @scope("console") external log: 'a => unit = "log" +@val @scope("console") external log2: ('a, 'b) => unit = "log" +@val @scope("console") external log3: ('a, 'b, 'c) => unit = "log" +@val @scope("console") external log4: ('a, 'b, 'c, 'd) => unit = "log" +@val @scope("console") @variadic external logMany: array<'a> => unit = "log" + +@val @scope("console") external info: 'a => unit = "info" +@val @scope("console") external info2: ('a, 'b) => unit = "info" +@val @scope("console") external info3: ('a, 'b, 'c) => unit = "info" +@val @scope("console") external info4: ('a, 'b, 'c, 'd) => unit = "info" +@val @scope("console") @variadic external infoMany: array<'a> => unit = "info" + +@val @scope("console") external warn: 'a => unit = "warn" +@val @scope("console") external warn2: ('a, 'b) => unit = "warn" +@val @scope("console") external warn3: ('a, 'b, 'c) => unit = "warn" +@val @scope("console") external warn4: ('a, 'b, 'c, 'd) => unit = "warn" +@val @scope("console") @variadic external warnMany: array<'a> => unit = "warn" + +@val @scope("console") external error: 'a => unit = "error" +@val @scope("console") external error2: ('a, 'b) => unit = "error" +@val @scope("console") external error3: ('a, 'b, 'c) => unit = "error" +@val @scope("console") external error4: ('a, 'b, 'c, 'd) => unit = "error" +@val @scope("console") @variadic external errorMany: array<'a> => unit = "error" + +@val @scope("console") external trace: unit => unit = "trace" + +@val @scope("console") external timeStart: string => unit = "time" + +@val @scope("console") external timeEnd: string => unit = "timeEnd" diff --git a/js/src/js_date.res b/js/src/js_date.res new file mode 100644 index 0000000..2a7b6be --- /dev/null +++ b/js/src/js_date.res @@ -0,0 +1,1382 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provide bindings to JS date. (See +[`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) +on MDN.) JavaScript stores dates as the number of milliseconds since the UNIX +*epoch*, midnight 1 January 1970, UTC. +*/ + +type t + +@send +/** +Returns the primitive value of this date, equivalent to `getTime()`. (See +[`Date.valueOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf) +on MDN.) + +## Examples + +```rescript +Js.Date.valueOf(exampleDate) == 123456654321.0 +``` +*/ +external valueOf: t => float = "valueOf" + +@new +/** +Returns a date representing the current time. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +## Examples + +```rescript +let now = Js.Date.make() +``` +*/ +external make: unit => t = "Date" + +@new +/** +Returns a date representing the given argument, which is a number of +milliseconds since the epoch. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +## Examples + +```rescript +Js.Date.fromFloat(123456654321.0) == exampleDate +``` +*/ +external fromFloat: float => t = "Date" + +@new +/** +Returns a `Js.Date.t` represented by the given string. The string can be in +“IETF-compliant RFC 2822 timestamps, and also strings in a version of ISO8601.” +Returns `NaN` if given an invalid date string. According to the [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +documentation on MDN, its use is discouraged. + +## Examples + +```rescript +Js.Date.fromString("Thu, 29 Nov 1973 21:30:54.321 GMT") == exampleDate +Js.Date.fromString("1973-11-29T21:30:54.321Z00:00") == exampleDate +Js.Date.fromString("Thor, 32 Lok -19 60:70:80 XYZ") // returns NaN +``` +*/ +external fromString: string => t = "Date" + +@new +/** +Returns a date representing midnight of the first day of the given month and +year in the current time zone. Fractional parts of arguments are ignored. See +[`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +## Examples + +```rescript +let november1 = Js.Date.makeWithYM(~year=2020.0, ~month=10.0, ()) +``` +*/ +external makeWithYM: (~year: float, ~month: float, unit) => t = "Date" + +@new +/** +Returns a date representing midnight of the given date of the given month and +year in the current time zone. Fractional parts of arguments are ignored. See +[`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. +*/ +external makeWithYMD: (~year: float, ~month: float, ~date: float, unit) => t = "Date" + +@new +/** +Returns a date representing the given date of the given month and year, at zero +minutes and zero seconds past the given `hours`, in the current time zone. +Fractional parts of arguments are ignored. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. Fractional parts of the arguments are ignored. +*/ +external makeWithYMDH: (~year: float, ~month: float, ~date: float, ~hours: float, unit) => t = + "Date" + +@new +/** +Returns a date representing the given date of the given month and year, at zero +seconds past the given time in hours and minutes in the current time zone. +Fractional parts of arguments are ignored. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. +*/ +external makeWithYMDHM: ( + ~year: float, + ~month: float, + ~date: float, + ~hours: float, + ~minutes: float, + unit, +) => t = "Date" + +@new +/** +Returns a date representing the given date of the given month and year, at the +given time in hours, minutes, and seconds in the current time zone. Fractional +parts of arguments are ignored. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +## Examples + +```rescript +Js.Date.makeWithYMDHMS( + ~year=1973.0, + ~month=11.0, + ~date=29.0, + ~hours=21.0, + ~minutes=30.0, + ~seconds=54.321, + (), +) == exampleDate +``` +*/ +external makeWithYMDHMS: ( + ~year: float, + ~month: float, + ~date: float, + ~hours: float, + ~minutes: float, + ~seconds: float, + unit, +) => t = "Date" + +@val("Date.UTC") +/** +Returns a float representing the number of milliseconds past the epoch for +midnight of the first day of the given month and year in UTC. Fractional parts +of arguments are ignored. See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. + +## Examples + +```rescript +let november1 = Js.Date.utcWithYM(~year=2020.0, ~month=10.0, ()) +``` +*/ +external utcWithYM: (~year: float, ~month: float, unit) => float = "" + +@val("Date.UTC") +/** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year in UTC. Fractional parts +of arguments are ignored. See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*/ +external utcWithYMD: (~year: float, ~month: float, ~date: float, unit) => float = "" + +@val("Date.UTC") +/** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year, at zero minutes and +seconds past the given hours in UTC. Fractional parts of arguments are ignored. +See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*/ +external utcWithYMDH: (~year: float, ~month: float, ~date: float, ~hours: float, unit) => float = "" + +@val("Date.UTC") +/** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year, at zero seconds past +the given number of minutes past the given hours in UTC. Fractional parts of +arguments are ignored. See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*/ +external utcWithYMDHM: ( + ~year: float, + ~month: float, + ~date: float, + ~hours: float, + ~minutes: float, + unit, +) => float = "" + +@val("Date.UTC") +/** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year, at the given time in +hours, minutes and seconds in UTC. Fractional parts of arguments are ignored. + +See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*/ +external utcWithYMDHMS: ( + ~year: float, + ~month: float, + ~date: float, + ~hours: float, + ~minutes: float, + ~seconds: float, + unit, +) => float = "" + +@val("Date.now") /** Returns the current time as number of milliseconds since Unix epoch. */ +external now: unit => float = "" + +@new @deprecated("Please use `fromString` instead") external parse: string => t = "Date" + +@val("parse") +@scope("Date") +/** +Returns a float with the number of milliseconds past the epoch represented by +the given string. The string can be in “IETF-compliant RFC 2822 timestamps, and +also strings in a version of ISO8601.” Returns `NaN` if given an invalid date +string. According to the +[`Date.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) +documentation on MDN, its use is discouraged. Returns `NaN` if passed invalid +date string. +*/ +external parseAsFloat: string => float = "" + +@send +/** +Returns the day of the month for its argument. The argument is evaluated in the +current time zone. See +[`Date.getDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate) +on MDN. + +## Examples + +```rescript +Js.Date.getDate(exampleDate) == 29.0 +``` +*/ +external getDate: t => float = "getDate" + +@send +/** +Returns the day of the week (0.0-6.0) for its argument, where 0.0 represents +Sunday. The argument is evaluated in the current time zone. See +[`Date.getDay`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay) +on MDN. + +## Examples + +```rescript +Js.Date.getDay(exampleDate) == 4.0 +``` +*/ +external getDay: t => float = "getDay" + +@send +/** +Returns the full year (as opposed to the range 0-99) for its argument. The +argument is evaluated in the current time zone. See +[`Date.getFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear) +on MDN. + +## Examples + +```rescript +Js.Date.getFullYear(exampleDate) == 1973.0 +``` +*/ +external getFullYear: t => float = "getFullYear" + +@send +/** +Returns the hours for its argument, evaluated in the current time zone. See +[`Date.getHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours) +on MDN. + +## Examples + +```rescript +Js.Date.getHours(exampleDate) == 22.0 // Vienna is in GMT+01:00 +``` +*/ +external getHours: t => float = "getHours" + +@send +/** +Returns the number of milliseconds for its argument, evaluated in the current +time zone. See +[`Date.getMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds) +on MDN. + +## Examples + +```rescript +Js.Date.getMilliseconds(exampleDate) == 321.0 +``` +*/ +external getMilliseconds: t => float = "getMilliseconds" + +@send +/** +Returns the number of minutes for its argument, evaluated in the current time +zone. See +[`Date.getMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMinutes) +on MDN. + +## Examples + +```rescript +Js.Date.getMinutes(exampleDate) == 30.0 +``` +*/ +external getMinutes: t => float = "getMinutes" + +@send +/** +Returns the month (0.0-11.0) for its argument, evaluated in the current time +zone. January is month zero. See +[`Date.getMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMonth) +on MDN. + +## Examples + +```rescript +Js.Date.getMonth(exampleDate) == 10.0 +``` +*/ +external getMonth: t => float = "getMonth" + +@send +/** +Returns the seconds for its argument, evaluated in the current time zone. See +[`Date.getSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getSeconds) +on MDN. + +## Examples + +```rescript +Js.Date.getSeconds(exampleDate) == 54.0 +``` +*/ +external getSeconds: t => float = "getSeconds" + +@send +/** +Returns the number of milliseconds since Unix epoch, evaluated in UTC. See +[`Date.getTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime) +on MDN. + +## Examples + +```rescript +Js.Date.getTime(exampleDate) == 123456654321.0 +``` +*/ +external getTime: t => float = "getTime" + +@send +/** +Returns the time zone offset in minutes from the current time zone to UTC. See +[`Date.getTimezoneOffset`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset) +on MDN. + +## Examples + +```rescript +Js.Date.getTimezoneOffset(exampleDate) == -60.0 +``` +*/ +external getTimezoneOffset: t => float = "getTimezoneOffset" + +@send +/** +Returns the day of the month of the argument, evaluated in UTC. See +[`Date.getUTCDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDate) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCDate(exampleDate) == 29.0 +``` +*/ +external getUTCDate: t => float = "getUTCDate" + +@send +/** +Returns the day of the week of the argument, evaluated in UTC. The range of the +return value is 0.0-6.0, where Sunday is zero. See +[`Date.getUTCDay`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDay) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCDay(exampleDate) == 4.0 +``` +*/ +external getUTCDay: t => float = "getUTCDay" + +@send +/** +Returns the full year (as opposed to the range 0-99) for its argument. The +argument is evaluated in UTC. See +[`Date.getUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCFullYear(exampleDate) == 1973.0 +``` +*/ +external getUTCFullYear: t => float = "getUTCFullYear" + +@send +/** +Returns the hours for its argument, evaluated in the current time zone. See +[`Date.getUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCHours) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCHours(exampleDate) == 21.0 +``` +*/ +external getUTCHours: t => float = "getUTCHours" + +@send +/** +Returns the number of milliseconds for its argument, evaluated in UTC. See +[`Date.getUTCMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCMilliseconds(exampleDate) == 321.0 +``` +*/ +external getUTCMilliseconds: t => float = "getUTCMilliseconds" + +@send +/** +Returns the number of minutes for its argument, evaluated in UTC. See +[`Date.getUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCMinutes(exampleDate) == 30.0 +``` +*/ +external getUTCMinutes: t => float = "getUTCMinutes" + +@send +/** +Returns the month (0.0-11.0) for its argument, evaluated in UTC. January is +month zero. See +[`Date.getUTCMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCMonth(exampleDate) == 10.0 +``` +*/ +external getUTCMonth: t => float = "getUTCMonth" + +@send +/** +Returns the seconds for its argument, evaluated in UTC. See +[`Date.getUTCSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds) +on MDN. + +## Examples + +```rescript +Js.Date.getUTCSeconds(exampleDate) == 54.0 +``` +*/ +external getUTCSeconds: t => float = "getUTCSeconds" + +@send @deprecated("Use `getFullYear` instead.") external getYear: t => float = "getYear" + +@send +/** +Sets the given `Date`’s day of month to the value in the second argument +according to the current time zone. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let twoWeeksBefore = Js.Date.setDate(date1, 15.0) +date1 == Js.Date.fromString("1973-11-15T21:30:54.321Z00:00") +twoWeeksBefore == Js.Date.getTime(date1) +``` +*/ +external setDate: (t, float) => float = "setDate" + +@send +/** +Sets the given `Date`’s year to the value in the second argument according to +the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextYear = Js.Date.setFullYear(date1, 1974.0) +date1 == Js.Date.fromString("1974-11-15T21:30:54.321Z00:00") +nextYear == Js.Date.getTime(date1) +``` +*/ +external setFullYear: (t, float) => float = "setFullYear" + +@send +/** +Sets the given `Date`’s year and month to the values in the labeled arguments +according to the current time zone. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setFullYearM(date1, ~year=1974.0, ~month=0.0, ()) +date1 == Js.Date.fromString("1974-01-22T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*/ +external setFullYearM: (t, ~year: float, ~month: float, unit) => float = "setFullYear" + +@send +/** +Sets the given `Date`’s year, month, and day of month to the values in the +labeled arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setFullYearMD(date1, ~year=1974.0, ~month=0.0, ~date=7.0, ()) +date1 == Js.Date.fromString("1974-01-07T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*/ +external setFullYearMD: (t, ~year: float, ~month: float, ~date: float, unit) => float = + "setFullYear" + +@send +/** +Sets the given `Date`’s hours to the value in the second argument according to +the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextHour = Js.Date.setHours(date1, 22.0) +date1 == Js.Date.fromString("1973-11-29T22:30:54.321Z00:00") +nextHour == Js.Date.getTime(date1) +``` +*/ +external setHours: (t, float) => float = "setHours" + +@send +/** +Sets the given `Date`’s hours and minutes to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setHoursM(date1, ~hours=22.0, ~minutes=46.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:54.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setHoursM: (t, ~hours: float, ~minutes: float, unit) => float = "setHours" + +@send +/** +Sets the given `Date`’s hours, minutes, and seconds to the values in the +labeled arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setHoursMS(date1, ~hours=22.0, ~minutes=46.0, ~seconds=37.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:37.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setHoursMS: (t, ~hours: float, ~minutes: float, ~seconds: float, unit) => float = + "setHours" + +@send +/** +Sets the given `Date`’s hours, minutes, seconds, and milliseconds to the values +in the labeled arguments according to the current time zone. Returns the number +of milliseconds since the epoch of the updated `Date`. *This function modifies +the original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setHoursMSMs( + date1, + ~hours=22.0, + ~minutes=46.0, + ~seconds=37.0, + ~milliseconds=494.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T22:46:37.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setHoursMSMs: ( + t, + ~hours: float, + ~minutes: float, + ~seconds: float, + ~milliseconds: float, + unit, +) => float = "setHours" + +@send +/** +Sets the given `Date`’s milliseconds to the value in the second argument +according to the current time zone. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMilliseconds(date1, 494.0) +date1 == Js.Date.fromString("1973-11-29T21:30:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setMilliseconds: (t, float) => float = "setMilliseconds" + +@send +/** +Sets the given `Date`’s minutes to the value in the second argument according +to the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMinutes(date1, 34.0) +date1 == Js.Date.fromString("1973-11-29T21:34:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setMinutes: (t, float) => float = "setMinutes" + +@send +/** +Sets the given `Date`’s minutes and seconds to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMinutesS(date1, ~minutes=34.0, ~seconds=56.0, ()) +date1 == Js.Date.fromString("1973-11-29T21:34:56.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setMinutesS: (t, ~minutes: float, ~seconds: float, unit) => float = "setMinutes" + +@send +/** +Sets the given `Date`’s minutes, seconds, and milliseconds to the values in the +labeled arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMinutesSMs( + date1, + ~minutes=34.0, + ~seconds=56.0, + ~milliseconds=789.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setMinutesSMs: (t, ~minutes: float, ~seconds: float, ~milliseconds: float, unit) => float = + "setMinutes" + +@send +/** +Sets the given `Date`’s month to the value in the second argument according to +the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMonth(date1, 11.0) +date1 == Js.Date.fromString("1973-12-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setMonth: (t, float) => float = "setMonth" + +@send +/** +Sets the given `Date`’s month and day of month to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMonthD(date1, ~month=11.0, ~date=8.0, ()) +date1 == Js.Date.fromString("1973-12-08T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setMonthD: (t, ~month: float, ~date: float, unit) => float = "setMonth" + +@send +/** +Sets the given `Date`’s seconds to the value in the second argument according +to the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setSeconds) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setSeconds(date1, 56.0) +date1 == Js.Date.fromString("1973-12-29T21:30:56.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setSeconds: (t, float) => float = "setSeconds" + +@send +/** +Sets the given `Date`’s seconds and milliseconds to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setSeconds) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setSecondsMs(date1, ~seconds=56.0, ~milliseconds=789.0, ()) +date1 == Js.Date.fromString("1973-12-29T21:30:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setSecondsMs: (t, ~seconds: float, ~milliseconds: float, unit) => float = "setSeconds" + +@send +/** +Sets the given `Date`’s value in terms of milliseconds since the epoch. Returns +the number of milliseconds since the epoch of the updated `Date`. *This +function modifies the original `Date`.* See +[`Date.setTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setTime) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setTime(date1, 198765432101.0) + +date1 == Js.Date.fromString("1976-04-19T12:37:12.101Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setTime: (t, float) => float = "setTime" + +@send +/** +Sets the given `Date`’s day of month to the value in the second argument +according to UTC. Returns the number of milliseconds since the epoch of the +updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCDate) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let twoWeeksBefore = Js.Date.setUTCDate(date1, 15.0) +date1 == Js.Date.fromString("1973-11-15T21:30:54.321Z00:00") +twoWeeksBefore == Js.Date.getTime(date1) +``` +*/ +external setUTCDate: (t, float) => float = "setUTCDate" + +@send +/** +Sets the given `Date`’s year to the value in the second argument according to +UTC. Returns the number of milliseconds since the epoch of the updated `Date`. +*This function modifies the original `Date`.* See +[`Date.setUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextYear = Js.Date.setUTCFullYear(date1, 1974.0) +date1 == Js.Date.fromString("1974-11-15T21:30:54.321Z00:00") +nextYear == Js.Date.getTime(date1) +``` +*/ +external setUTCFullYear: (t, float) => float = "setUTCFullYear" + +@send +/** +Sets the given `Date`’s year and month to the values in the labeled arguments +according to UTC. Returns the number of milliseconds since the epoch of the +updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setUTCFullYearM(date1, ~year=1974.0, ~month=0.0, ()) +date1 == Js.Date.fromString("1974-01-22T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*/ +external setUTCFullYearM: (t, ~year: float, ~month: float, unit) => float = "setUTCFullYear" + +@send +/** +Sets the given `Date`’s year, month, and day of month to the values in the +labeled arguments according to UTC. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setUTCFullYearMD(date1, ~year=1974.0, ~month=0.0, ~date=7.0, ()) +date1 == Js.Date.fromString("1974-01-07T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*/ +external setUTCFullYearMD: (t, ~year: float, ~month: float, ~date: float, unit) => float = + "setUTCFullYear" + +@send +/** +Sets the given `Date`’s hours to the value in the second argument according to +UTC. Returns the number of milliseconds since the epoch of the updated `Date`. +*This function modifies the original `Date`.* See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextHour = Js.Date.setUTCHours(date1, 22.0) +date1 == Js.Date.fromString("1973-11-29T22:30:54.321Z00:00") +nextHour == Js.Date.getTime(date1) +``` +*/ +external setUTCHours: (t, float) => float = "setUTCHours" + +@send +/** +Sets the given `Date`’s hours and minutes to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCHoursM(date1, ~hours=22.0, ~minutes=46.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:54.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCHoursM: (t, ~hours: float, ~minutes: float, unit) => float = "setUTCHours" + +@send +/** +Sets the given `Date`’s hours, minutes, and seconds to the values in the +labeled arguments according to UTC. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* + +See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCHoursMS(date1, ~hours=22.0, ~minutes=46.0, ~seconds=37.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:37.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCHoursMS: (t, ~hours: float, ~minutes: float, ~seconds: float, unit) => float = + "setUTCHours" + +@send +/** +Sets the given `Date`’s hours, minutes, seconds, and milliseconds to the values +in the labeled arguments according to UTC. Returns the number of milliseconds +since the epoch of the updated `Date`. *This function modifies the original +`Date`.* See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCHoursMSMs( + date1, + ~hours=22.0, + ~minutes=46.0, + ~seconds=37.0, + ~milliseconds=494.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T22:46:37.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCHoursMSMs: ( + t, + ~hours: float, + ~minutes: float, + ~seconds: float, + ~milliseconds: float, + unit, +) => float = "setUTCHours" + +@send +/** +Sets the given `Date`’s milliseconds to the value in the second argument +according to UTC. Returns the number of milliseconds since the epoch of the +updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMilliseconds(date1, 494.0) +date1 == Js.Date.fromString("1973-11-29T21:30:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCMilliseconds: (t, float) => float = "setUTCMilliseconds" + +@send +/** +Sets the given `Date`’s minutes to the value in the second argument according +to the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMinutes(date1, 34.0) +date1 == Js.Date.fromString("1973-11-29T21:34:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCMinutes: (t, float) => float = "setUTCMinutes" + +@send +/** +Sets the given `Date`’s minutes and seconds to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMinutesS(date1, ~minutes=34.0, ~seconds=56.0, ()) +date1 == Js.Date.fromString("1973-11-29T21:34:56.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCMinutesS: (t, ~minutes: float, ~seconds: float, unit) => float = "setUTCMinutes" + +@send +/** +Sets the given `Date`’s minutes, seconds, and milliseconds to the values in the +labeled arguments according to UTC. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMinutesSMs( + date1, + ~minutes=34.0, + ~seconds=56.0, + ~milliseconds=789.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCMinutesSMs: ( + t, + ~minutes: float, + ~seconds: float, + ~milliseconds: float, + unit, +) => float = "setUTCMinutes" + +@send +/** +Sets the given `Date`’s month to the value in the second argument according to +UTC. Returns the number of milliseconds since the epoch of the updated `Date`. +*This function modifies the original `Date`.* See +[`Date.setUTCMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMonth(date1, 11.0) +date1 == Js.Date.fromString("1973-12-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCMonth: (t, float) => float = "setUTCMonth" + +@send +/** +Sets the given `Date`’s month and day of month to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMonthD(date1, ~month=11.0, ~date=8.0, ()) +date1 == Js.Date.fromString("1973-12-08T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCMonthD: (t, ~month: float, ~date: float, unit) => float = "setUTCMonth" + +@send +/** +Sets the given `Date`’s seconds to the value in the second argument according +to UTC. Returns the number of milliseconds since the epoch of the updated +`Date`. *This function modifies the original `Date`.* See +[`Date.setUTCSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCSeconds(date1, 56.0) +date1 == Js.Date.fromString("1973-12-29T21:30:56.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCSeconds: (t, float) => float = "setUTCSeconds" + +@send +/** +Sets the given `Date`’s seconds and milliseconds to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds) +on MDN. + +## Examples + +```rescript +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCSecondsMs(date1, ~seconds=56.0, ~milliseconds=789.0, ()) +date1 == Js.Date.fromString("1973-12-29T21:30:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*/ +external setUTCSecondsMs: (t, ~seconds: float, ~milliseconds: float, unit) => float = + "setUTCSeconds" + +@send /** Same as [`setTime()`](#settime). */ +external setUTCTime: (t, float) => float = "setTime" + +@send @deprecated("Use `setFullYear` instead") external setYear: (t, float) => float = "setYear" + +@send +/** +Returns the date (day of week, year, month, and day of month) portion of a +`Date` in English. See +[`Date.toDateString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toDateString) +on MDN. + +## Examples + +```rescript +Js.Date.toDateString(exampleDate) == "Thu Nov 29 1973" +``` +*/ +external toDateString: t => string = "toDateString" + +@send @deprecated("Use `toUTCString` instead") external toGMTString: t => string = "toGMTString" + +@send +/** +Returns a simplified version of the ISO 8601 format for the date. See +[`Date.toISOString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +on MDN. + +## Examples + +```rescript +Js.Date.toISOString(exampleDate) == "1973-11-29T21:30:54.321Z" +``` +*/ +external toISOString: t => string = "toISOString" + +@send +@deprecated( + "This method is unsafe. It will be changed to return option in a future \ + release. Please use toJSONUnsafe instead." +) +external toJSON: t => string = "toJSON" + +@send +/** +Returns a string representation of the given date. See +[`Date.toJSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON) +on MDN. +*/ +external toJSONUnsafe: t => string = "toJSON" + +@send +/** +Returns the year, month, and day for the given `Date` in the current locale +format. See +[`Date.toLocaleDateString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString) +on MDN. + +## Examples + +```rescript +Js.Date.toLocaleDateString(exampleDate) == "11/29/1973" // for en_US.utf8 +Js.Date.toLocaleDateString(exampleDate) == "29.11.73" // for de_DE.utf8 +``` +*/ +external toLocaleDateString: t => string = "toLocaleDateString" + +/* TODO: has overloads with somewhat poor browser support */ + +@send +/** +Returns the time and date for the given `Date` in the current locale format. +See +[`Date.toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString) +on MDN. + +## Examples + +```rescript +Js.Date.toLocaleString(exampleDate) == "11/29/1973, 10:30:54 PM" // for en_US.utf8 +Js.Date.toLocaleString(exampleDate) == "29.11.1973, 22:30:54" // for de_DE.utf8 +``` +*/ +external toLocaleString: t => string = "toLocaleString" + +/* TODO: has overloads with somewhat poor browser support */ + +@send +/** +Returns the time of day for the given `Date` in the current locale format. See +[`Date.toLocaleTimeString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString) +on MDN. + +## Examples + +```rescript +Js.Date.toLocaleString(exampleDate) == "10:30:54 PM" // for en_US.utf8 +Js.Date.toLocaleString(exampleDate) == "22:30:54" // for de_DE.utf8 +``` +*/ +external toLocaleTimeString: t => string = "toLocaleTimeString" + +/* TODO: has overloads with somewhat poor browser support */ + +@send +/** +Returns a string representing the date and time of day for the given `Date` in +the current locale and time zone. See +[`Date.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString) +on MDN. + +## Examples + +```rescript +Js.Date.toString( + exampleDate, +) == "Thu Nov 29 1973 22:30:54 GMT+0100 (Central European Standard Time)" +``` +*/ +external toString: t => string = "toString" + +@send +/** +Returns a string representing the time of day for the given `Date` in the +current locale and time zone. See +[`Date.toTimeString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toTimeString) +on MDN. + +## Examples + +```rescript +Js.Date.toTimeString(exampleDate) == "22:30:54 GMT+0100 (Central European Standard Time)" +``` +*/ +external toTimeString: t => string = "toTimeString" + +@send +/** +Returns a string representing the date and time of day for the given `Date` in +the current locale and UTC (GMT time zone). See +[`Date.toUTCString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString) +on MDN. + +## Examples + +```rescript +Js.Date.toUTCString(exampleDate) == "Thu, 29 Nov 1973 21:30:54 GMT" +``` +*/ +external toUTCString: t => string = "toUTCString" diff --git a/js/src/js_dict.res b/js/src/js_dict.res new file mode 100644 index 0000000..cd07c15 --- /dev/null +++ b/js/src/js_dict.res @@ -0,0 +1,124 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provides a simple key-value dictionary abstraction over native JavaScript objects */ + +/** The dict type */ +type t<'a> = dict<'a> + +/** The key type, an alias of string */ +type key = string + +/** + `unsafeGet dict key` returns the value associated with `key` in `dict` + + This function will return an invalid value (`undefined`) if `key` does not exist in `dict`. It + will not throw an error. +*/ +@get_index +external unsafeGet: (t<'a>, key) => 'a = "" +let \".!()" = unsafeGet + +/** `get dict key` returns the value associated with `key` in `dict` */ +let get = (type u, dict: t, k: key): option => + if %raw(`k in dict`) { + Some(\".!()"(dict, k)) + } else { + None + } + +/** `set dict key value` sets the value of `key` in `dict` to `value` */ +@set_index +external set: (t<'a>, key, 'a) => unit = "" + +/** `keys dict` returns an array of all the keys in `dict` */ +@val +external keys: t<'a> => array = "Object.keys" + +/** `empty ()` creates an empty dictionary */ +@obj +external empty: unit => t<'a> = "" + +let unsafeDeleteKey: (. t, string) => unit = %raw(` function (dict,key){ + delete dict[key]; + } + `) + +@new external unsafeCreate: int => array<'a> = "Array" +/* external entries : 'a t -> (key * 'a) array = "Object.entries" [@@val] (* ES2017 *) */ +let entries = dict => { + let keys = keys(dict) + let l = Js_array2.length(keys) + let values = unsafeCreate(l) + for i in 0 to l - 1 { + let key = Js_array2.unsafe_get(keys, i) + Js_array2.unsafe_set(values, i, (key, \".!()"(dict, key))) + } + values +} + +/* external values : 'a t -> 'a array = "Object.values" [@@val] (* ES2017 *) */ +let values = dict => { + let keys = keys(dict) + let l = Js_array2.length(keys) + let values = unsafeCreate(l) + for i in 0 to l - 1 { + Js_array2.unsafe_set(values, i, \".!()"(dict, Js_array2.unsafe_get(keys, i))) + } + values +} + +let fromList = entries => { + let dict = empty() + let rec loop = x => + switch x { + | list{} => dict + | list{(key, value), ...rest} => + set(dict, key, value) + loop(rest) + } + + loop(entries) +} + +let fromArray = entries => { + let dict = empty() + let l = Js_array2.length(entries) + for i in 0 to l - 1 { + let (key, value) = Js_array2.unsafe_get(entries, i) + set(dict, key, value) + } + dict +} + +let map = (f, source) => { + let target = empty() + let keys = keys(source) + let l = Js_array2.length(keys) + for i in 0 to l - 1 { + let key = Js_array2.unsafe_get(keys, i) + set(target, key, f(. unsafeGet(source, key))) + } + target +} diff --git a/js/src/js_dict.resi b/js/src/js_dict.resi new file mode 100644 index 0000000..5f6a30f --- /dev/null +++ b/js/src/js_dict.resi @@ -0,0 +1,173 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provide utilities for JS dictionary object. + +**Note:** This module's examples will assume this predeclared dictionary: + +## Examples + +```rescript +let ages = Js.Dict.fromList(list{("Maria", 30), ("Vinh", 22), ("Fred", 49)}) +``` +*/ + +/* +Dictionary type (ie an '{ }' JS object). However it is restricted to hold a +single type; therefore values must have the same type. This Dictionary type is +mostly used with the Js_json.t type. +*/ +type t<'a> = dict<'a> + +/** + The type for dictionary keys. This means that dictionaries *must* use `string`s as their keys. +*/ +type key = string + +/** +`Js.Dict.get(key)` returns `None` if the key is not found in the dictionary, +`Some(value)` otherwise. + +## Examples + +```rescript +Js.Dict.get(ages, "Vinh") == Some(22) +Js.Dict.get(ages, "Paul") == None +``` +*/ +let get: (t<'a>, key) => option<'a> + +@get_index +/** +`Js.Dict.unsafeGet(key)` returns the value if the key exists, otherwise an `undefined` value is returned. Use this only when you are sure the key exists (i.e. when having used the `keys()` function to check that the key is valid). + +## Examples + +```rescript +Js.Dict.unsafeGet(ages, "Fred") == 49 +Js.Dict.unsafeGet(ages, "Paul") // returns undefined +``` +*/ +external unsafeGet: (t<'a>, key) => 'a = "" + +@set_index +/** +`Js.Dict.set(dict, key, value)` sets the key/value in the dictionary `dict`. If +the key does not exist, and entry will be created for it. + +*This function modifies the original dictionary.* + +## Examples + +```rescript +Js.Dict.set(ages, "Maria", 31) +Js.log(ages == Js.Dict.fromList(list{("Maria", 31), ("Vinh", 22), ("Fred", 49)})) + +Js.Dict.set(ages, "David", 66) +Js.log(ages == Js.Dict.fromList(list{("Maria", 31), ("Vinh", 22), ("Fred", 49), ("David", 66)})) +``` +*/ +external set: (t<'a>, key, 'a) => unit = "" + +@val +/** +Returns all the keys in the dictionary `dict`. + +## Examples + +```rescript +Js.Dict.keys(ages) == ["Maria", "Vinh", "Fred"] +``` +*/ +external keys: t<'a> => array = "Object.keys" + +@obj /** Returns an empty dictionary. */ +external empty: unit => t<'a> = "" + +/** Experimental internal function */ +let unsafeDeleteKey: (. t, string) => unit + +/** +Returns an array of key/value pairs in the given dictionary (ES2017). + +## Examples + +```rescript +Js.Dict.entries(ages) == [("Maria", 30), ("Vinh", 22), ("Fred", 49)] +``` +*/ +let entries: t<'a> => array<(key, 'a)> + +/** +Returns the values in the given dictionary (ES2017). + +## Examples + +```rescript +Js.Dict.values(ages) == [30, 22, 49] +``` +*/ +let values: t<'a> => array<'a> + +/** +Creates a new dictionary containing each (key, value) pair in its list +argument. + +## Examples + +```rescript +let capitals = Js.Dict.fromList(list{("Japan", "Tokyo"), ("France", "Paris"), ("Egypt", "Cairo")}) +``` +*/ +let fromList: list<(key, 'a)> => t<'a> + +/** +Creates a new dictionary containing each (key, value) pair in its array +argument. + +## Examples + +```rescript +let capitals2 = Js.Dict.fromArray([("Germany", "Berlin"), ("Burkina Faso", "Ouagadougou")]) +``` +*/ +let fromArray: array<(key, 'a)> => t<'a> + +/** +`map(f, dict)` maps `dict` to a new dictionary with the same keys, using the +function `f` to map each value. + +## Examples + +```rescript +let prices = Js.Dict.fromList(list{("pen", 1.00), ("book", 5.00), ("stapler", 7.00)}) + +let discount = (. price) => price *. 0.90 +let salePrices = Js.Dict.map(discount, prices) + +salePrices == Js.Dict.fromList(list{("pen", 0.90), ("book", 4.50), ("stapler", 6.30)}) +``` +*/ +let map: ((. 'a) => 'b, t<'a>) => t<'b> diff --git a/js/src/js_exn.res b/js/src/js_exn.res new file mode 100644 index 0000000..9cd37bc --- /dev/null +++ b/js/src/js_exn.res @@ -0,0 +1,87 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +type t = unknown + +@@warning("-38") /* unused extension constructor */ +exception Error = JsError + +external asJsExn: exn => option = "?as_js_exn" + +@get external stack: t => option = "stack" +@get external message: t => option = "message" +@get external name: t => option = "name" +@get external fileName: t => option = "fileName" + +type error +@new external makeError: string => error = "Error" +external isCamlExceptionOrOpenVariant: 'a => bool = "?is_extension" + +external anyToExnInternal: 'a => exn = "#wrap_exn" + +let raiseError = str => raise((Obj.magic((makeError(str): error)): exn)) + +type eval_error +@new external makeEvalError: string => eval_error = "EvalError" + +let raiseEvalError = str => raise((Obj.magic((makeEvalError(str): eval_error)): exn)) + +type range_error +@new external makeRangeError: string => range_error = "RangeError" + +let raiseRangeError = str => raise((Obj.magic((makeRangeError(str): range_error)): exn)) + +type reference_error + +@new external makeReferenceError: string => reference_error = "ReferenceError" + +let raiseReferenceError = str => raise(Obj.magic(makeReferenceError(str))) + +type syntax_error +@new external makeSyntaxError: string => syntax_error = "SyntaxError" + +let raiseSyntaxError = str => raise(Obj.magic(makeSyntaxError(str))) + +type type_error +@new external makeTypeError: string => type_error = "TypeError" + +let raiseTypeError = str => raise(Obj.magic(makeTypeError(str))) + +type uri_error +@new external makeURIError: string => uri_error = "URIError" + +let raiseUriError = str => raise(Obj.magic(makeURIError(str))) + +/* TODO add predicate to tell which error is which " */ + +/* +exception EvalError of error +exception RangeError of error +exception ReferenceError of error +exception SyntaxError of error +exception TypeError of error + + The URIError object represents an error when a global URI handling function was used in a wrong way. +exception URIError of error +*/ diff --git a/js/src/js_exn.resi b/js/src/js_exn.resi new file mode 100644 index 0000000..87ce8ca --- /dev/null +++ b/js/src/js_exn.resi @@ -0,0 +1,76 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provide utilities for dealing with JS exceptions. +*/ + +/** Represents a JS exception */ +type t + +type exn += private Error(t) + +external asJsExn: exn => option = "?as_js_exn" + +@get external stack: t => option = "stack" +@get external message: t => option = "message" +@get external name: t => option = "name" +@get external fileName: t => option = "fileName" + +/** internal use only */ +external isCamlExceptionOrOpenVariant: 'a => bool = "?is_extension" + +/** +`anyToExnInternal(obj)` will take any value `obj` and wrap it +in a Js.Exn.Error if given value is not an exn already. If +`obj` is an exn, it will return `obj` without any changes. + +This function is mostly useful for cases where you want to unify a type of a value +that potentially is either exn, a JS error, or any other JS value really (e.g. for +a value passed to a Promise.catch callback) + +**IMPORTANT**: This is an internal API and may be changed / removed any time in the future. + +## Examples + +```rescript +switch (Js.Exn.unsafeAnyToExn("test")) { +| Js.Exn.Error(v) => + switch(Js.Exn.message(v)) { + | Some(str) => Js.log("We won't end up here") + | None => Js.log2("We will land here: ", v) + } +} +``` +*/ +external anyToExnInternal: 'a => exn = "#wrap_exn" + +/** Raise Js exception Error object with stacktrace */ +let raiseError: string => 'a +let raiseEvalError: string => 'a +let raiseRangeError: string => 'a +let raiseReferenceError: string => 'a +let raiseSyntaxError: string => 'a +let raiseTypeError: string => 'a +let raiseUriError: string => 'a diff --git a/js/src/js_file.res b/js/src/js_file.res new file mode 100644 index 0000000..9836eff --- /dev/null +++ b/js/src/js_file.res @@ -0,0 +1,3 @@ +/*** JavaScript File API */ + +type t diff --git a/js/src/js_float.res b/js/src/js_float.res new file mode 100644 index 0000000..0b63205 --- /dev/null +++ b/js/src/js_float.res @@ -0,0 +1,274 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provide utilities for JS float. +*/ + +@val +/** +The special value "Not a Number". See [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) on MDN. +*/ +external _NaN: float = "NaN" + +@val +@scope("Number") +/** +Tests if the given value is `_NaN` + +Note that both `_NaN = _NaN` and `_NaN == _NaN` will return `false`. `isNaN` is +therefore necessary to test for `_NaN`. Return `true` if the given value is +`_NaN`, `false` otherwise. See [`isNaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) on MDN. +*/ +external isNaN: float => bool = "isNaN" + +@val +@scope("Number") +/** +Tests if the given value is finite. Return `true` if the given value is a finite +number, `false` otherwise. See [`isFinite`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) on MDN. + +## Examples + +```rescript +/* returns [false] */ +Js.Float.isFinite(infinity) + +/* returns [false] */ +Js.Float.isFinite(neg_infinity) + +/* returns [false] */ +Js.Float.isFinite(Js.Float._NaN) + +/* returns [true] */ +Js.Float.isFinite(1234.) +``` +*/ +external isFinite: float => bool = "isFinite" + +@send +/** +Formats a `float` using exponential (scientific) notation. Return a +`string` representing the given value in exponential notation. Raise +RangeError if digits is not in the range [0, 20] (inclusive). See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) on MDN. + +## Examples + +```rescript +/* prints "7.71234e+1" */ +Js.Float.toExponential(77.1234)->Js.log + +/* prints "7.7e+1" */ +Js.Float.toExponential(77.)->Js.log +``` +*/ +external toExponential: float => string = "toExponential" + +@send +/** +Formats a `float` using exponential (scientific) notation. `digits` specifies +how many digits should appear after the decimal point. The value must be in +the range [0, 20] (inclusive). Return a `string` representing the given value +in exponential notation. The output will be rounded or padded with zeroes if +necessary. Raise RangeError if `digits` is not in the range [0, 20] (inclusive). +See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) on MDN. + +## Examples + +```rescript +/* prints "7.71e+1" */ +Js.Float.toExponentialWithPrecision(77.1234, ~digits=2)->Js.log +``` +*/ +external toExponentialWithPrecision: (float, ~digits: int) => string = "toExponential" + +@send +/** +Formats a `float` using fixed point notation. Return a `string` representing the +given value in fixed-point notation (usually). Raise RangeError if digits is not +in the range [0, 20] (inclusive). See [`toFixed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) on MDN. + +## Examples + +```rescript +/* prints "12346" (note the rounding) */ +Js.Float.toFixed(12345.6789)->Js.log + +/* print "1.2e+21" */ +Js.Float.toFixed(1.2e21)->Js.log +``` +*/ +external toFixed: float => string = "toFixed" + +@send +/** +Formats a `float` using fixed point notation. `digits` specifies how many digits +should appear after the decimal point. The value must be in the range [0, 20] +(inclusive). Defaults to `0`. Return a `string` representing the given value in +fixed-point notation (usually). See [`toFixed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) on MDN. + +The output will be rounded or padded with zeroes if necessary. + +Raise RangeError if digits is not in the range [0, 20] (inclusive) + +## Examples + +```rescript +/* prints "12345.7" (note the rounding) */ +Js.Float.toFixedWithPrecision(12345.6789, ~digits=1)->Js.log + +/* prints "0.00" (note the added zeroes) */ +Js.Float.toFixedWithPrecision(0., ~digits=2)->Js.log +``` +*/ +external toFixedWithPrecision: (float, ~digits: int) => string = "toFixed" + +@send +/** +Formats a `float` using some fairly arbitrary rules. Return a `string` +representing the given value in fixed-point (usually). `toPrecision` differs +from `Js.Float.toFixed` in that the former will format the number with full +precision, while the latter will not output any digits after the decimal point. +See [`toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN. + +Raise RangeError if digits is not in the range accepted by this function (what do you mean "vague"?) + +## Examples + +```rescript +/* prints "12345.6789" */ +Js.Float.toPrecision(12345.6789)->Js.log + +/* print "1.2e+21" */ +Js.Float.toPrecision(1.2e21)->Js.log +``` +*/ +external toPrecision: float => string = "toPrecision" + +/* equivalent to `toString` I think */ + +@send +/** +Formats a `float` using some fairly arbitrary rules. `digits` specifies how many +digits should appear in total. The value must between 0 and some arbitrary number +that's hopefully at least larger than 20 (for Node it's 21. Why? Who knows). +See [`toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN. + +Return a `string` representing the given value in fixed-point or scientific +notation. The output will be rounded or padded with zeroes if necessary. + +`toPrecisionWithPrecision` differs from `toFixedWithPrecision` in that the former +will count all digits against the precision, while the latter will count only +the digits after the decimal point. `toPrecisionWithPrecision` will also use +scientific notation if the specified precision is less than the number for digits +before the decimal point. + +Raise RangeError if digits is not in the range accepted by this function (what do you mean "vague"?) + +## Examples + +```rescript +/* prints "1e+4" */ +Js.Float.toPrecisionWithPrecision(12345.6789, ~digits=1)->Js.log + +/* prints "0.0" */ +Js.Float.toPrecisionWithPrecision(0., ~digits=2)->Js.log +``` +*/ +external toPrecisionWithPrecision: (float, ~digits: int) => string = "toPrecision" + +@send +/** +Formats a `float` as a string. Return a `string` representing the given value in +fixed-point (usually). See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) on MDN. + +## Examples + +```rescript +/* prints "12345.6789" */ +Js.Float.toString(12345.6789)->Js.log +``` +*/ +external toString: float => string = "toString" + +@send +/** +Formats a `float` as a string. `radix` specifies the radix base to use for the +formatted number. The value must be in the range [2, 36] (inclusive). Return a +`string` representing the given value in fixed-point (usually). See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) on MDN. + +Raise RangeError if radix is not in the range [2, 36] (inclusive) + +## Examples + +```rescript +/* prints "110" */ +Js.Float.toStringWithRadix(6., ~radix=2)->Js.log + +/* prints "11.001000111101011100001010001111010111000010100011111" */ +Js.Float.toStringWithRadix(3.14, ~radix=2)->Js.log + +/* prints "deadbeef" */ +Js.Float.toStringWithRadix(3735928559., ~radix=16)->Js.log + +/* prints "3f.gez4w97ry0a18ymf6qadcxr" */ +Js.Float.toStringWithRadix(123.456, ~radix=36)->Js.log +``` +*/ +external toStringWithRadix: (float, ~radix: int) => string = "toString" + +@val +/** +Parses the given `string` into a `float` using JavaScript semantics. Return the +number as a `float` if successfully parsed, `_NaN` otherwise. + +## Examples + +```rescript +/* returns 123 */ +Js.Float.fromString("123") + +/* returns 12.3 */ +Js.Float.fromString("12.3") + +/* returns 0 */ +Js.Float.fromString("") + +/* returns 17 */ +Js.Float.fromString("0x11") + +/* returns 3 */ +Js.Float.fromString("0b11") + +/* returns 9 */ +Js.Float.fromString("0o11") + +/* returns [_NaN] */ +Js.Float.fromString("hello") + +/* returns [_NaN] */ +Js.Float.fromString("100a") +``` +*/ +external fromString: string => float = "Number" diff --git a/js/src/js_global.res b/js/src/js_global.res new file mode 100644 index 0000000..901a64d --- /dev/null +++ b/js/src/js_global.res @@ -0,0 +1,197 @@ +/* Copyright (C) 2017 Hongbo Zhang, Authors of ReScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Contains functions available in the global scope (`window` in a browser context) +*/ + +/** Identify an interval started by `Js.Global.setInterval`. */ +type intervalId + +/** Identify timeout started by `Js.Global.setTimeout`. */ +type timeoutId + +@val +/** +Clear an interval started by `Js.Global.setInterval` + +## Examples + +```rescript +/* API for a somewhat aggressive snoozing alarm clock */ + +let punchSleepyGuy = () => Js.log("Punch") + +let interval = ref(Js.Nullable.null) + +let remind = () => { + Js.log("Wake Up!") + punchSleepyGuy() +} + +let snooze = mins => + interval := Js.Nullable.return(Js.Global.setInterval(remind, mins * 60 * 1000)) + +let cancel = () => + Js.Nullable.iter(interval.contents, (. intervalId) => Js.Global.clearInterval(intervalId)) +``` +*/ +external clearInterval: intervalId => unit = "clearInterval" + +@val +/** +Clear a timeout started by `Js.Global.setTimeout`. + +## Examples + +```rescript +/* A simple model of a code monkey's brain */ + +let closeHackerNewsTab = () => Js.log("close") + +let timer = ref(Js.Nullable.null) + +let work = () => closeHackerNewsTab() + +let procrastinate = mins => { + Js.Nullable.iter(timer.contents, (. timer) => Js.Global.clearTimeout(timer)) + timer := Js.Nullable.return(Js.Global.setTimeout(work, mins * 60 * 1000)) +} +``` +*/ +external clearTimeout: timeoutId => unit = "clearTimeout" + +@val +/** +Repeatedly executes a callback with a specified interval (in milliseconds) +between calls. Returns a `Js.Global.intervalId` that can be passed to +`Js.Global.clearInterval` to cancel the timeout. + +## Examples + +```rescript +/* Will count up and print the count to the console every second */ + +let count = ref(0) + +let tick = () => { + count := count.contents + 1 + Js.log(Belt.Int.toString(count.contents)) +} + +Js.Global.setInterval(tick, 1000) +``` +*/ +external setInterval: (unit => unit, int) => intervalId = "setInterval" + +@val +/** +Repeatedly executes a callback with a specified interval (in milliseconds) +between calls. Returns a `Js.Global.intervalId` that can be passed to +`Js.Global.clearInterval` to cancel the timeout. + +## Examples + +```rescript +/* Will count up and print the count to the console every second */ + +let count = ref(0) + +let tick = () => { + count := count.contents + 1 + Js.log(Belt.Int.toString(count.contents)) +} + +Js.Global.setIntervalFloat(tick, 1000.0) +``` +*/ +external setIntervalFloat: (unit => unit, float) => intervalId = "setInterval" + +@val +/** +Execute a callback after a specified delay (in milliseconds). Returns a +`Js.Global.timeoutId` that can be passed to `Js.Global.clearTimeout` to cancel +the timeout. + +## Examples + +```rescript +/* Prints "Timed out!" in the console after one second */ + +let message = "Timed out!" + +Js.Global.setTimeout(() => Js.log(message), 1000) +``` +*/ +external setTimeout: (unit => unit, int) => timeoutId = "setTimeout" + +@val +/** +Execute a callback after a specified delay (in milliseconds). Returns a +`Js.Global.timeoutId` that can be passed to `Js.Global.clearTimeout` to cancel +the timeout. + +## Examples + +```rescript +/* Prints "Timed out!" in the console after one second */ + +let message = "Timed out!" + +Js.Global.setTimeoutFloat(() => Js.log(message), 1000.0) +``` +*/ +external setTimeoutFloat: (unit => unit, float) => timeoutId = "setTimeout" + +@val +/** +URL-encodes a string. + +See [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) on MDN. +*/ +external encodeURI: string => string = "encodeURI" + +@val +/** +Decodes a URL-enmcoded string produced by `encodeURI` + +See [`decodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) on MDN. +*/ +external decodeURI: string => string = "decodeURI" + +@val +/** +URL-encodes a string, including characters with special meaning in a URI. + +See [`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) on MDN. +*/ +external encodeURIComponent: string => string = "encodeURIComponent" + +@val +/** +Decodes a URL-enmcoded string produced by `encodeURIComponent` + +See [`decodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) on MDN. +*/ +external decodeURIComponent: string => string = "decodeURIComponent" diff --git a/js/src/js_int.res b/js/src/js_int.res new file mode 100644 index 0000000..f375b05 --- /dev/null +++ b/js/src/js_int.res @@ -0,0 +1,171 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provide utilities for handling `int`. +*/ + +/* +If we use number, we need coerce to int32 by adding `|0`, +otherwise `+0` can be wrong. +Most JS API is float oriented, it may overflow int32 or +comes with `NAN` +*/ + +/* + conversion */ + +@send +/** +Formats an `int` using exponential (scientific) notation. +Returns a `string` representing the given value in exponential notation. +Raises `RangeError` if digits is not in the range \[0, 20\] (inclusive). + +See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) on MDN. + +## Examples + +```rescript +/* prints "7.7e+1" */ +Js.log(Js.Int.toExponential(77)) +``` +*/ +external toExponential: int => string = "toExponential" + +@send +/** +Formats an `int` using exponential (scientific) notation. +`digits` specifies how many digits should appear after the decimal point. The value must be in the range \[0, 20\] (inclusive). + +Returns a `string` representing the given value in exponential notation. + +The output will be rounded or padded with zeroes if necessary. +Raises `RangeError` if `digits` is not in the range \[0, 20\] (inclusive). + +See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) on MDN. + +## Examples + +```rescript +/* prints "7.70e+1" */ +Js.log(Js.Int.toExponentialWithPrecision(77, ~digits=2)) + +/* prints "5.68e+3" */ +Js.log(Js.Int.toExponentialWithPrecision(5678, ~digits=2)) +``` +*/ +external toExponentialWithPrecision: (int, ~digits: int) => string = "toExponential" + +@send +/** +Formats an `int` using some fairly arbitrary rules. +Returns a `string` representing the given value in fixed-point (usually). + +`toPrecision` differs from `toFixed` in that the former will format the number with full precision, while the latter will not output any digits after the decimal point. +Raises `RangeError` if `digits` is not in the range accepted by this function. + +See [`toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN. + +## Examples + +```rescript +/* prints "123456789" */ +Js.log(Js.Int.toPrecision(123456789)) +``` +*/ +external toPrecision: int => string = "toPrecision" + +@send +/** +Formats an `int` using some fairly arbitrary rules. +`digits` specifies how many digits should appear in total. The value must between 0 and some arbitrary number that's hopefully at least larger than 20 (for Node it's 21. Why? Who knows). + +Returns a `string` representing the given value in fixed-point or scientific notation. + +The output will be rounded or padded with zeroes if necessary. + +`toPrecisionWithPrecision` differs from `toFixedWithPrecision` in that the former will count all digits against the precision, while the latter will count only the digits after the decimal point. +`toPrecisionWithPrecision` will also use scientific notation if the specified precision is less than the number of digits before the decimal point. +Raises `RangeError` if `digits` is not in the range accepted by this function. + + +See [`toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN. + +## Examples + +```rescript +/* prints "1.2e+8" */ +Js.log(Js.Int.toPrecisionWithPrecision(123456789, ~digits=2)) + +/* prints "0.0" */ +Js.log(Js.Int.toPrecisionWithPrecision(0, ~digits=2)) +``` +*/ +external toPrecisionWithPrecision: (int, ~digits: int) => string = "toPrecision" + +@send +/** +Formats an `int` as a `string`. Returns a `string` representing the given value +in fixed-point (usually). + +See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) on MDN. + +## Examples + +```rescript +/* prints "123456789" */ +Js.log(Js.Int.toString(123456789)) +``` +*/ +external toString: int => string = "toString" + +@send +/** +Formats an `int` as a `string`. `radix` specifies the radix base to use for the +formatted number. The value must be in the range \[2, 36\] (inclusive). Returns +a `string` representing the given value in fixed-point (usually). Raises +`RangeError` if `radix` is not in the range \[2, 36\] (inclusive). + + +See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) on MDN. + +## Examples + +```rescript +/* prints "110" */ +Js.log(Js.Int.toStringWithRadix(6, ~radix=2)) + +/* prints "deadbeef" */ +Js.log(Js.Int.toStringWithRadix(3735928559, ~radix=16)) + +/* prints "2n9c" */ +Js.log(Js.Int.toStringWithRadix(123456, ~radix=36)) +``` +*/ +external toStringWithRadix: (int, ~radix: int) => string = "toString" + +external toFloat: int => float = "%floatofint" + +let equal = (x: int, y) => x == y +let max: int = 2147483647 +let min: int = -2147483648 diff --git a/js/src/js_json.js b/js/src/js_json.js new file mode 100644 index 0000000..0d9dcb2 --- /dev/null +++ b/js/src/js_json.js @@ -0,0 +1,174 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var Kind = {}; + +function classify(x) { + var ty = typeof x; + if (ty === "string") { + return { + TAG: "JSONString", + _0: x + }; + } else if (ty === "number") { + return { + TAG: "JSONNumber", + _0: x + }; + } else if (ty === "boolean") { + if (x === true) { + return "JSONTrue"; + } else { + return "JSONFalse"; + } + } else if (x === null) { + return "JSONNull"; + } else if (Array.isArray(x)) { + return { + TAG: "JSONArray", + _0: x + }; + } else { + return { + TAG: "JSONObject", + _0: x + }; + } +} + +function test(x, v) { + switch (v) { + case "String" : + return typeof x === "string"; + case "Number" : + return typeof x === "number"; + case "Object" : + if (x !== null && typeof x === "object") { + return !Array.isArray(x); + } else { + return false; + } + case "Array" : + return Array.isArray(x); + case "Boolean" : + return typeof x === "boolean"; + case "Null" : + return x === null; + + } +} + +function decodeString(json) { + if (typeof json === "string") { + return json; + } + +} + +function decodeNumber(json) { + if (typeof json === "number") { + return json; + } + +} + +function decodeObject(json) { + if (typeof json === "object" && !Array.isArray(json) && json !== null) { + return json; + } + +} + +function decodeArray(json) { + if (Array.isArray(json)) { + return json; + } + +} + +function decodeBoolean(json) { + if (typeof json === "boolean") { + return json; + } + +} + +function decodeNull(json) { + if (json === null) { + return null; + } + +} + +var patch = (function (json) { + var x = [json]; + var q = [{ kind: 0, i: 0, parent: x }]; + while (q.length !== 0) { + // begin pop the stack + var cur = q[q.length - 1]; + if (cur.kind === 0) { + cur.val = cur.parent[cur.i]; // patch the undefined value for array + if (++cur.i === cur.parent.length) { + q.pop(); + } + } else { + q.pop(); + } + // finish + var task = cur.val; + if (typeof task === "object") { + if (Array.isArray(task) && task.length !== 0) { + q.push({ kind: 0, i: 0, parent: task, val: undefined }); + } else { + for (var k in task) { + if (k === "RE_PRIVATE_NONE") { + if (cur.kind === 0) { + cur.parent[cur.i - 1] = undefined; + } else { + cur.parent[cur.i] = undefined; + } + continue; + } + q.push({ kind: 1, i: k, parent: task, val: task[k] }); + } + } + } + } + return x[0]; +}); + +function serializeExn(x) { + return (function(obj){ + var output= JSON.stringify(obj,function(_,value){ + if(value===undefined){ + return {RE_PRIVATE_NONE : true} + } + return value + }); + + if(output === undefined){ + // JSON.stringify will raise TypeError when it detects cylic objects + throw new TypeError("output is undefined") + } + return output + })(x); +} + +function deserializeUnsafe(s) { + return patch(JSON.parse(s)); +} + +export { + Kind , + classify , + test , + decodeString , + decodeNumber , + decodeObject , + decodeArray , + decodeBoolean , + decodeNull , + deserializeUnsafe , + serializeExn , +} +/* No side effect */ diff --git a/js/src/js_json.res b/js/src/js_json.res new file mode 100644 index 0000000..dbf26e6 --- /dev/null +++ b/js/src/js_json.res @@ -0,0 +1,222 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Efficient JSON encoding using JavaScript API */ + +/** + The same as empty in `Js.Null`. Compiles to `null`. +*/ +external null: Js_null.t<'a> = "#null" + +@unboxed +type rec t = Runtime_types.json = + | Boolean(bool) + | @as(null) Null + | String(string) + | Number(float) + | Object(dict) + | Array(array) + +module Kind = { + type json = t + type rec t<_> = + | String: t + | Number: t + | Object: t> + | Array: t> + | Boolean: t + | Null: t +} + +type tagged_t = + | JSONFalse + | JSONTrue + | JSONNull + | JSONString(string) + | JSONNumber(float) + | JSONObject(Js_dict.t) + | JSONArray(array) + +let classify = (x: t): tagged_t => { + let ty = Js_typeof.typeof(x) + if ty == "string" { + JSONString(Obj.magic(x)) + } else if ty == "number" { + JSONNumber(Obj.magic(x)) + } else if ty == "boolean" { + if Obj.magic(x) == true { + JSONTrue + } else { + JSONFalse + } + } else if Obj.magic(x) === null { + JSONNull + } else if Js_array2.isArray(x) { + JSONArray(Obj.magic(x)) + } else { + JSONObject(Obj.magic(x)) + } +} + +let test = (type a, x: 'a, v: Kind.t): bool => + switch v { + | Kind.Number => Js_typeof.typeof(x) == "number" + | Kind.Boolean => Js_typeof.typeof(x) == "boolean" + | Kind.String => Js_typeof.typeof(x) == "string" + | Kind.Null => Obj.magic(x) === null + | Kind.Array => Js_array2.isArray(x) + | Kind.Object => + Obj.magic(x) !== null && (Js_typeof.typeof(x) == "object" && !Js_array2.isArray(x)) + } + +let decodeString = json => + if Js_typeof.typeof(json) == "string" { + Some((Obj.magic((json: t)): string)) + } else { + None + } + +let decodeNumber = json => + if Js_typeof.typeof(json) == "number" { + Some((Obj.magic((json: t)): float)) + } else { + None + } + +let decodeObject = json => + if ( + Js_typeof.typeof(json) == "object" && + (!Js_array2.isArray(json) && + !((Obj.magic(json): Js_null.t<'a>) === null)) + ) { + Some((Obj.magic((json: t)): Js_dict.t)) + } else { + None + } + +let decodeArray = json => + if Js_array2.isArray(json) { + Some((Obj.magic((json: t)): array)) + } else { + None + } + +let decodeBoolean = (json: t) => + if Js_typeof.typeof(json) == "boolean" { + Some((Obj.magic((json: t)): bool)) + } else { + None + } + +let decodeNull = (json): option> => + if (Obj.magic(json): Js_null.t<'a>) === null { + Some(null) + } else { + None + } + +/* external parse : string -> t = "parse" + [@@val][@@scope "JSON"] */ + +@val @scope("JSON") external parseExn: string => t = "parse" + +@val @scope("JSON") external stringifyAny: 'a => option = "stringify" +/* TODO: more docs when parse error happens or stringify non-stringfy value */ + +@val external null: t = "null" +external string: string => t = "%identity" +external number: float => t = "%identity" +external boolean: bool => t = "%identity" +external object_: Js_dict.t => t = "%identity" + +/* external array_ : t array -> t = "%identity" */ + +external array: array => t = "%identity" +external stringArray: array => t = "%identity" +external numberArray: array => t = "%identity" +external booleanArray: array => t = "%identity" +external objectArray: array> => t = "%identity" +@val @scope("JSON") external stringify: t => string = "stringify" +@val @scope("JSON") external stringifyWithSpace: (t, @as(json`null`) _, int) => string = "stringify" + +/* in memory modification does not work until your root is + actually None, so we need wrap it as ``v`` and + return the first element instead */ + +let patch: _ => _ = %raw(`function (json) { + var x = [json]; + var q = [{ kind: 0, i: 0, parent: x }]; + while (q.length !== 0) { + // begin pop the stack + var cur = q[q.length - 1]; + if (cur.kind === 0) { + cur.val = cur.parent[cur.i]; // patch the undefined value for array + if (++cur.i === cur.parent.length) { + q.pop(); + } + } else { + q.pop(); + } + // finish + var task = cur.val; + if (typeof task === "object") { + if (Array.isArray(task) && task.length !== 0) { + q.push({ kind: 0, i: 0, parent: task, val: undefined }); + } else { + for (var k in task) { + if (k === "RE_PRIVATE_NONE") { + if (cur.kind === 0) { + cur.parent[cur.i - 1] = undefined; + } else { + cur.parent[cur.i] = undefined; + } + continue; + } + q.push({ kind: 1, i: k, parent: task, val: task[k] }); + } + } + } + } + return x[0]; +} +`) + +let serializeExn = (type t, x: t): string => + %raw(` function(obj){ + var output= JSON.stringify(obj,function(_,value){ + if(value===undefined){ + return {RE_PRIVATE_NONE : true} + } + return value + }); + + if(output === undefined){ + // JSON.stringify will raise TypeError when it detects cylic objects + throw new TypeError("output is undefined") + } + return output + } +`)(x) + +let deserializeUnsafe = (s: string): 'a => patch(parseExn(s)) diff --git a/js/src/js_json.resi b/js/src/js_json.resi new file mode 100644 index 0000000..78c373d --- /dev/null +++ b/js/src/js_json.resi @@ -0,0 +1,277 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Efficient JSON encoding using JavaScript API + +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) +*/ + +/* ## Types */ + +@unboxed /** The JSON data structure */ +type rec t = Runtime_types.json = + | Boolean(bool) + | @as(null) Null + | String(string) + | Number(float) + | Object(dict) + | Array(array) + +module Kind: { + type json = t + /** Underlying type of a JSON value */ + type rec t<_> = + | String: t + | Number: t + | Object: t> + | Array: t> + | Boolean: t + | Null: t +} + +type tagged_t = + | JSONFalse + | JSONTrue + | JSONNull + | JSONString(string) + | JSONNumber(float) + | JSONObject(Js_dict.t) + | JSONArray(array) + +/* ## Accessors */ + +let classify: t => tagged_t + +/** +`test(v, kind)` returns `true` if `v` is of `kind`. +*/ +let test: ('a, Kind.t<'b>) => bool + +/** +`decodeString(json)` returns `Some(s)` if `json` is a `string`, `None` otherwise. +*/ +let decodeString: t => option + +/** +`decodeNumber(json)` returns `Some(n)` if `json` is a `number`, `None` otherwise. +*/ +let decodeNumber: t => option + +/** +`decodeObject(json)` returns `Some(o)` if `json` is an `object`, `None` otherwise. +*/ +let decodeObject: t => option> + +/** +`decodeArray(json)` returns `Some(a)` if `json` is an `array`, `None` otherwise. +*/ +let decodeArray: t => option> + +/** +`decodeBoolean(json)` returns `Some(b)` if `json` is a `boolean`, `None` otherwise. +*/ +let decodeBoolean: t => option + +/** +`decodeNull(json)` returns `Some(null)` if `json` is a `null`, `None` otherwise. +*/ +let decodeNull: t => option> + +/* ## Constructors */ + +/* + Those functions allows the construction of an arbitrary complex + JSON values. +*/ + +@val /** `null` is the singleton null JSON value. */ +external null: t = "null" + +/** `string(s)` makes a JSON string of the `string` `s`. */ +external string: string => t = "%identity" + +/** `number(n)` makes a JSON number of the `float` `n`. */ +external number: float => t = "%identity" + +/** `boolean(b)` makes a JSON boolean of the `bool` `b`. */ +external boolean: bool => t = "%identity" + +/** `object_(dict)` makes a JSON object of the `Js.Dict.t` `dict`. */ +external object_: Js_dict.t => t = "%identity" + +/** `array_(a)` makes a JSON array of the `Js.Json.t` array `a`. */ +external array: array => t = "%identity" + +/* + The functions below are specialized for specific array type which + happened to be already JSON object in the ReScript runtime. Therefore + they are more efficient (constant time rather than linear conversion). +*/ + +/** `stringArray(a)` makes a JSON array of the `string` array `a`. */ +external stringArray: array => t = "%identity" + +/** `numberArray(a)` makes a JSON array of the `float` array `a`. */ +external numberArray: array => t = "%identity" + +/** `booleanArray(a)` makes a JSON array of the `bool` array `a`. */ +external booleanArray: array => t = "%identity" + +/** `objectArray(a) makes a JSON array of the `JsDict.t` array `a`. */ +external objectArray: array> => t = "%identity" + +/* ## String conversion */ + +@val +@scope("JSON") +/** +`parseExn(s)` parses the `string` `s` into a JSON data structure. +Returns a JSON data structure. +Raises `SyntaxError` if the given string is not a valid JSON. Note: `SyntaxError` is a JavaScript exception. + +See [`parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) on MDN. + +## Examples + +```rescript +/* parse a simple JSON string */ + +let json = try Js.Json.parseExn(` "hello" `) catch { +| _ => failwith("Error parsing JSON string") +} + +switch Js.Json.classify(json) { +| Js.Json.JSONString(value) => Js.log(value) +| _ => failwith("Expected a string") +} +``` + +```rescript +/* parse a complex JSON string */ + +let getIds = s => { + let json = try Js.Json.parseExn(s) catch { + | _ => failwith("Error parsing JSON string") + } + + switch Js.Json.classify(json) { + | Js.Json.JSONObject(value) => + /* In this branch, compiler infer value : Js.Json.t Js.Dict.t */ + switch Js.Dict.get(value, "ids") { + | Some(ids) => + switch Js.Json.classify(ids) { + | Js.Json.JSONArray(ids) => /* In this branch compiler infer ids : Js.Json.t array */ + ids + | _ => failwith("Expected an array") + } + | None => failwith("Expected an `ids` property") + } + | _ => failwith("Expected an object") + } +} + +/* prints `1, 2, 3` */ +Js.log(getIds(` { "ids" : [1, 2, 3 ] } `)) +``` +*/ +external parseExn: string => t = "parse" + +@val +@scope("JSON") +/** +`stringify(json)` formats the JSON data structure as a `string`. +Returns the string representation of a given JSON data structure. + +See [`stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) on MDN. + +## Examples + +```rescript +/* Creates and stringifies a simple JS object */ + +let dict = Js.Dict.empty() +Js.Dict.set(dict, "name", Js.Json.string("John Doe")) +Js.Dict.set(dict, "age", Js.Json.number(30.0)) +Js.Dict.set(dict, "likes", Js.Json.stringArray(["ReScript", "ocaml", "js"])) + +Js.log(Js.Json.stringify(Js.Json.object_(dict))) +``` +*/ +external stringify: t => string = "stringify" + +@val +@scope("JSON") +/** +`stringifyWithSpace(json)` formats the JSON data structure as a `string`. +Returns the string representation of a given JSON data structure with spacing. + +See [`stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) on MDN. + +## Examples + +```rescript +/* Creates and stringifies a simple JS object with spacing */ + +let dict = Js.Dict.empty() +Js.Dict.set(dict, "name", Js.Json.string("John Doe")) +Js.Dict.set(dict, "age", Js.Json.number(30.0)) +Js.Dict.set(dict, "likes", Js.Json.stringArray(["ReScript", "ocaml", "js"])) + +Js.log(Js.Json.stringifyWithSpace(Js.Json.object_(dict), 2)) +``` +*/ +external stringifyWithSpace: (t, @as(json`null`) _, int) => string = "stringify" + +@val +@scope("JSON") +/** +`stringifyAny(value)` formats any value into a JSON string. + +## Examples + +```rescript +/* prints `["hello", "world"]` */ +Js.log(Js.Json.stringifyAny(["hello", "world"])) +``` +*/ +external stringifyAny: 'a => option = "stringify" + +/** +Best-effort serialization, it tries to seralize as +many objects as possible and deserialize it back + +It is unsafe in two aspects +- It may throw during parsing +- when you cast it to a specific type, it may have a type mismatch +*/ +let deserializeUnsafe: string => 'a + +/** +It will raise in such situations: +- The object can not be serlialized to a JSON +- There are cycles +- Some JS engines can not stringify deeply nested json objects +*/ +let serializeExn: 'a => string diff --git a/js/src/js_list.res b/js/src/js_list.res new file mode 100644 index 0000000..72c66b5 --- /dev/null +++ b/js/src/js_list.res @@ -0,0 +1,213 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@@warning("-3") + +type t<'a> = list<'a> + +let rec lengthAux = (len, x) => + switch x { + | list{} => len + | list{_, ...l} => lengthAux(len + 1, l) + } + +let length = l => lengthAux(0, l) + +let cons = (x, xs) => list{x, ...xs} + +let isEmpty = x => x == list{} + +let hd = x => + switch x { + | list{} => None + | list{a, ..._} => Some(a) + } + +let tl = x => + switch x { + | list{} => None + | list{_, ...l} => Some(l) + } + +let nth = (l, n) => + if n < 0 { + None + } else { + let rec nth_aux = (l, n) => + switch l { + | list{} => None + | list{a, ...l} => + if n == 0 { + Some(a) + } else { + nth_aux(l, n - 1) + } + } + nth_aux(l, n) + } + +let rec revAppend = (l1, l2) => + switch l1 { + | list{} => l2 + | list{a, ...l} => revAppend(l, list{a, ...l2}) + } + +let rev = l => revAppend(l, list{}) + +let rec mapRevAux = (f, acc, ls) => + switch ls { + | list{} => acc + | list{a, ...l} => mapRevAux(f, list{f(. a), ...acc}, l) + } + +let mapRev = (f, ls) => mapRevAux(f, list{}, ls) + +let map = (f, ls) => rev(mapRevAux(f, list{}, ls)) + +let rec iter = (f, x) => + switch x { + | list{} => () + | list{a, ...l} => + f(. a) + iter(f, l) + } + +let rec iteri = (i, f, x) => + switch x { + | list{} => () + | list{a, ...l} => + f(. i, a) + iteri(i + 1, f, l) + } + +let iteri = (f, l) => iteri(0, f, l) + +let rec foldLeft = (f, accu, l) => + switch l { + | list{} => accu + | list{a, ...l} => foldLeft(f, f(. accu, a), l) + } + +let foldRightMaxStack = 1000 + +let rec tailLoop = (f, acc, x) => + switch x { + | list{} => acc + | list{h, ...t} => tailLoop(f, f(. h, acc), t) + } + +let foldRight = (f, l, init) => { + let rec loop = (n, x) => + switch x { + | list{} => init + | list{h, ...t} => + if n < foldRightMaxStack { + f(. h, loop(n + 1, t)) + } else { + f(. h, tailLoop(f, init, rev(t))) + } + } + + loop(0, l) +} + +let rec flattenAux = (acc, lx) => + switch lx { + | list{} => rev(acc) + | list{y, ...ys} => flattenAux(revAppend(y, acc), ys) + } + +let flatten = lx => flattenAux(list{}, lx) + +let rec filterRevAux = (f, acc, xs) => + switch xs { + | list{} => acc + | list{y, ...ys} => + switch f(. y) { + | false => filterRevAux(f, acc, ys) + | true => filterRevAux(f, list{y, ...acc}, ys) + } + } + +let filter = (f, xs) => rev(filterRevAux(f, list{}, xs)) + +let rec filterMapRevAux = (f: (. 'a) => option<'b>, acc, xs) => + switch xs { + | list{} => acc + | list{y, ...ys} => + switch f(. y) { + | None => filterMapRevAux(f, acc, ys) + | Some(z) => filterMapRevAux(f, list{z, ...acc}, ys) + } + } + +let filterMap = (f, xs) => rev(filterMapRevAux(f, list{}, xs)) + +let rec countByAux = (f, acc, xs) => + switch xs { + | list{} => acc + | list{y, ...ys} => + countByAux( + f, + if f(. y) { + acc + 1 + } else { + acc + }, + ys, + ) + } + +let countBy = (f, xs) => countByAux(f, 0, xs) + +let init = (n, f) => Js_vector.toList(Js_vector.init(n, f)) + +@new external createUnsafe: int => array<'a> = "Array" + +let toVector = xs => + switch xs { + | list{} => [] + | l => + let a = createUnsafe(length(l)) + let rec fill = (i, x) => + switch x { + | list{} => a + | list{hd, ...tl} => + Js_array2.unsafe_set(a, i, hd) + fill(i + 1, tl) + } + fill(0, l) + } + +let rec equal = (cmp, xs, ys) => + switch (xs, ys) { + | (list{}, list{}) => true + | (list{x, ...xs}, list{y, ...ys}) => + if cmp(. x, y) { + equal(cmp, xs, ys) + } else { + false + } + | (_, _) => false + } diff --git a/js/src/js_list.resi b/js/src/js_list.resi new file mode 100644 index 0000000..d4c9efa --- /dev/null +++ b/js/src/js_list.resi @@ -0,0 +1,71 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@@deprecated("Use Belt.List instead") + +type t<'a> = list<'a> + +let length: t<'a> => int + +let cons: ('a, t<'a>) => t<'a> + +let isEmpty: t<'a> => bool + +let hd: t<'a> => option<'a> + +let tl: t<'a> => option> + +let nth: (t<'a>, int) => option<'a> + +let revAppend: (t<'a>, t<'a>) => t<'a> + +let rev: t<'a> => t<'a> + +let mapRev: ((. 'a) => 'b, t<'a>) => t<'b> + +let map: ((. 'a) => 'b, t<'a>) => t<'b> + +let iter: ((. 'a) => unit, t<'a>) => unit + +let iteri: ((. int, 'a) => unit, t<'a>) => unit + +/** Application order is left to right, tail recurisve */ +let foldLeft: ((. 'a, 'b) => 'a, 'a, list<'b>) => 'a + +/** Application order is right to left tail-recursive. */ +let foldRight: ((. 'a, 'b) => 'b, list<'a>, 'b) => 'b + +let flatten: t> => t<'a> + +let filter: ((. 'a) => bool, t<'a>) => t<'a> + +let filterMap: ((. 'a) => option<'b>, t<'a>) => t<'b> + +let countBy: ((. 'a) => bool, list<'a>) => int + +let init: (int, (. int) => 'a) => t<'a> + +let toVector: t<'a> => array<'a> + +let equal: ((. 'a, 'a) => bool, list<'a>, list<'a>) => bool diff --git a/js/src/js_log.js b/js/src/js_log.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_log.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_log.res b/js/src/js_log.res new file mode 100644 index 0000000..94759ec --- /dev/null +++ b/js/src/js_log.res @@ -0,0 +1,16 @@ +/** Equivalent to console.log any value */ +@val @scope("console") +external log: 'a => unit = "log" + +@val @scope("console") +external log2: 'a => 'b => unit = "log" + +@val @scope("console") +external log3: 'a => 'b => 'c => unit = "log" + +@val @scope("console") +external log4: 'a => 'b => 'c => 'd => unit = "log" + +/** A convenience function to console.log more than 4 arguments */ +@val @scope("console") @variadic +external logMany: array<'a> => unit = "log" diff --git a/js/src/js_map.res b/js/src/js_map.res new file mode 100644 index 0000000..e5e1c8e --- /dev/null +++ b/js/src/js_map.res @@ -0,0 +1,3 @@ +/*** ES6 Map API */ + +type t<'k, 'v> diff --git a/js/src/js_math.ml b/js/src/js_math.ml new file mode 100644 index 0000000..977af91 --- /dev/null +++ b/js/src/js_math.ml @@ -0,0 +1,711 @@ +(* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) + +(** +Provide utilities for JS Math. Note: The constants `_E`, `_LN10`, `_LN2`, +`_LOG10E`, `_LOG2E`, `_PI`, `_SQRT1_2`, and `_SQRT2` begin with an underscore +because ReScript variable names cannot begin with a capital letter. (Module +names begin with upper case.) +*) + +external _E : float = "E" +[@@val] [@@scope "Math"] +(** +Euler's number; ≈ 2.718281828459045. See +[`Math.E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/E) +on MDN. +*) + +external _LN2 : float = "LN2" +[@@val] [@@scope "Math"] +(** +Natural logarithm of 2; ≈ 0.6931471805599453. See +[`Math.LN2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LN2) +on MDN. +*) + +external _LN10 : float = "LN10" +[@@val] [@@scope "Math"] +(** +Natural logarithm of 10; ≈ 2.302585092994046. See +[`Math.LN10`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LN10) +on MDN. +*) + +external _LOG2E : float = "LOG2E" +[@@val] [@@scope "Math"] +(** +Base 2 logarithm of E; ≈ 1.4426950408889634. See +[`Math.LOG2E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LOG2E) +on MDN. +*) + +external _LOG10E : float = "LOG10E" +[@@val] [@@scope "Math"] +(** +Base 10 logarithm of E; ≈ 0.4342944819032518. See +[`Math.LOG10E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LOG10E) +on MDN. +*) + +external _PI : float = "PI" +[@@val] [@@scope "Math"] +(** +Pi - ratio of the circumference to the diameter of a circle; ≈ 3.141592653589793. See +[`Math.PI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI) +on MDN. +*) + +external _SQRT1_2 : float = "SQRT1_2" +[@@val] [@@scope "Math"] +(** +Square root of 1/2; ≈ 0.7071067811865476. See +[`Math.SQRT1_2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2) +on MDN. +*) + +external _SQRT2 : float = "SQRT2" +[@@val] [@@scope "Math"] +(** +Square root of 2; ≈ 1.4142135623730951. See +[`Math.SQRT2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/SQRT2) +on MDN. +*) + +external abs_int : int -> int = "abs" +[@@val] [@@scope "Math"] +(** +Absolute value for integer argument. See +[`Math.abs`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs) +on MDN. +*) + +external abs_float : float -> float = "abs" +[@@val] [@@scope "Math"] +(** +Absolute value for float argument. See +[`Math.abs`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs) +on MDN. +*) + +external acos : float -> float = "acos" +[@@val] [@@scope "Math"] +(** +Arccosine (in radians) of argument; returns `NaN` if the argument is outside +the range [-1.0, 1.0]. See +[`Math.acos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos) +on MDN. +*) + +external acosh : float -> float = "acosh" +[@@val] [@@scope "Math"] +(** +Hyperbolic arccosine (in radians) of argument; returns `NaN` if the argument +is less than 1.0. See +[`Math.acosh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh) +on MDN. +*) + +external asin : float -> float = "asin" +[@@val] [@@scope "Math"] +(** +Arcsine (in radians) of argument; returns `NaN` if the argument is outside +the range [-1.0, 1.0]. See +[`Math.asin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin) +on MDN. +*) + +external asinh : float -> float = "asinh" +[@@val] [@@scope "Math"] +(** +Hyperbolic arcsine (in radians) of argument. See +[`Math.asinh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh) +on MDN. +*) + +external atan : float -> float = "atan" +[@@val] [@@scope "Math"] +(** +Arctangent (in radians) of argument. See +[`Math.atan`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan) +on MDN. +*) + +external atanh : float -> float = "atanh" +[@@val] [@@scope "Math"] +(** +Hyperbolic arctangent (in radians) of argument; returns `NaN` if the argument +is is outside the range [-1.0, 1.0]. Returns `-Infinity` and `Infinity` for +arguments -1.0 and 1.0. See +[`Math.atanh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh) +on MDN. +*) + +external atan2 : y:float -> x:float -> unit -> float = "atan2" +[@@val] [@@scope "Math"] +(** +Returns the angle (in radians) of the quotient `y /. x`. It is also the angle +between the *x*-axis and point (*x*, *y*). See +[`Math.atan2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2) +on MDN. + +## Examples + +```rescript +Js.Math.atan2(~y=0.0, ~x=10.0, ()) == 0.0 +Js.Math.atan2(~x=5.0, ~y=5.0, ()) == Js.Math._PI /. 4.0 +Js.Math.atan2(~x=-5.0, ~y=5.0, ()) +Js.Math.atan2(~x=-5.0, ~y=5.0, ()) == 3.0 *. Js.Math._PI /. 4.0 +Js.Math.atan2(~x=-0.0, ~y=-5.0, ()) == -.Js.Math._PI /. 2.0 +``` +*) + +external cbrt : float -> float = "cbrt" +[@@val] [@@scope "Math"] +(** +Cube root. See +[`Math.cbrt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt) +on MDN +*) + +external unsafe_ceil_int : float -> int = "ceil" +[@@val] [@@scope "Math"] +(** +Returns the smallest integer greater than or equal to the argument. This +function may return values not representable by `int`, whose range is +-2147483648 to 2147483647. This is because, in JavaScript, there are only +64-bit floating point numbers, which can represent integers in the range +±(253-1) exactly. See +[`Math.ceil`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil) +on MDN. + +## Examples + +```rescript +Js.Math.unsafe_ceil_int(3.1) == 4 +Js.Math.unsafe_ceil_int(3.0) == 3 +Js.Math.unsafe_ceil_int(-3.1) == -3 +Js.Math.unsafe_ceil_int(1.0e15) // result is outside range of int datatype +``` +*) + +let unsafe_ceil = unsafe_ceil_int +[@@deprecated "Please use `unsafe_ceil_int` instead"] + +(** +Returns the smallest `int` greater than or equal to the argument; the result +is pinned to the range of the `int` data type: -2147483648 to 2147483647. See +[`Math.ceil`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil) +on MDN. + +## Examples + +```rescript +Js.Math.ceil_int(3.1) == 4 +Js.Math.ceil_int(3.0) == 3 +Js.Math.ceil_int(-3.1) == -3 +Js.Math.ceil_int(-1.0e15) == -2147483648 +Js.Math.ceil_int(1.0e15) == 2147483647 +``` +*) +let ceil_int (f : float) : int = + if f > Js_int.toFloat Js_int.max then Js_int.max + else if f < Js_int.toFloat Js_int.min then Js_int.min + else unsafe_ceil_int f + +let ceil = ceil_int [@@deprecated "Please use `ceil_int` instead"] + +external ceil_float : float -> float = "ceil" +[@@val] [@@scope "Math"] +(** +Returns the smallest integral value greater than or equal to the argument. +The result is a `float` and is not restricted to the `int` data type range. +See +[`Math.ceil`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil) +on MDN. + +## Examples + +```rescript +Js.Math.ceil_float(3.1) == 4.0 +Js.Math.ceil_float(3.0) == 3.0 +Js.Math.ceil_float(-3.1) == -3.0 +Js.Math.ceil_float(2_150_000_000.3) == 2_150_000_001.0 +``` +*) + +external clz32 : int -> int = "clz32" +[@@val] [@@scope "Math"] +(** +Number of leading zero bits of the argument's 32 bit int representation. See +[`Math.clz32`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32) +on MDN. + +## Examples + +```rescript +Js.Math.clz32(0) == 32 +Js.Math.clz32(-1) == 0 +Js.Math.clz32(255) == 24 +``` +*) + +external cos : float -> float = "cos" +[@@val] [@@scope "Math"] +(** +Cosine of argument, which must be specified in radians. See +[`Math.cos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos) +on MDN. +*) + +external cosh : float -> float = "cosh" +[@@val] [@@scope "Math"] +(** +Hyperbolic cosine of argument, which must be specified in radians. See +[`Math.cosh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh) +on MDN. +*) + +external exp : float -> float = "exp" +[@@val] [@@scope "Math"] +(** +Natural exponentional; returns *e* (the base of natural logarithms) to the +power of the given argument. See +[`Math.exp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp) +on MDN. +*) + +external expm1 : float -> float = "expm1" +[@@val] [@@scope "Math"] +(** +Returns *e* (the base of natural logarithms) to the power of the given +argument minus 1. See +[`Math.expm1`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1) +on MDN. +*) + +external unsafe_floor_int : float -> int = "floor" +[@@val] [@@scope "Math"] +(** +Returns the largest integer less than or equal to the argument. This function +may return values not representable by `int`, whose range is -2147483648 to +2147483647. This is because, in JavaScript, there are only 64-bit floating +point numbers, which can represent integers in the range +±(253-1) exactly. See +[`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) +on MDN. + +## Examples + +```rescript +Js.Math.unsafe_floor_int(3.7) == 3 +Js.Math.unsafe_floor_int(3.0) == 3 +Js.Math.unsafe_floor_int(-3.7) == -4 +Js.Math.unsafe_floor_int(1.0e15) // result is outside range of int datatype +``` +*) + +let unsafe_floor = unsafe_floor_int +[@@deprecated "Please use `unsafe_floor_int` instead"] + +(** +Returns the largest `int` less than or equal to the argument; the result is +pinned to the range of the `int` data type: -2147483648 to 2147483647. See +[`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) +on MDN. + +## Examples + +```rescript +Js.Math.floor_int(3.7) == 3 +Js.Math.floor_int(3.0) == 3 +Js.Math.floor_int(-3.1) == -4 +Js.Math.floor_int(-1.0e15) == -2147483648 +Js.Math.floor_int(1.0e15) == 2147483647 +``` +*) +let floor_int f = + if f > Js_int.toFloat Js_int.max then Js_int.max + else if f < Js_int.toFloat Js_int.min then Js_int.min + else unsafe_floor f + +let floor = floor_int [@@deprecated "Please use `floor_int` instead"] + +external floor_float : float -> float = "floor" +[@@val] [@@scope "Math"] +(** +Returns the largest integral value less than or equal to the argument. The +result is a `float` and is not restricted to the `int` data type range. See +[`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) +on MDN. + +## Examples + +```rescript +Js.Math.floor_float(3.7) == 3.0 +Js.Math.floor_float(3.0) == 3.0 +Js.Math.floor_float(-3.1) == -4.0 +Js.Math.floor_float(2_150_000_000.3) == 2_150_000_000.0 +``` +*) + +external fround : float -> float = "fround" +[@@val] [@@scope "Math"] +(** +Round to nearest single precision float. See +[`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround) +on MDN. + +## Examples + +```rescript +Js.Math.fround(5.5) == 5.5 +Js.Math.fround(5.05) == 5.050000190734863 +``` +*) + +external hypot : float -> float -> float = "hypot" +[@@val] [@@scope "Math"] +(** +Returns the square root of the sum of squares of its two arguments (the +Pythagorean formula). See +[`Math.hypot`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot) +on MDN. +*) + +external hypotMany : float array -> float = "hypot" +[@@val] [@@variadic] [@@scope "Math"] +(** +Returns the square root of the sum of squares of the numbers in the array +argument (generalized Pythagorean equation). Using an array allows you to +have more than two items. See +[`Math.hypot`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot) +on MDN. + +## Examples + +```rescript +Js.Math.hypotMany([3.0, 4.0, 12.0]) == 13.0 +``` +*) + +external imul : int -> int -> int = "imul" +[@@val] [@@scope "Math"] +(** +32-bit integer multiplication. Use this only when you need to optimize +performance of multiplication of numbers stored as 32-bit integers. See +[`Math.imul`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul) +on MDN. +*) + +external log : float -> float = "log" +[@@val] [@@scope "Math"] +(** +Returns the natural logarithm of its argument; this is the number *x* such +that *e**x* equals the argument. Returns `NaN` for negative +arguments. See +[`Math.log`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log) +on MDN. + +## Examples + +```rescript +Js.Math.log(Js.Math._E) == 1.0 +Js.Math.log(100.0) == 4.605170185988092 +``` +*) + +external log1p : float -> float = "log1p" +[@@val] [@@scope "Math"] +(** +Returns the natural logarithm of one plus the argument. Returns `NaN` for +arguments less than -1. See +[`Math.log1p`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p) +on MDN. + +## Examples + +```rescript +Js.Math.log1p(Js.Math._E -. 1.0) == 1.0 +Js.Math.log1p(99.0) == 4.605170185988092 +``` +*) + +external log10 : float -> float = "log10" +[@@val] [@@scope "Math"] +(** +Returns the base 10 logarithm of its argument. Returns `NaN` for negative +arguments. See +[`Math.log10`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10) +on MDN. + +## Examples + +```rescript +Js.Math.log10(1000.0) == 3.0 +Js.Math.log10(0.01) == -2.0 +Js.Math.log10(Js.Math.sqrt(10.0)) == 0.5 +``` +*) + +external log2 : float -> float = "log2" +[@@val] [@@scope "Math"] +(** +Returns the base 2 logarithm of its argument. Returns `NaN` for negative +arguments. See +[`Math.log2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2) +on MDN. + +## Examples + +```rescript +Js.Math.log2(512.0) == 9.0 +Js.Math.log2(0.125) == -3.0 +Js.Math.log2(Js.Math._SQRT2) == 0.5000000000000001 // due to precision +``` +*) + +external max_int : int -> int -> int = "max" +[@@val] [@@scope "Math"] +(** +Returns the maximum of its two integer arguments. See +[`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) +on MDN. +*) + +external maxMany_int : int array -> int = "max" +[@@val] [@@variadic] [@@scope "Math"] +(** +Returns the maximum of the integers in the given array. See +[`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) +on MDN. +*) + +external max_float : float -> float -> float = "max" +[@@val] [@@scope "Math"] +(** +Returns the maximum of its two floating point arguments. See +[`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) +on MDN. +*) + +external maxMany_float : float array -> float = "max" +[@@val] [@@variadic] [@@scope "Math"] +(** +Returns the maximum of the floating point values in the given array. See +[`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) +on MDN. +*) + +external min_int : int -> int -> int = "min" +[@@val] [@@scope "Math"] +(** +Returns the minimum of its two integer arguments. See +[`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) +on MDN. +*) + +external minMany_int : int array -> int = "min" +[@@val] [@@variadic] [@@scope "Math"] +(** +Returns the minimum of the integers in the given array. See +[`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) +on MDN. +*) + +external min_float : float -> float -> float = "min" +[@@val] [@@scope "Math"] +(** +Returns the minimum of its two floating point arguments. See +[`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) +on MDN. +*) + +external minMany_float : float array -> float = "min" +[@@val] [@@variadic] [@@scope "Math"] +(** +Returns the minimum of the floating point values in the given array. See +[`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) +on MDN. +*) + +external pow_int : base:int -> exp:int -> int = "pow" +[@@val] +[@@scope "Math"] +[@@deprecated "use `pow_float` instead, the return type may be not int"] +(** +Raises the given base to the given exponent. (Arguments and result are +integers.) See +[`Math.pow`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow) +on MDN. + +## Examples + +```rescript +Js.Math.pow_int(~base=3, ~exp=4) == 81 +``` +*) + +external pow_float : base:float -> exp:float -> float = "pow" +[@@val] [@@scope "Math"] +(** +Raises the given base to the given exponent. (Arguments and result are +floats.) Returns `NaN` if the result would be imaginary. See +[`Math.pow`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow) +on MDN. + +## Examples + +```rescript +Js.Math.pow_float(~base=3.0, ~exp=4.0) == 81.0 +Js.Math.pow_float(~base=4.0, ~exp=-2.0) == 0.0625 +Js.Math.pow_float(~base=625.0, ~exp=0.5) == 25.0 +Js.Math.pow_float(~base=625.0, ~exp=-0.5) == 0.04 +Js.Float.isNaN(Js.Math.pow_float(~base=-2.0, ~exp=0.5)) == true +``` +*) + +external random : unit -> float = "random" +[@@val] [@@scope "Math"] +(** +Returns a random number in the half-closed interval [0,1). See +[`Math.random`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) +on MDN. +*) + +(** +A call to `random_int(minVal, maxVal)` returns a random number in the +half-closed interval [minVal, maxVal). See +[`Math.random`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) +on MDN. +*) +let random_int min max = floor (random () *. Js_int.toFloat (max - min)) + min + +external unsafe_round : float -> int = "round" +[@@val] [@@scope "Math"] +(** +Rounds its argument to nearest integer. For numbers with a fractional portion +of exactly 0.5, the argument is rounded to the next integer in the direction +of positive infinity. This function may return values not representable by +`int`, whose range is -2147483648 to 2147483647. This is because, in +JavaScript, there are only 64-bit floating point numbers, which can represent +integers in the range ±(253-1) exactly. See +[`Math.round`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round) +on MDN. + +## Examples + +```rescript +Js.Math.unsafe_round(3.7) == 4 +Js.Math.unsafe_round(-3.5) == -3 +Js.Math.unsafe_round(2_150_000_000_000.3) // out of range for int +``` +*) + +external round : float -> float = "round" +[@@val] [@@scope "Math"] +(** +Rounds to nearest integral value (expressed as a float). See +[`Math.round`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round) +on MDN. +*) + +external sign_int : int -> int = "sign" +[@@val] [@@scope "Math"] +(** +Returns the sign of its integer argument: -1 if negative, 0 if zero, 1 if +positive. See +[`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) +on MDN. +*) + +external sign_float : float -> float = "sign" +[@@val] [@@scope "Math"] +(** +Returns the sign of its float argument: -1.0 if negative, 0.0 if zero, 1.0 if +positive. See +[`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) +on MDN. +*) + +external sin : float -> float = "sin" +[@@val] [@@scope "Math"] +(** +Sine of argument, which must be specified in radians. See +[`Math.sin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin) +on MDN. +*) + +external sinh : float -> float = "sinh" +[@@val] [@@scope "Math"] +(** +Hyperbolic sine of argument, which must be specified in radians. See +[`Math.sinh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh) +on MDN. +*) + +external sqrt : float -> float = "sqrt" +[@@val] [@@scope "Math"] +(** +Square root. If the argument is negative, this function returns `NaN`. See +[`Math.sqrt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt) +on MDN. +*) + +external tan : float -> float = "tan" +[@@val] [@@scope "Math"] +(** +Tangent of argument, which must be specified in radians. Returns `NaN` if the +argument is positive infinity or negative infinity. See +[`Math.cos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos) +on MDN. +*) + +external tanh : float -> float = "tanh" +[@@val] [@@scope "Math"] +(** +Hyperbolic tangent of argument, which must be specified in radians. See +[`Math.tanh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh) +on MDN. +*) + +external unsafe_trunc : float -> int = "trunc" +[@@val] [@@scope "Math"] +(** +Truncates its argument; i.e., removes fractional digits. This function may +return values not representable by `int`, whose range is -2147483648 to +2147483647. This is because, in JavaScript, there are only 64-bit floating +point numbers, which can represent integers in the range ±(253-1) +exactly. See +[`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) +on MDN. +*) + +external trunc : float -> float = "trunc" +[@@val] [@@scope "Math"] +(** +Truncates its argument; i.e., removes fractional digits. See +[`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) +on MDN. +*) diff --git a/js/src/js_null.js b/js/src/js_null.js new file mode 100644 index 0000000..7612fcf --- /dev/null +++ b/js/src/js_null.js @@ -0,0 +1,51 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Js_exn from "./js_exn.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; + +function test(x) { + return x === null; +} + +function getExn(f) { + if (f !== null) { + return f; + } else { + return Js_exn.raiseError("Js.Null.getExn"); + } +} + +function bind(x, f) { + if (x !== null) { + return f(x); + } else { + return null; + } +} + +function iter(x, f) { + if (x !== null) { + return f(x); + } + +} + +function fromOption(x) { + if (x !== undefined) { + return Caml_option.valFromOption(x); + } else { + return null; + } +} + +var from_opt = fromOption; + +export { + test , + getExn , + bind , + iter , + fromOption , + from_opt , +} +/* No side effect */ diff --git a/js/src/js_null.res b/js/src/js_null.res new file mode 100644 index 0000000..b806173 --- /dev/null +++ b/js/src/js_null.res @@ -0,0 +1,67 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provides functionality for dealing with the `'a Js.null` type */ + +@unboxed +type t<+'a> = Runtime_types.null<'a> = + | Value('a) + | @as(null) Null + +/** + The same as empty in `Js.Null`. Compiles to `null`. +*/ +external null: t<'a> = "#null" +external to_opt: t<'a> => option<'a> = "#null_to_opt" +external toOption: t<'a> => option<'a> = "#null_to_opt" +external return: 'a => t<'a> = "%identity" +let test: t<'a> => bool = x => x == null +external empty: t<'a> = "#null" +external getUnsafe: t<'a> => 'a = "%identity" + +let getExn = f => + switch toOption(f) { + | None => Js_exn.raiseError("Js.Null.getExn") + | Some(x) => x + } + +let bind = (x, f) => + switch toOption(x) { + | None => empty + | Some(x) => return(f(x)) + } + +let iter = (x, f) => + switch toOption(x) { + | None => () + | Some(x) => f(x) + } + +let fromOption = x => + switch x { + | None => empty + | Some(x) => return(x) + } + +let from_opt = fromOption diff --git a/js/src/js_null.resi b/js/src/js_null.resi new file mode 100644 index 0000000..e93b927 --- /dev/null +++ b/js/src/js_null.resi @@ -0,0 +1,90 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provides functionality for dealing with the `Js.null<'a>` type */ + +@unboxed /** Local alias for `Js.null<'a>` */ +type t<+'a> = Runtime_types.null<'a> = + | Value('a) + | @as(null) Null + +/** Constructs a value of `Js.null<'a>` containing a value of `'a`. */ +external return: 'a => t<'a> = "%identity" + +@deprecated("Use = Js.null directly ") +/** Returns `true` if the given value is empty (`null`), `false` otherwise. */ +let test: t<'a> => bool + +/** The empty value, `null` */ +external empty: t<'a> = "#null" + +external getUnsafe: t<'a> => 'a = "%identity" +let getExn: t<'a> => 'a + +/** +Maps the contained value using the given function. + +If `Js.null<'a>` contains a value, that value is unwrapped, mapped to a `'b` +using the given function `'a => 'b`, then wrapped back up and returned as +`Js.null<'b>`. + +## Examples + +```rescript +let maybeGreetWorld = (maybeGreeting: Js.null) => + Js.Null.bind(maybeGreeting, (. greeting) => greeting ++ " world!") +``` +*/ +let bind: (t<'a>, 'a => 'b) => t<'b> + +/** +Iterates over the contained value with the given function. +If `Js.null<'a>` contains a value, that value is unwrapped and applied to the given function. + +## Examples + +```rescript +let maybeSay = (maybeMessage: Js.null) => + Js.Null.iter(maybeMessage, (. message) => Js.log(message)) +``` +*/ +let iter: (t<'a>, 'a => unit) => unit + +/** +Maps `option<'a>` to `Js.null<'a>`. +`Some(a)` => `a` +`None` => `empty` +*/ +let fromOption: option<'a> => t<'a> + +@deprecated("Use fromOption instead") let from_opt: option<'a> => t<'a> + +/** +Maps `Js.null<'a>` to `option<'a>`. +`a` => `Some(a)` +`empty` => `None` +*/ +external toOption: t<'a> => option<'a> = "#null_to_opt" + +@deprecated("Use toOption instead") external to_opt: t<'a> => option<'a> = "#null_to_opt" diff --git a/js/src/js_null_undefined.js b/js/src/js_null_undefined.js new file mode 100644 index 0000000..74fe942 --- /dev/null +++ b/js/src/js_null_undefined.js @@ -0,0 +1,35 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Caml_option from "rescript/lib/es6/caml_option.js"; + +function bind(x, f) { + if (x == null) { + return x; + } else { + return f(x); + } +} + +function iter(x, f) { + if (!(x == null)) { + return f(x); + } + +} + +function fromOption(x) { + if (x !== undefined) { + return Caml_option.valFromOption(x); + } + +} + +var from_opt = fromOption; + +export { + bind , + iter , + fromOption , + from_opt , +} +/* No side effect */ diff --git a/js/src/js_null_undefined.res b/js/src/js_null_undefined.res new file mode 100644 index 0000000..0e02084 --- /dev/null +++ b/js/src/js_null_undefined.res @@ -0,0 +1,58 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Contains functionality for dealing with values that can be both `null` and `undefined` */ + +@unboxed +type t<+'a> = Js_nullable.t<'a> = + | Value('a) + | @as(null) Null + | @as(undefined) Undefined + +external toOption: t<'a> => option<'a> = "#nullable_to_opt" +external to_opt: t<'a> => option<'a> = "#nullable_to_opt" +external return: 'a => t<'a> = "%identity" +external isNullable: t<'a> => bool = "#is_nullable" +external null: t<'a> = "#null" +external undefined: t<'a> = "#undefined" + +let bind = (x, f) => + switch to_opt(x) { + | None => (Obj.magic((x: t<'a>)): t<'b>) + | Some(x) => return(f(. x)) + } + +let iter = (x, f) => + switch to_opt(x) { + | None => () + | Some(x) => f(. x) + } + +let fromOption = x => + switch x { + | None => undefined + | Some(x) => return(x) + } + +let from_opt = fromOption diff --git a/js/src/js_null_undefined.resi b/js/src/js_null_undefined.resi new file mode 100644 index 0000000..93188be --- /dev/null +++ b/js/src/js_null_undefined.resi @@ -0,0 +1,94 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Contains functionality for dealing with values that can be both `null` and `undefined` +*/ + +/** Local alias for `Js.null_undefined<'a>`. */ +@unboxed +type t<+'a> = Js_nullable.t<'a> = + | Value('a) + | @as(null) Null + | @as(undefined) Undefined + +/** Constructs a value of `Js.null_undefined<'a>` containing a value of `'a`. */ +external return: 'a => t<'a> = "%identity" + +/** Returns `true` if the given value is null or undefined, `false` otherwise. */ +external isNullable: t<'a> => bool = "#is_nullable" + +/** The null value of type `Js.null_undefined<'a>`. */ +external null: t<'a> = "#null" + +/** The undefined value of type `Js.null_undefined<'a>`. */ +external undefined: t<'a> = "#undefined" + +/** +Maps the contained value using the given function. + +If `Js.null_undefined<'a>` contains a value, that value is unwrapped, mapped to +a `'b` using the given function `a' => 'b`, then wrapped back up and returned +as `Js.null_undefined<'b>`. + +## Examples + +```rescript +let maybeGreetWorld = (maybeGreeting: Js.null_undefined) => + Js.Null_undefined.bind(maybeGreeting, (. greeting) => greeting ++ " world!") +``` +*/ +let bind: (t<'a>, (. 'a) => 'b) => t<'b> + +/** +Iterates over the contained value with the given function. +If `Js.null_undefined<'a>` contains a value, that value is unwrapped and applied to the given function. + +## Examples + +```rescript +let maybeSay = (maybeMessage: Js.null_undefined) => + Js.Null_undefined.iter(maybeMessage, (. message) => Js.log(message)) +``` +*/ +let iter: (t<'a>, (. 'a) => unit) => unit + +/** +Maps `option<'a>` to `Js.null_undefined<'a>`. +`Some(a)` => `a` +`None` => `undefined` +*/ +let fromOption: option<'a> => t<'a> + +@deprecated("Use fromOption instead") let from_opt: option<'a> => t<'a> + +/** +Maps `Js.null_undefined<'a>` to `option<'a>`. +`a` => `Some(a)` +`undefined` => `None` +`null` => `None` +*/ +external toOption: t<'a> => option<'a> = "#nullable_to_opt" + +@deprecated("Use toOption instead") external to_opt: t<'a> => option<'a> = "#nullable_to_opt" diff --git a/js/src/js_nullable.js b/js/src/js_nullable.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_nullable.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_nullable.res b/js/src/js_nullable.res new file mode 100644 index 0000000..df73ecd --- /dev/null +++ b/js/src/js_nullable.res @@ -0,0 +1,5 @@ +@unboxed +type t<+'a> = Runtime_types.nullable<'a> = + | Value('a) + | @as(null) Null + | @as(undefined) Undefined diff --git a/js/src/js_obj.res b/js/src/js_obj.res new file mode 100644 index 0000000..75d75d7 --- /dev/null +++ b/js/src/js_obj.res @@ -0,0 +1,103 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provides functions for inspecting and manipulating native JavaScript objects +*/ + +@obj /** `empty()` returns the empty object `{}` */ +external empty: unit => {..} = "" + +@val +/** +`assign(target, source)` copies properties from source to target. +Properties in `target` will be overwritten by properties in `source` if they have the same key. +Returns `target`. + +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + +## Examples + +```rescript +/* Copy an object */ + +let obj = {"a": 1} + +let copy = Js.Obj.assign(Js.Obj.empty(), obj) + +/* prints "{ a: 1 }" */ +Js.log(copy) + +/* Merge objects with same properties */ + +let target = {"a": 1, "b": 1} +let source = {"b": 2} + +let obj = Js.Obj.assign(target, source) + +/* prints "{ a: 1, b: 2 }" */ +Js.log(obj) + +/* prints "{ a: 1, b: 2 }", target is modified */ +Js.log(target) +``` +*/ +external assign: ({..}, {..}) => {..} = "Object.assign" + +/* TODO: + + Should we map this API as directly as possible, provide some abstractions, or deliberately nerf it? + + "static": + - Object.create + - Object.defineProperty + - Object.defineProperties + - Object.entries - experimental + - Object.getOwnPropertyDescriptor + - Object.getOwnPropertyDescriptors + - Object.getOwnPropertyNames + - Object.getOwnPropertySymbols + - Object.getPrototypeOf + - Object.isExtensible + - Object.isFrozen + - Object.isSealed + - Object.preventExtension + - Object.seal + - Object.setPrototypeOf + - Object.values - experimental + + send: + - hasOwnProperty + - isPrototypeOf + - propertyIsEnumerable + - toLocaleString + - toString + + Put directly on Js? + - Object.is +*/ + +/** `keys(obj)` returns an `array` of the keys of `obj`'s own enumerable properties. */ +@val +external keys: {..} => array = "Object.keys" diff --git a/js/src/js_option.res b/js/src/js_option.res new file mode 100644 index 0000000..d18e815 --- /dev/null +++ b/js/src/js_option.res @@ -0,0 +1,232 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provide utilities for handling `option`. */ + +/** +`Js.Option.t` is an alias for `option` +*/ +type t<'a> = option<'a> + +/** +Wraps the given value in `Some()` + +## Examples + +```rescript +Js.Option.some(1066) == Some(1066) +``` +*/ +let some = x => Some(x) + +/** +Returns `true` if the argument is `Some(value)`; `false` if the argument is +`None`. +*/ +let isSome = x => + switch x { + | None => false + | Some(_) => true + } + +/** +The first argument to `isSomeValue` is an uncurried function `eq()` that +takes two arguments and returns `true` if they are considered to be equal. It +is used to compare a plain value `v1`(the second argument) with an `option` +value. If the `option` value is `None`, `isSomeValue()` returns `false`; if +the third argument is `Some(v2)`, `isSomeValue()` returns the result of +calling `eq(v1, v2)`. + +## Examples + +```rescript +let clockEqual = (. a, b) => mod(a, 12) == mod(b, 12) +Js.Option.isSomeValue(clockEqual, 3, Some(15)) == true +Js.Option.isSomeValue(clockEqual, 3, Some(4)) == false +Js.Option.isSomeValue(clockEqual, 3, None) == false +``` +*/ +let isSomeValue = (eq, v, x) => + switch x { + | None => false + | Some(x) => eq(. v, x) + } + +/** Returns `true` if the argument is `None`; `false` otherwise. */ +let isNone = x => + switch x { + | None => true + | Some(_) => false + } + +/** +If the argument to `getExn()` is of the form `Some(value)`, returns `value`. +If given `None`, it throws a `getExn` exception. +*/ +let getExn = x => + switch x { + | None => Js_exn.raiseError("getExn") + | Some(x) => x + } + +/** +The first argument to `equal` is an uncurried function `eq()` that takes two +arguments and returns `true` if they are considered to be equal. The second +and third arguments are `option` values. + +If the second and third arguments are of the form: + +* `Some(v1)` and `Some(v2)`: returns `eq(v1, v2)` +* `Some(v1)` and `None`: returns `false` +* `None` and `Some(v2)`: returns `false` +* `None` and `None`: returns `true` + +## Examples + +```rescript +let clockEqual = (. a, b) => mod(a, 12) == mod(b, 12) +Js.Option.equal(clockEqual, Some(3), Some(15)) == true +Js.Option.equal(clockEqual, Some(3), Some(16)) == false +Js.Option.equal(clockEqual, Some(3), None) == false +Js.Option.equal(clockEqual, None, Some(15)) == false +Js.Option.equal(clockEqual, None, None) == true +``` +*/ +let equal = (eq, a, b) => + switch a { + | None => b == None + | Some(x) => + switch b { + | None => false + | Some(y) => eq(. x, y) + } + } + +/** +The first argument to `andThen()` is an uncurried function `f()` that takes a +plain value and returns an `option` result. The second argument is an +`option` value. If the second argument is `None`, the return value is `None`. +If the second argument is `Some(v)`, the return value is `f(v)`. + +## Examples + +```rescript +let reciprocal = (. x) => x == 0 ? None : Some(1.0 /. Belt.Int.toFloat(x)) +Js.Option.andThen(reciprocal, Some(5)) == Some(0.2) +Js.Option.andThen(reciprocal, Some(0)) == None +Js.Option.andThen(reciprocal, None) == None +``` +*/ +let andThen = (f, x) => + switch x { + | None => None + | Some(x) => f(. x) + } + +/** +The first argument to `map()` is an uncurried function `f()` that takes a +plain value and returns a plain result. The second argument is an `option` +value. If it is of the form `Some(v)`, `map()` returns `Some(f(v))`; if it is +`None`, the return value is `None`, and function `f()` is not called. + +## Examples + +```rescript +let square = (. x) => x * x +Js.Option.map(square, Some(3)) == Some(9) +Js.Option.map(square, None) == None +``` +*/ +let map = (f, x) => + switch x { + | None => None + | Some(x) => Some(f(. x)) + } + +/** +The first argument to `getWithDefault()` is a default value. If the second +argument is of the form `Some(v)`, `getWithDefault()` returns `v`; if the +second argument is `None`, the return value is the default value. + +## Examples + +```rescript +Js.Option.getWithDefault(1066, Some(15)) == 15 +Js.Option.getWithDefault(1066, None) == 1066 +``` +*/ +let getWithDefault = (a, x) => + switch x { + | None => a + | Some(x) => x + } + +/** **See:** [getWithDefault](#getWithDefault) */ +let default = getWithDefault + +/** +The first argument to `filter()` is an uncurried function that takes a plain +value and returns a boolean. The second argument is an `option` value. + +If the second argument is of the form `Some(v)` and `f(v)` is `true`, +the return value is `Some(v)`. Otherwise, the return value is `None`. + +## Examples + +```rescript +let isEven = (. x) => mod(x, 2) == 0 +Js.Option.filter(isEven, Some(2)) == Some(2) +Js.Option.filter(isEven, Some(3)) == None +Js.Option.filter(isEven, None) == None +``` +*/ +let filter = (f, x) => + switch x { + | None => None + | Some(x) => + if f(. x) { + Some(x) + } else { + None + } + } + +/** +The `firstSome()` function takes two `option` values; if the first is of the form `Some(v1)`, that is the return value. Otherwise, `firstSome()` returns the second value. + +## Examples + +```rescript +Js.Option.firstSome(Some("one"), Some("two")) == Some("one") +Js.Option.firstSome(Some("one"), None) == Some("one") +Js.Option.firstSome(None, Some("two")) == Some("two") +Js.Option.firstSome(None, None) == None +``` +*/ +let firstSome = (a, b) => + switch (a, b) { + | (Some(_), _) => a + | (None, Some(_)) => b + | (None, None) => None + } diff --git a/js/src/js_option.resi b/js/src/js_option.resi new file mode 100644 index 0000000..dca50e3 --- /dev/null +++ b/js/src/js_option.resi @@ -0,0 +1,50 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +type t<'a> = option<'a> + +let some: 'a => option<'a> + +let isSome: option<'a> => bool + +let isSomeValue: ((. 'a, 'a) => bool, 'a, option<'a>) => bool + +let isNone: option<'a> => bool + +let getExn: option<'a> => 'a + +let equal: ((. 'a, 'b) => bool, option<'a>, option<'b>) => bool + +let andThen: ((. 'a) => option<'b>, option<'a>) => option<'b> + +let map: ((. 'a) => 'b, option<'a>) => option<'b> + +let getWithDefault: ('a, option<'a>) => 'a + +@deprecated("Use `getWithDefault` instead since default has special meaning in ES module") +let default: ('a, option<'a>) => 'a + +let filter: ((. 'a) => bool, option<'a>) => option<'a> + +let firstSome: (option<'a>, option<'a>) => option<'a> diff --git a/js/src/js_promise.js b/js/src/js_promise.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_promise.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_promise.res b/js/src/js_promise.res new file mode 100644 index 0000000..7268e1e --- /dev/null +++ b/js/src/js_promise.res @@ -0,0 +1,106 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Deprecation note: These bindings are pretty outdated and cannot be used properly +with the `->` operator. + +More details on proper Promise usage can be found here: +https://rescript-lang.org/docs/manual/latest/promise#promise-legacy +*/ + +@@warning("-103") + +type t<+'a> = promise<'a> +type error = Js_promise2.error + +/* +## Examples + +```rescript +type error +``` +*/ + +@new +external make: ((@uncurry ~resolve: (. 'a) => unit, ~reject: (. exn) => unit) => unit) => promise< + 'a, +> = "Promise" + +/* `make (fun resolve reject -> .. )` */ +@val @scope("Promise") external resolve: 'a => promise<'a> = "resolve" +@val @scope("Promise") external reject: exn => promise<'a> = "reject" + +@val @scope("Promise") external all: array> => promise> = "all" + +@val @scope("Promise") external all2: ((promise<'a0>, promise<'a1>)) => promise<('a0, 'a1)> = "all" + +@val @scope("Promise") +external all3: ((promise<'a0>, promise<'a1>, promise<'a2>)) => promise<('a0, 'a1, 'a2)> = "all" + +@val @scope("Promise") +external all4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => promise<( + 'a0, + 'a1, + 'a2, + 'a3, +)> = "all" + +@val @scope("Promise") +external all5: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>)) => promise<( + 'a0, + 'a1, + 'a2, + 'a3, + 'a4, +)> = "all" + +@val @scope("Promise") +external all6: ( + (promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>, promise<'a5>) +) => promise<('a0, 'a1, 'a2, 'a3, 'a4, 'a5)> = "all" + +@val @scope("Promise") external race: array> => promise<'a> = "race" + +@bs.send.pipe(: promise<'a>) external then_: (@uncurry ('a => promise<'b>)) => promise<'b> = "then" + +@bs.send.pipe(: promise<'a>) +external catch: (@uncurry (error => promise<'a>)) => promise<'a> = "catch" +/* ` p|> catch handler` + Note in JS the returned promise type is actually runtime dependent, + if promise is rejected, it will pick the `handler` otherwise the original promise, + to make it strict we enforce reject handler + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch +*/ + +external unsafe_async: 'a => promise<'a> = "%identity" +external unsafe_await: promise<'a> => 'a = "?await" + +/* +let errorAsExn (x : error) (e : (exn ->'a option))= + if Caml_exceptions.isCamlExceptionOrOpenVariant (Obj.magic x ) then + e (Obj.magic x) + else None +[%bs.error? ] +*/ diff --git a/js/src/js_promise2.js b/js/src/js_promise2.js new file mode 100644 index 0000000..5a5c158 --- /dev/null +++ b/js/src/js_promise2.js @@ -0,0 +1,16 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var then = (function(p, cont) { + return Promise.resolve(p).then(cont) + }); + +var $$catch = (function(p, cont) { + return Promise.resolve(p).catch(cont) + }); + +export { + then , + $$catch , +} +/* No side effect */ diff --git a/js/src/js_promise2.res b/js/src/js_promise2.res new file mode 100644 index 0000000..4fa6778 --- /dev/null +++ b/js/src/js_promise2.res @@ -0,0 +1,58 @@ +type t<+'a> = promise<'a> +type error + +/** Type-safe t-first then */ +let then: (promise<'a>, 'a => promise<'b>) => promise<'b> = %raw(` + function(p, cont) { + return Promise.resolve(p).then(cont) + } + `) + +/** Type-safe t-first catch */ +let catch: (promise<'a>, error => promise<'a>) => promise<'a> = %raw(` + function(p, cont) { + return Promise.resolve(p).catch(cont) + } + `) + +@new +external make: ((@uncurry ~resolve: (. 'a) => unit, ~reject: (. exn) => unit) => unit) => promise< + 'a, +> = "Promise" + +@val @scope("Promise") external resolve: 'a => promise<'a> = "resolve" +@val @scope("Promise") external reject: exn => promise<'a> = "reject" + +@val @scope("Promise") external all: array> => promise> = "all" + +@val @scope("Promise") external all2: ((promise<'a0>, promise<'a1>)) => promise<('a0, 'a1)> = "all" + +@val @scope("Promise") +external all3: ((promise<'a0>, promise<'a1>, promise<'a2>)) => promise<('a0, 'a1, 'a2)> = "all" + +@val @scope("Promise") +external all4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => promise<( + 'a0, + 'a1, + 'a2, + 'a3, +)> = "all" + +@val @scope("Promise") +external all5: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>)) => promise<( + 'a0, + 'a1, + 'a2, + 'a3, + 'a4, +)> = "all" + +@val @scope("Promise") +external all6: ( + (promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>, promise<'a5>) +) => promise<('a0, 'a1, 'a2, 'a3, 'a4, 'a5)> = "all" + +@val @scope("Promise") external race: array> => promise<'a> = "race" + +external unsafe_async: 'a => promise<'a> = "%identity" +external unsafe_await: promise<'a> => 'a = "?await" diff --git a/js/src/js_re.js b/js/src/js_re.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_re.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_re.res b/js/src/js_re.res new file mode 100644 index 0000000..3b11af6 --- /dev/null +++ b/js/src/js_re.res @@ -0,0 +1,201 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +Provide bindings to JS regular expressions (RegExp). + +**Note:** This is not an immutable API. A RegExp object with the `global` ("g") +flag set will modify the [`lastIndex`]() property when the RegExp object is used, +and subsequent uses will continue the search from the previous [`lastIndex`](). +*/ + +/** The RegExp object. */ +type t = Runtime_types.regExp + +/** The result of a executing a RegExp on a string. */ +type result + +/** +An `array` of the match and captures, the first is the full match and the +remaining are the substring captures. +*/ +external captures: result => array> = "%identity" + +@deprecated("Use Js.Re.captures instead") +external matches: result => array = "%identity" + +/** 0-based index of the match in the input string. */ +@get +external index: result => int = "index" + +/** The original input string. */ +@get +external input: result => string = "input" + +/** +Constructs a RegExp object (Js.Re.t) from a `string`. +Regex literals `%re("/.../")` should generally be preferred, but `fromString` +is useful when you need to dynamically construct a regex using strings, +exactly like when you do so in JavaScript. + +## Examples + +```rescript +let firstReScriptFileExtension = (filename, content) => { + let result = Js.Re.fromString(filename ++ "\.(res|resi)")->Js.Re.exec_(content) + switch result { + | Some(r) => Js.Nullable.toOption(Js.Re.captures(r)[1]) + | None => None + } +} + +// outputs "res" +firstReScriptFileExtension("School", "School.res School.resi Main.js School.bs.js") +``` +*/ +@new +external fromString: string => t = "RegExp" + +/** +Constructs a RegExp object (`Js.Re.t`) from a string with the given flags. +See `Js.Re.fromString`. + +Valid flags: + +- **g** global +- **i** ignore case +- **m** multiline +- **u** unicode (es2015) +- **y** sticky (es2015) +*/ +@new +external fromStringWithFlags: (string, ~flags: string) => t = "RegExp" + +/** Returns the enabled flags as a string. */ +@get +external flags: t => string = "flags" + +/** Returns a `bool` indicating whether the global flag is set. */ +@get +external global: t => bool = "global" + +/** Returns a `bool` indicating whether the ignoreCase flag is set. */ +@get +external ignoreCase: t => bool = "ignoreCase" + +/** +Returns the index where the next match will start its search. This property +will be modified when the RegExp object is used, if the global ("g") flag is +set. + +## Examples + +```rescript +let re = %re("/ab*TODO/g") +let str = "abbcdefabh" + +let break = ref(false) +while !break.contents { + switch Js.Re.exec_(re, str) { + | Some(result) => Js.Nullable.iter(Js.Re.captures(result)[0], (. match_) => { + let next = Belt.Int.toString(Js.Re.lastIndex(re)) + Js.log("Found " ++ (match_ ++ (". Next match starts at " ++ next))) + }) + | None => break := true + } +} +``` + +See +[`RegExp: lastIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex) +on MDN. +*/ +@get +external lastIndex: t => int = "lastIndex" + +/** Sets the index at which the next match will start its search from. */ +@set +external setLastIndex: (t, int) => unit = "lastIndex" + +/** Returns a `bool` indicating whether the multiline flag is set. */ +@get +external multiline: t => bool = "multiline" + +/** Returns the pattern as a `string`. */ +@get +external source: t => string = "source" + +/** Returns a `bool` indicating whether the sticky flag is set. */ +@get +external sticky: t => bool = "sticky" + +/** Returns a `bool` indicating whether the unicode flag is set. */ +@get +external unicode: t => bool = "unicode" + +/** +Executes a search on a given string using the given RegExp object. +Returns `Some(Js.Re.result)` if a match is found, `None` otherwise. + +## Examples + +```rescript +/* Match "quick brown" followed by "jumps", ignoring characters in between + * Remember "brown" and "jumps" + * Ignore case + */ + +let re = %re("/quick\s(brown).+?(jumps)/ig") +let result = Js.Re.exec_(re, "The Quick Brown Fox Jumps Over The Lazy Dog") +``` + +See [`RegExp.prototype.exec()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) +on MDN. +*/ +@send +@return(null_to_opt) +external exec_: (t, string) => option = "exec" + +/** +Tests whether the given RegExp object will match a given `string`. +Returns true if a match is found, false otherwise. + +## Examples + +```rescript +/* A simple implementation of Js.String.startsWith */ + +let str = "hello world!" + +let startsWith = (target, substring) => + Js.Re.fromString("^" ++ substring)->Js.Re.test_(target) + +Js.log(str->startsWith("hello")) /* prints "true" */ +``` + +See [`RegExp.prototype.test()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) +on MDN. +*/ +@send +external test_: (t, string) => bool = "test" diff --git a/js/src/js_result.res b/js/src/js_result.res new file mode 100644 index 0000000..8cb2ab1 --- /dev/null +++ b/js/src/js_result.res @@ -0,0 +1,28 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@deprecated("Please use `Belt.Result.t` instead") +type t<+'good, +'bad> = + | Ok('good) + | Error('bad) diff --git a/js/src/js_result.resi b/js/src/js_result.resi new file mode 100644 index 0000000..8cb2ab1 --- /dev/null +++ b/js/src/js_result.resi @@ -0,0 +1,28 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@deprecated("Please use `Belt.Result.t` instead") +type t<+'good, +'bad> = + | Ok('good) + | Error('bad) diff --git a/js/src/js_set.res b/js/src/js_set.res new file mode 100644 index 0000000..8e0d51d --- /dev/null +++ b/js/src/js_set.res @@ -0,0 +1,3 @@ +/*** ES6 Set API */ + +type t<'a> diff --git a/js/src/js_string.js b/js/src/js_string.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_string.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_string.res b/js/src/js_string.res new file mode 100644 index 0000000..a198c96 --- /dev/null +++ b/js/src/js_string.res @@ -0,0 +1,1006 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** JavaScript String API */ + +@@warning("-103") + +type t = string + +@val +/** +`make(value)` converts the given value to a `string`. + +## Examples + +```rescript +Js.String2.make(3.5) == "3.5" +Js.String2.make([1, 2, 3]) == "1,2,3" +``` +*/ +external make: 'a => t = "String" + +@val +/** +`fromCharCode(n)` creates a `string` containing the character corresponding to that number; `n` ranges from 0 to 65535. +If out of range, the lower 16 bits of the value are used. Thus, `fromCharCode(0x1F63A)` gives the same result as `fromCharCode(0xF63A)`. See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) on MDN. + +## Examples + +```rescript +Js.String2.fromCharCode(65) == "A" +Js.String2.fromCharCode(0x3c8) == `ψ` +Js.String2.fromCharCode(0xd55c) == `한` +Js.String2.fromCharCode(-64568) == `ψ` +``` +*/ +external fromCharCode: int => t = "String.fromCharCode" + +@val +@variadic +/** +`fromCharCodeMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given numbers, using the same rules as `fromCharCode`. See +[`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) +on MDN. +*/ +external fromCharCodeMany: array => t = "String.fromCharCode" + +@val +/** +`fromCodePoint(n)` creates a `string` containing the character corresponding to +that numeric code point. If the number is not a valid code point, it raises +`RangeError`.Thus, `fromCodePoint(0x1F63A)` will produce a correct value, +unlike `fromCharCode(0x1F63A)`, and `fromCodePoint(-5)` will raise a +`RangeError`. + +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. + +## Examples + +```rescript +Js.String2.fromCodePoint(65) == "A" +Js.String2.fromCodePoint(0x3c8) == `ψ` +Js.String2.fromCodePoint(0xd55c) == `한` +Js.String2.fromCodePoint(0x1f63a) == `😺` +``` +*/ +external fromCodePoint: int => t = "String.fromCodePoint" + +@val +@variadic +/** +`fromCodePointMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given code point numbers, using the same rules as +`fromCodePoint`. + +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. + +## Examples + +```rescript +Js.String2.fromCodePointMany([0xd55c, 0xae00, 0x1f63a]) == `한글😺` +``` +*/ +external fromCodePointMany: array => t = "String.fromCodePoint" + +/* String.raw: ES2015, meant to be used with template strings, not directly */ + +@get +/** +`length(s)` returns the length of the given `string`. See +[`String.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length) +on MDN. + +## Examples + +```rescript +Js.String2.length("abcd") == 4 +``` +*/ +external length: t => int = "length" + +@get_index +/** +`get(s, n)` returns as a `string` the character at the given index number. If +`n` is out of range, this function returns `undefined`, so at some point this +function may be modified to return `option`. + +## Examples + +```rescript +Js.String2.get("Reason", 0) == "R" +Js.String2.get("Reason", 4) == "o" +Js.String2.get(`Rẽasöń`, 5) == `ń` +``` +*/ +external get: (t, int) => t = "" + +@bs.send.pipe(: t) +/** +`charAt(n, s)` gets the character at index `n` within string `s`. If `n` is +negative or greater than the length of `s`, it returns the empty string. If the +string contains characters outside the range \u0000-\uffff, it will return the +first 16-bit value at that position in the string. + +See [`String.charAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt) +on MDN. + +## Examples + +```rescript +Js.String.charAt(0, "Reason") == "R" +Js.String.charAt(12, "Reason") == "" +Js.String.charAt(5, `Rẽasöń`) == `ń` +``` +*/ +external charAt: int => t = "charAt" + +@bs.send.pipe(: t) +/** +`charCodeAt(n, s)` returns the character code at position `n` in string `s`; +the result is in the range 0-65535, unlke `codePointAt`, so it will not work +correctly for characters with code points greater than or equal to 0x10000. The +return type is `float` because this function returns NaN if `n` is less than +zero or greater than the length of the string. + +See [`String.charCodeAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) +on MDN. + +## Examples + +```rescript +Js.String.charCodeAt(0, `😺`) == 0xd83d->Belt.Int.toFloat +Js.String.codePointAt(0, `😺`) == Some(0x1f63a) +``` +*/ +external charCodeAt: int => float = "charCodeAt" + +@bs.send.pipe(: t) +/** +`codePointAt(n, s)` returns the code point at position `n` within string `s` as +a `Some(value)`. The return value handles code points greater than or equal to +0x10000. If there is no code point at the given position, the function returns +`None`. + +See [`String.codePointAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) +on MDN. + +## Examples + +```rescript +Js.String.codePointAt(1, `¿😺?`) == Some(0x1f63a) +Js.String.codePointAt(5, "abc") == None +``` +*/ +external codePointAt: int => option = "codePointAt" + +@bs.send.pipe(: t) +/** +`concat(append, original)` returns a new `string` with `append` added after +`original`. + +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. + +## Examples + +```rescript +Js.String.concat("bell", "cow") == "cowbell" +``` +*/ +external concat: t => t = "concat" + +@send.pipe(: t) +@variadic +/** +`concat(arr, original)` returns a new `string` consisting of each item of an +array of strings added to the `original` string. + +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. + +## Examples + +```rescript +Js.String.concatMany(["2nd", "3rd", "4th"], "1st") == "1st2nd3rd4th" +``` +*/ +external concatMany: array => t = "concat" + +@bs.send.pipe(: t) +/** +ES2015: `endsWith(substr, str)` returns `true` if the `str` ends with `substr`, +`false` otherwise. + +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. + +## Examples + +```rescript +Js.String.endsWith("Script", "ReScript") == true +Js.String.endsWith("Script", "C++") == false +``` +*/ +external endsWith: t => bool = "endsWith" + +@bs.send.pipe(: t) +/** +`endsWithFrom(ending, len, str)` returns `true` if the first len characters of +`str` end with `ending`, `false` otherwise. If `len` is greater than or equal +to the length of `str`, then it works like `endsWith`. (Honestly, this should +have been named endsWithAt, but oh well.) + +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. + +## Examples + +```rescript +Js.String.endsWithFrom("cd", 4, "abcd") == true +Js.String.endsWithFrom("cd", 3, "abcde") == false +Js.String.endsWithFrom("cde", 99, "abcde") == true +Js.String.endsWithFrom("ple", 7, "example.dat") == true +``` +*/ +external endsWithFrom: (t, int) => bool = "endsWith" + +@bs.send.pipe(: t) +/** +ES2015: `includes(searchValue, str)` returns `true` if `searchValue` is found +anywhere within `str`, false otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. + +## Examples + +```rescript +Js.String.includes("gram", "programmer") == true +Js.String.includes("er", "programmer") == true +Js.String.includes("pro", "programmer") == true +Js.String.includes("xyz", "programmer.dat") == false +``` +*/ +external includes: t => bool = "includes" + +@bs.send.pipe(: t) +/** +ES2015: `includes(searchValue start, str)` returns `true` if `searchValue` is +found anywhere within `str` starting at character number `start` (where 0 is +the first character), `false` otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. + +## Examples + +```rescript +Js.String.includesFrom("gram", 1, "programmer") == true +Js.String.includesFrom("gram", 4, "programmer") == false +Js.String.includesFrom(`한`, 1, `대한민국`) == true +``` +*/ +external includesFrom: (t, int) => bool = "includes" + +@bs.send.pipe(: t) +/** +ES2015: `indexOf(searchValue, str)` returns the position at which `searchValue` +was first found within `str`, or -1 if `searchValue` is not in `str`. + +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. + +## Examples + +```rescript +Js.String.indexOf("ok", "bookseller") == 2 +Js.String.indexOf("sell", "bookseller") == 4 +Js.String.indexOf("ee", "beekeeper") == 1 +Js.String.indexOf("xyz", "bookseller") == -1 +``` +*/ +external indexOf: t => int = "indexOf" + +@bs.send.pipe(: t) +/** +`indexOfFrom(searchValue, start, str)` returns the position at which +`searchValue` was found within `str` starting at character position `start`, or +-1 if `searchValue` is not found in that portion of `str`. The return value is +relative to the beginning of the string, no matter where the search started +from. + +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. + +## Examples + +```rescript +Js.String.indexOfFrom("ok", 1, "bookseller") == 2 +Js.String.indexOfFrom("sell", 2, "bookseller") == 4 +Js.String.indexOfFrom("sell", 5, "bookseller") == -1 +``` +*/ +external indexOfFrom: (t, int) => int = "indexOf" + +@bs.send.pipe(: t) +/** +`lastIndexOf(searchValue, str)` returns the position of the last occurrence of +`searchValue` within `str`, searching backwards from the end of the string. +Returns -1 if `searchValue` is not in `str`. The return value is always +relative to the beginning of the string. + +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.String.lastIndexOf("ok", "bookseller") == 2 +Js.String.lastIndexOf("ee", "beekeeper") == 4 +Js.String.lastIndexOf("xyz", "abcdefg") == -1 +``` +*/ +external lastIndexOf: t => int = "lastIndexOf" + +@bs.send.pipe(: t) +/** +`lastIndexOfFrom(searchValue, start, str)` returns the position of the last +occurrence of `searchValue` within `str`, searching backwards from the given +start position. Returns -1 if `searchValue` is not in `str`. The return value +is always relative to the beginning of the string. + +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.String.lastIndexOfFrom("ok", 6, "bookseller") == 2 +Js.String.lastIndexOfFrom("ee", 8, "beekeeper") == 4 +Js.String.lastIndexOfFrom("ee", 3, "beekeeper") == 1 +Js.String.lastIndexOfFrom("xyz", 4, "abcdefg") == -1 +``` +*/ +external lastIndexOfFrom: (t, int) => int = "lastIndexOf" + +/* extended by ECMA-402 */ + +@bs.send.pipe(: t) +/** +`localeCompare(comparison, reference)` returns +- a negative value if reference comes before comparison in sort order +- zero if reference and comparison have the same sort order +- a positive value if reference comes after comparison in sort order + +See [`String.localeCompare`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) on MDN. + +## Examples + +```rescript +Js.String.localeCompare("ant", "zebra") > 0.0 +Js.String.localeCompare("zebra", "ant") < 0.0 +Js.String.localeCompare("cat", "cat") == 0.0 +Js.String.localeCompare("cat", "CAT") > 0.0 +``` +*/ +external localeCompare: t => float = "localeCompare" + +@send.pipe(: t) +@return(nullable) +/** +`match(regexp, str)` matches a `string` against the given `regexp`. If there is +no match, it returns `None`. For regular expressions without the g modifier, if + there is a match, the return value is `Some(array)` where the array contains: +- The entire matched string +- Any capture groups if the regexp had parentheses + +For regular expressions with the g modifier, a matched expression returns +`Some(array)` with all the matched substrings and no capture groups. + +See [`String.match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) +on MDN. + +## Examples + +```rescript +Js.String.match_(%re("/b[aeiou]t/"), "The better bats") == Some(["bet"]) +Js.String.match_(%re("/b[aeiou]t/g"), "The better bats") == Some(["bet", "bat"]) +Js.String.match_(%re("/(\d+)-(\d+)-(\d+)/"), "Today is 2018-04-05.") == + Some(["2018-04-05", "2018", "04", "05"]) +Js.String.match_(%re("/b[aeiou]g/"), "The large container.") == None +``` +*/ +external match_: Js_re.t => option>> = "match" + +@bs.send.pipe(: t) +/** +`normalize(str)` returns the normalized Unicode string using Normalization Form +Canonical (NFC) Composition. Consider the character ã, which can be represented +as the single codepoint \u00e3 or the combination of a lower case letter A +\u0061 and a combining tilde \u0303. Normalization ensures that both can be +stored in an equivalent binary representation. + +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) +on MDN. + +See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for +details. +*/ +external normalize: t = "normalize" + +@bs.send.pipe(: t) +/** +ES2015: `normalize(form, str)` returns the normalized Unicode string using the specified form of normalization, which may be one of: +- "NFC" — Normalization Form Canonical Composition. +- "NFD" — Normalization Form Canonical Decomposition. +- "NFKC" — Normalization Form Compatibility Composition. +- "NFKD" — Normalization Form Compatibility Decomposition. + +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) on MDN. + +See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for details. +*/ +external normalizeByForm: t => t = "normalize" + +@bs.send.pipe(: t) +/** +`repeat(n, str)` returns a `string` that consists of `n` repetitions of `str`. +Raises `RangeError` if `n` is negative. + +See [`String.repeat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) +on MDN. + +## Examples + +```rescript +Js.String.repeat(3, "ha") == "hahaha" +Js.String.repeat(0, "empty") == "" +``` +*/ +external repeat: int => t = "repeat" + +@bs.send.pipe(: t) +/** +ES2015: `replace(substr, newSubstr, str)` returns a new `string` which is +identical to `str` except with the first matching instance of `substr` replaced +by `newSubstr`. `substr` is treated as a verbatim string to match, not a +regular expression. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +Js.String.replace("old", "new", "old string") == "new string" +Js.String.replace("the", "this", "the cat and the dog") == "this cat and the dog" +``` +*/ +external replace: (t, t) => t = "replace" + +@bs.send.pipe(: t) +/** +`replaceByRe(regex, replacement, str)` returns a new `string` where occurrences +matching regex have been replaced by `replacement`. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +Js.String.replaceByRe(%re("/[aeiou]/g"), "x", "vowels be gone") == "vxwxls bx gxnx" +Js.String.replaceByRe(%re("/(\w+) (\w+)/"), "$2, $1", "Juan Fulano") == "Fulano, Juan" +``` +*/ +external replaceByRe: (Js_re.t, t) => t = "replace" + +@bs.send.pipe(: t) +/** +Returns a new `string` with some or all matches of a pattern with no capturing +parentheses replaced by the value returned from the given function. The +function receives as its parameters the matched string, the offset at which the +match begins, and the whole string being matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +let str = "beautiful vowels" +let re = %re("/[aeiou]/g") +let matchFn = (matchPart, _offset, _wholeString) => Js.String.toUpperCase(matchPart) + +Js.String.unsafeReplaceBy0(re, matchFn, str) == "bEAUtIfUl vOwEls" +``` +*/ +external unsafeReplaceBy0: (Js_re.t, (t, int, t) => t) => t = "replace" + +@bs.send.pipe(: t) +/** +Returns a new `string` with some or all matches of a pattern with one set of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +string, the offset at which the match begins, and the whole string being +matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +let str = "Jony is 40" +let re = %re("/(Jony is )\d+/g") +let matchFn = (_match, part1, _offset, _wholeString) => { + part1 ++ "41" +} + +Js.String.unsafeReplaceBy1(re, matchFn, str) == "Jony is 41" +``` +*/ +external unsafeReplaceBy1: (Js_re.t, (t, t, int, t) => t) => t = "replace" + +@bs.send.pipe(: t) +/** +Returns a new `string` with some or all matches of a pattern with two sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +let str = "7 times 6" +let re = %re("/(\d+) times (\d+)/") +let matchFn = (_match, p1, p2, _offset, _wholeString) => { + switch (Belt.Int.fromString(p1), Belt.Int.fromString(p2)) { + | (Some(x), Some(y)) => Belt.Int.toString(x * y) + | _ => "???" + } +} + +Js.String.unsafeReplaceBy2(re, matchFn, str) == "42" +``` +*/ +external unsafeReplaceBy2: (Js_re.t, (t, t, t, int, t) => t) => t = "replace" + +@bs.send.pipe(: t) +/** +Returns a new `string` with some or all matches of a pattern with three sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. +*/ +external unsafeReplaceBy3: (Js_re.t, (t, t, t, t, int, t) => t) => t = "replace" + +@bs.send.pipe(: t) +/** +`search(regexp, str)` returns the starting position of the first match of +`regexp` in the given `str`, or -1 if there is no match. + +See [`String.search`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) +on MDN. + +## Examples + +```rescript +Js.String.search(%re("/\d+/"), "testing 1 2 3") == 8 +Js.String.search(%re("/\d+/"), "no numbers") == -1 +``` +*/ +external search: Js_re.t => int = "search" + +@bs.send.pipe(: t) +/** +`slice(from:n1, to_:n2, str)` returns the substring of `str` starting at +character `n1` up to but not including `n2`. +- If either `n1` or `n2` is negative, then it is evaluated as `length(str - n1)` or `length(str - n2)`. +- If `n2` is greater than the length of `str`, then it is treated as `length(str)`. +- If `n1` is greater than `n2`, slice returns the empty string. + +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. + +## Examples + +```rescript +Js.String.slice(~from=2, ~to_=5, "abcdefg") == "cde" +Js.String.slice(~from=2, ~to_=9, "abcdefg") == "cdefg" +Js.String.slice(~from=-4, ~to_=-2, "abcdefg") == "de" +Js.String.slice(~from=5, ~to_=1, "abcdefg") == "" +``` +*/ +external slice: (~from: int, ~to_: int) => t = "slice" + +@bs.send.pipe(: t) +/** +`sliceToEnd(str, from:n)` returns the substring of `str` starting at character +`n` to the end of the string. +- If `n` is negative, then it is evaluated as `length(str - n)`. +- If `n` is greater than the length of `str`, then sliceToEnd returns the empty string. + +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. + +## Examples + +```rescript +Js.String.sliceToEnd(~from=4, "abcdefg") == "efg" +Js.String.sliceToEnd(~from=-2, "abcdefg") == "fg" +Js.String.sliceToEnd(~from=7, "abcdefg") == "" +``` +*/ +external sliceToEnd: (~from: int) => t = "slice" + +@bs.send.pipe(: t) +/** +`split(delimiter, str)` splits the given `str` at every occurrence of +`delimiter` and returns an array of the resulting substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String.split("-", "2018-01-02") == ["2018", "01", "02"] +Js.String.split(",", "a,b,,c") == ["a", "b", "", "c"] +Js.String.split("::", "good::bad as great::awful") == ["good", "bad as great", "awful"] +Js.String.split(";", "has-no-delimiter") == ["has-no-delimiter"] +``` +*/ +external split: t => array = "split" + +@bs.send.pipe(: t) +/** +`splitAtMost(delimiter, ~limit:n, str)` splits the given `str` at every +occurrence of `delimiter` and returns an array of the first `n` resulting +substrings. If `n` is negative or greater than the number of substrings, the +array will contain all the substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String.splitAtMost("/", ~limit=3, "ant/bee/cat/dog/elk") == ["ant", "bee", "cat"] +Js.String.splitAtMost("/", ~limit=0, "ant/bee/cat/dog/elk") == [] +Js.String.splitAtMost("/", ~limit=9, "ant/bee/cat/dog/elk") == ["ant", "bee", "cat", "dog", "elk"] +``` +*/ +external splitAtMost: (t, ~limit: int) => array = "split" + +@bs.send.pipe(: t) +@ocaml.doc(" +`splitByRe(regex, str)` splits the given `str` at every occurrence of `regex` +and returns an array of the resulting substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String.splitByRe(%re(\"/\s*[,;]\s*/\"), \"art; bed , cog ;dad\") == [ + Some(\"art\"), + Some(\"bed\"), + Some(\"cog\"), + Some(\"dad\"), + ] +``` +") +external splitByRe: Js_re.t => array> = "split" + +@bs.send.pipe(: t) +@ocaml.doc(" +`splitByReAtMost(regex, ~limit:n, str)` splits the given `str` at every +occurrence of `regex` and returns an array of the first `n` resulting +substrings. If `n` is negative or greater than the number of substrings, the +array will contain all the substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String.splitByReAtMost(%re(\"/\s*:\s*/\"), ~limit=3, \"one: two: three: four\") == [ + Some(\"one\"), + Some(\"two\"), + Some(\"three\"), + ] + +Js.String.splitByReAtMost(%re(\"/\s*:\s*/\"), ~limit=0, \"one: two: three: four\") == [] + +Js.String.splitByReAtMost(%re(\"/\s*:\s*/\"), ~limit=8, \"one: two: three: four\") == [ + Some(\"one\"), + Some(\"two\"), + Some(\"three\"), + Some(\"four\"), + ] +``` +") +external splitByReAtMost: (Js_re.t, ~limit: int) => array> = "split" + +@bs.send.pipe(: t) +/** +ES2015: `startsWith(substr, str)` returns `true` if the `str` starts with +`substr`, `false` otherwise. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. + +## Examples + +```rescript +Js.String.startsWith("Re", "ReScript") == true +Js.String.startsWith("", "ReScript") == true +Js.String.startsWith("Re", "JavaScript") == false +``` +*/ +external startsWith: t => bool = "startsWith" + +@bs.send.pipe(: t) +/** +ES2015: `startsWithFrom(substr, n, str)` returns `true` if the `str` starts +with `substr` starting at position `n`, false otherwise. If `n` is negative, +the search starts at the beginning of `str`. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. + +## Examples + +```rescript +Js.String.startsWithFrom("Scri", 2, "ReScript") == true +Js.String.startsWithFrom("", 2, "ReScript") == true +Js.String.startsWithFrom("Scri", 2, "JavaScript") == false +``` +*/ +external startsWithFrom: (t, int) => bool = "startsWith" + +@bs.send.pipe(: t) +/** +`substr(~from:n, str)` returns the substring of `str` from position `n` to the +end of the string. +- If `n` is less than zero, the starting position is the length of `str - n`. +- If `n` is greater than or equal to the length of `str`, returns the empty string. + +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. + +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. + +## Examples + +```rescript +Js.String.substr(~from=3, "abcdefghij") == "defghij" +Js.String.substr(~from=-3, "abcdefghij") == "hij" +Js.String.substr(~from=12, "abcdefghij") == "" +``` +*/ +external substr: (~from: int) => t = "substr" + +@bs.send.pipe(: t) +/** +`substrAtMost(~from: pos, ~length: n, str)` returns the substring of `str` of +length `n` starting at position `pos`. +- If `pos` is less than zero, the starting position is the length of `str - pos`. +- If `pos` is greater than or equal to the length of `str`, returns the empty string. +- If `n` is less than or equal to zero, returns the empty string. + +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. + +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. + +## Examples + +```rescript +Js.String.substrAtMost(~from=3, ~length=4, "abcdefghij") == "defg" +Js.String.substrAtMost(~from=-3, ~length=4, "abcdefghij") == "hij" +Js.String.substrAtMost(~from=12, ~length=2, "abcdefghij") == "" +``` +*/ +external substrAtMost: (~from: int, ~length: int) => t = "substr" + +@bs.send.pipe(: t) +/** +`substring(~from: start, ~to_: finish, str)` returns characters `start` up to +but not including finish from `str`. +- If `start` is less than zero, it is treated as zero. +- If `finish` is zero or negative, the empty string is returned. +- If `start` is greater than `finish`, the `start` and `finish` points are swapped. + +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. + +## Examples + +```rescript +Js.String.substring(~from=3, ~to_=6, "playground") == "ygr" +Js.String.substring(~from=6, ~to_=3, "playground") == "ygr" +Js.String.substring(~from=4, ~to_=12, "playground") == "ground" +``` +*/ +external substring: (~from: int, ~to_: int) => t = "substring" + +@bs.send.pipe(: t) +/** +`substringToEnd(~from: start, str)` returns the substring of `str` from +position `start` to the end. +- If `start` is less than or equal to zero, the entire string is returned. +- If `start` is greater than or equal to the length of `str`, the empty string is returned. + +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. + +## Examples + +```rescript +Js.String.substringToEnd(~from=4, "playground") == "ground" +Js.String.substringToEnd(~from=-3, "playground") == "playground" +Js.String.substringToEnd(~from=12, "playground") == "" +``` +*/ +external substringToEnd: (~from: int) => t = "substring" + +@bs.send.pipe(: t) +/** +`toLowerCase(str)` converts `str` to lower case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +give different results depending upon context, for example with the Greek +letter sigma, which has two different lower case forms; one when it is the last +character in a string and another when it is not. + +See [`String.toLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) +on MDN. + +## Examples + +```rescript +Js.String.toLowerCase("ABC") == "abc" +Js.String.toLowerCase(`ΣΠ`) == `σπ` +Js.String.toLowerCase(`ΠΣ`) == `πς` +``` +*/ +external toLowerCase: t = "toLowerCase" + +@bs.send.pipe(: t) +/** +`toLocaleLowerCase(str)` converts `str` to lower case using the current locale. + +See [`String.toLocaleLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase) +on MDN. +*/ +external toLocaleLowerCase: t = "toLocaleLowerCase" + +@bs.send.pipe(: t) +/** +`toUpperCase(str)` converts `str` to upper case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +expand the number of letters in the result; for example the German ß +capitalizes to two Ses in a row. + +See [`String.toUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) +on MDN. + +## Examples + +```rescript +Js.String.toUpperCase("abc") == "ABC" +Js.String.toUpperCase(`Straße`) == `STRASSE` +Js.String.toUpperCase(`πς`) == `ΠΣ` +``` +*/ +external toUpperCase: t = "toUpperCase" + +@bs.send.pipe(: t) +/** +`toLocaleUpperCase(str)` converts `str` to upper case using the current locale. + +See [`String.to:LocaleUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase) +on MDN. +*/ +external toLocaleUpperCase: t = "toLocaleUpperCase" + +@bs.send.pipe(: t) +/** +`trim(str)` returns a string that is `str` with whitespace stripped from both +ends. Internal whitespace is not removed. + +See [`String.trim`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim) +on MDN. + +## Examples + +```rescript +Js.String.trim(" abc def ") == "abc def" +Js.String.trim("\n\r\t abc def \n\n\t\r ") == "abc def" +``` +*/ +external trim: t = "trim" + +/* HTML wrappers */ + +@bs.send.pipe(: t) +/** +`anchor(anchorName, anchorText)` creates a string with an HTML `` element +with name attribute of `anchorName` and `anchorText` as its content. Please do +not use this method, as it has been removed from the relevant web standards. + +See [`String.anchor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/anchor) +on MDN. + +## Examples + +```rescript +Js.String.anchor("page1", "Page One") == "Page One" +``` +*/ +external anchor: t => t = "anchor" + +@bs.send.pipe(: t) +/** +ES2015: `link(urlText, linkText)` creates a string with an HTML `` element +with href attribute of `urlText` and `linkText` as its content. Please do not +use this method, as it has been removed from the relevant web standards. + +See [`String.link`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/link) +on MDN. + +## Examples + +```rescript +Js.String.link("page2.html", "Go to page two") == "Go to page two" +``` +*/ +external link: t => t = "link" + +/** +Casts its argument to an `array_like` entity that can be processed by functions +such as `Js.Array2.fromMap()` + +## Examples + +```rescript +let s = "abcde" +let arr = Js.Array2.fromMap(Js.String.castToArrayLike(s), x => x) +arr == ["a", "b", "c", "d", "e"] +``` +*/ +external castToArrayLike: t => Js_array2.array_like = "%identity" diff --git a/js/src/js_string2.js b/js/src/js_string2.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_string2.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_string2.res b/js/src/js_string2.res new file mode 100644 index 0000000..7dd51fd --- /dev/null +++ b/js/src/js_string2.res @@ -0,0 +1,1001 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provide bindings to JS string. Optimized for pipe-first. */ + +type t = string + +@val +/** +`make(value)` converts the given value to a `string`. + +## Examples + +```rescript +Js.String2.make(3.5) == "3.5" +Js.String2.make([1, 2, 3]) == "1,2,3" +``` +*/ +external make: 'a => t = "String" + +@val +/** +`fromCharCode(n)` creates a `string` containing the character corresponding to +that number; `n` ranges from 0 to 65535.If out of range, the lower 16 bits of +the value are used. Thus, `fromCharCode(0x1F63A)` gives the same result as +`fromCharCode(0xF63A)`. + +See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) +on MDN. + +## Examples + +```rescript +Js.String2.fromCharCode(65) == "A" +Js.String2.fromCharCode(0x3c8) == `ψ` +Js.String2.fromCharCode(0xd55c) == `한` +Js.String2.fromCharCode(-64568) == `ψ` +``` +*/ +external fromCharCode: int => t = "String.fromCharCode" + +@val +@variadic +/** +`fromCharCodeMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given numbers, using the same rules as `fromCharCode`. + +See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) +on MDN. +*/ +external fromCharCodeMany: array => t = "String.fromCharCode" + +@val +/** +`fromCodePoint(n)` creates a `string` containing the character corresponding to +that numeric code point. If the number is not a valid code point, it raises +`RangeError`. Thus, `fromCodePoint(0x1F63A)` will produce a correct value, +unlike `fromCharCode(0x1F63A)`, and `fromCodePoint(-5)` will raise a +`RangeError`. + +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. + +## Examples + +```rescript +Js.String2.fromCodePoint(65) == "A" +Js.String2.fromCodePoint(0x3c8) == `ψ` +Js.String2.fromCodePoint(0xd55c) == `한` +Js.String2.fromCodePoint(0x1f63a) == `😺` +``` +*/ +external fromCodePoint: int => t = "String.fromCodePoint" + +@val +@variadic +/** +`fromCodePointMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given code point numbers, using the same rules as +`fromCodePoint`. + +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. + +## Examples + +```rescript +Js.String2.fromCodePointMany([0xd55c, 0xae00, 0x1f63a]) == `한글😺` +``` +*/ +external fromCodePointMany: array => t = "String.fromCodePoint" + +/* String.raw: ES2015, meant to be used with template strings, not directly */ + +@get +/** +`length(s)` returns the length of the given `string`. + +See [`String.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length) +on MDN. + +## Examples + +```rescript +Js.String2.length("abcd") == 4 +``` +*/ +external length: t => int = "length" + +@get_index +/** +`get(s, n)` returns as a `string` the character at the given index number. If +`n` is out of range, this function returns `undefined`,so at some point this +function may be modified to return `option`. + +## Examples + +```rescript +Js.String2.get("Reason", 0) == "R" +Js.String2.get("Reason", 4) == "o" +Js.String2.get(`Rẽasöń`, 5) == `ń` +``` +*/ +external get: (t, int) => t = "" + +@send +/** +`charAt(s, n)` gets the character at index `n` within string `s`. If `n` is +negative or greater than the length of `s`, it returns the empty string. If the +string contains characters outside the range \u0000-\uffff, it will return the +first 16-bit value at that position in the string. + +See [`String.charAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt) +on MDN. + +## Examples + +```rescript +Js.String2.charAt("Reason", 0) == "R" +Js.String2.charAt("Reason", 12) == "" +Js.String2.charAt(`Rẽasöń`, 5) == `ń` +``` +*/ +external charAt: (t, int) => t = "charAt" + +@send +/** +`charCodeAt(s, n)` returns the character code at position `n` in string `s`; +the result is in the range 0-65535, unlke `codePointAt`, so it will not work +correctly for characters with code points greater than or equal to 0x10000. The +return type is `float` because this function returns NaN if `n` is less than +zero or greater than the length of the string. + +See [`String.charCodeAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) +on MDN. + +## Examples + +```rescript +Js.String2.charCodeAt(`😺`, 0) == 0xd83d->Belt.Int.toFloat +Js.String2.codePointAt(`😺`, 0) == Some(0x1f63a) +``` +*/ +external charCodeAt: (t, int) => float = "charCodeAt" + +@send +/** +`codePointAt(s, n)` returns the code point at position `n` within string `s` as +a `Some(value)`. The return value handles code points greater than or equal to +0x10000. If there is no code point at the given position, the function returns +`None`. + +See [`String.codePointAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) +on MDN. + +## Examples + +```rescript +Js.String2.codePointAt(`¿😺?`, 1) == Some(0x1f63a) +Js.String2.codePointAt("abc", 5) == None +``` +*/ +external codePointAt: (t, int) => option = "codePointAt" + +@send +/** +`concat(original, append)` returns a new `string` with `append` added after +`original`. + +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. + +## Examples + +```rescript +Js.String2.concat("cow", "bell") == "cowbell" +``` +*/ +external concat: (t, t) => t = "concat" + +@send +@variadic +/** +`concatMany(original, arr)` returns a new `string` consisting of each item of an +array of strings added to the `original` string. + +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. + +## Examples + +```rescript +Js.String2.concatMany("1st", ["2nd", "3rd", "4th"]) == "1st2nd3rd4th" +``` +*/ +external concatMany: (t, array) => t = "concat" + +@send +/** +ES2015: `endsWith(str, substr)` returns `true` if the `str` ends with `substr`, +`false` otherwise. + +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. + +## Examples + +```rescript +Js.String2.endsWith("ReScript", "Script") == true +Js.String2.endsWith("C++", "Script") == false +``` +*/ +external endsWith: (t, t) => bool = "endsWith" + +@send +/** +`endsWithFrom(str, ending, len)` returns `true` if the first len characters of +`str` end with `ending`, `false` otherwise. If `len` is greater than or equal +to the length of `str`, then it works like `endsWith`. (Honestly, this should +have been named endsWithAt, but oh well). + +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. + +## Examples + +```rescript +Js.String2.endsWithFrom("abcd", "cd", 4) == true +Js.String2.endsWithFrom("abcde", "cd", 3) == false +Js.String2.endsWithFrom("abcde", "cde", 99) == true +Js.String2.endsWithFrom("example.dat", "ple", 7) == true +``` +*/ +external endsWithFrom: (t, t, int) => bool = "endsWith" + +@send +/** +ES2015: `includes(str, searchValue)` returns `true` if `searchValue` is found +anywhere within `str`, false otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. + +## Examples + +```rescript +Js.String2.includes("programmer", "gram") == true +Js.String2.includes("programmer", "er") == true +Js.String2.includes("programmer", "pro") == true +Js.String2.includes("programmer.dat", "xyz") == false +``` +*/ +external includes: (t, t) => bool = "includes" + +@send +/** +ES2015: `includes(str, searchValue start)` returns `true` if `searchValue` is +found anywhere within `str` starting at character number `start` (where 0 is +the first character), `false` otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. + +## Examples + +```rescript +Js.String2.includesFrom("programmer", "gram", 1) == true +Js.String2.includesFrom("programmer", "gram", 4) == false +Js.String2.includesFrom(`대한민국`, `한`, 1) == true +``` +*/ +external includesFrom: (t, t, int) => bool = "includes" + +@send +/** +ES2015: `indexOf(str, searchValue)` returns the position at which `searchValue` +was first found within `str`, or -1 if `searchValue` is not in `str`. + +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. + +## Examples + +```rescript +Js.String2.indexOf("bookseller", "ok") == 2 +Js.String2.indexOf("bookseller", "sell") == 4 +Js.String2.indexOf("beekeeper", "ee") == 1 +Js.String2.indexOf("bookseller", "xyz") == -1 +``` +*/ +external indexOf: (t, t) => int = "indexOf" + +@send +/** +`indexOfFrom(str, searchValue, start)` returns the position at which +`searchValue` was found within `str` starting at character position `start`, or +-1 if `searchValue` is not found in that portion of `str`. The return value is +relative to the beginning of the string, no matter where the search started +from. + +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. + +## Examples + +```rescript +Js.String2.indexOfFrom("bookseller", "ok", 1) == 2 +Js.String2.indexOfFrom("bookseller", "sell", 2) == 4 +Js.String2.indexOfFrom("bookseller", "sell", 5) == -1 +``` +*/ +external indexOfFrom: (t, t, int) => int = "indexOf" + +@send +/** +`lastIndexOf(str, searchValue)` returns the position of the last occurrence of +`searchValue` within `str`, searching backwards from the end of the string. +Returns -1 if `searchValue` is not in `str`. The return value is always +relative to the beginning of the string. + +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.String2.lastIndexOf("bookseller", "ok") == 2 +Js.String2.lastIndexOf("beekeeper", "ee") == 4 +Js.String2.lastIndexOf("abcdefg", "xyz") == -1 +``` +*/ +external lastIndexOf: (t, t) => int = "lastIndexOf" + +@send +/** +`lastIndexOfFrom(str, searchValue, start)` returns the position of the last +occurrence of `searchValue` within `str`, searching backwards from the given +start position. Returns -1 if `searchValue` is not in `str`. The return value +is always relative to the beginning of the string. + +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. + +## Examples + +```rescript +Js.String2.lastIndexOfFrom("bookseller", "ok", 6) == 2 +Js.String2.lastIndexOfFrom("beekeeper", "ee", 8) == 4 +Js.String2.lastIndexOfFrom("beekeeper", "ee", 3) == 1 +Js.String2.lastIndexOfFrom("abcdefg", "xyz", 4) == -1 +``` +*/ +external lastIndexOfFrom: (t, t, int) => int = "lastIndexOf" + +/* extended by ECMA-402 */ + +@send +/** +`localeCompare(reference, comparison)` returns +- a negative value if reference comes before comparison in sort order +- zero if reference and comparison have the same sort order +- a positive value if reference comes after comparison in sort order + +See [`String.localeCompare`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) on MDN. + +## Examples + +```rescript +Js.String2.localeCompare("zebra", "ant") > 0.0 +Js.String2.localeCompare("ant", "zebra") < 0.0 +Js.String2.localeCompare("cat", "cat") == 0.0 +Js.String2.localeCompare("CAT", "cat") > 0.0 +``` +*/ +external localeCompare: (t, t) => float = "localeCompare" + +@send +@return({null_to_opt: null_to_opt}) +/** +`match(str, regexp)` matches a `string` against the given `regexp`. If there is +no match, it returns `None`. For regular expressions without the g modifier, if + there is a match, the return value is `Some(array)` where the array contains: +- The entire matched string +- Any capture groups if the regexp had parentheses +For regular expressions with the g modifier, a matched expression returns +`Some(array)` with all the matched substrings and no capture groups. + +See [`String.match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) +on MDN. + +## Examples + +```rescript +Js.String2.match_("The better bats", %re("/b[aeiou]t/")) == Some(["bet"]) +Js.String2.match_("The better bats", %re("/b[aeiou]t/g")) == Some(["bet", "bat"]) +Js.String2.match_("Today is 2018-04-05.", %re("/(\d+)-(\d+)-(\d+)/")) == + Some(["2018-04-05", "2018", "04", "05"]) +Js.String2.match_("The large container.", %re("/b[aeiou]g/")) == None +``` +*/ +external match_: (t, Js_re.t) => option>> = "match" + +@send +/** +`normalize(str)` returns the normalized Unicode string using Normalization Form +Canonical (NFC) Composition. Consider the character ã, which can be represented +as the single codepoint \u00e3 or the combination of a lower case letter A +\u0061 and a combining tilde \u0303. Normalization ensures that both can be +stored in an equivalent binary representation. + +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) +on MDN. See also [Unicode technical report +#15](https://unicode.org/reports/tr15/) for details. +*/ +external normalize: t => t = "normalize" + +@send +/** +ES2015: `normalize(str, form)` returns the normalized Unicode string using the +specified form of normalization, which may be one of: +- "NFC" — Normalization Form Canonical Composition. +- "NFD" — Normalization Form Canonical Decomposition. +- "NFKC" — Normalization Form Compatibility Composition. +- "NFKD" — Normalization Form Compatibility Decomposition. + +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) on MDN. +See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for details. +*/ +external normalizeByForm: (t, t) => t = "normalize" + +@send +/** +`repeat(str, n)` returns a `string` that consists of `n` repetitions of `str`. +Raises `RangeError` if `n` is negative. + +See [`String.repeat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) +on MDN. + +## Examples + +```rescript +Js.String2.repeat("ha", 3) == "hahaha" +Js.String2.repeat("empty", 0) == "" +``` +*/ +external repeat: (t, int) => t = "repeat" + +@send +/** +ES2015: `replace(str, substr, newSubstr)` returns a new `string` which is +identical to `str` except with the first matching instance of `substr` replaced +by `newSubstr`. `substr` is treated as a verbatim string to match, not a +regular expression. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +Js.String2.replace("old string", "old", "new") == "new string" +Js.String2.replace("the cat and the dog", "the", "this") == "this cat and the dog" +``` +*/ +external replace: (t, t, t) => t = "replace" + +@send +/** +`replaceByRe(str, regex, replacement)` returns a new `string` where occurrences +matching regex have been replaced by `replacement`. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +Js.String2.replaceByRe("vowels be gone", %re("/[aeiou]/g"), "x") == "vxwxls bx gxnx" +Js.String2.replaceByRe("Juan Fulano", %re("/(\w+) (\w+)/"), "$2, $1") == "Fulano, Juan" +``` +*/ +external replaceByRe: (t, Js_re.t, t) => t = "replace" + +@send +/** +Returns a new `string` with some or all matches of a pattern with no capturing +parentheses replaced by the value returned from the given function. The +function receives as its parameters the matched string, the offset at which the +match begins, and the whole string being matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +let str = "beautiful vowels" +let re = %re("/[aeiou]/g") +let matchFn = (matchPart, _offset, _wholeString) => Js.String2.toUpperCase(matchPart) + +Js.String2.unsafeReplaceBy0(str, re, matchFn) == "bEAUtIfUl vOwEls" +``` +*/ +external unsafeReplaceBy0: (t, Js_re.t, @uncurry (t, int, t) => t) => t = "replace" + +@send +/** +Returns a new `string` with some or all matches of a pattern with one set of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +string, the offset at which the match begins, and the whole string being +matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +let str = "Jony is 40" +let re = %re("/(Jony is )\d+/g") +let matchFn = (_match, part1, _offset, _wholeString) => { + part1 ++ "41" +} + +Js.String2.unsafeReplaceBy1(str, re, matchFn) == "Jony is 41" +``` +*/ +external unsafeReplaceBy1: (t, Js_re.t, @uncurry (t, t, int, t) => t) => t = "replace" + +@send +/** +Returns a new `string` with some or all matches of a pattern with two sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +## Examples + +```rescript +let str = "7 times 6" +let re = %re("/(\d+) times (\d+)/") +let matchFn = (_match, p1, p2, _offset, _wholeString) => { + switch (Belt.Int.fromString(p1), Belt.Int.fromString(p2)) { + | (Some(x), Some(y)) => Belt.Int.toString(x * y) + | _ => "???" + } +} + +Js.String2.unsafeReplaceBy2(str, re, matchFn) == "42" +``` +*/ +external unsafeReplaceBy2: (t, Js_re.t, @uncurry (t, t, t, int, t) => t) => t = "replace" + +@send +/** +Returns a new `string` with some or all matches of a pattern with three sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. + +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. +*/ +external unsafeReplaceBy3: (t, Js_re.t, @uncurry (t, t, t, t, int, t) => t) => t = "replace" + +@send +/** +`search(str, regexp)` returns the starting position of the first match of +`regexp` in the given `str`, or -1 if there is no match. + +See [`String.search`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) +on MDN. + +## Examples + +```rescript +Js.String2.search("testing 1 2 3", %re("/\d+/")) == 8 +Js.String2.search("no numbers", %re("/\d+/")) == -1 +``` +*/ +external search: (t, Js_re.t) => int = "search" + +@send +/** +`slice(str, from:n1, to_:n2)` returns the substring of `str` starting at +character `n1` up to but not including `n2`. +- If either `n1` or `n2` is negative, then it is evaluated as `length(str - n1)` or `length(str - n2)`. +- If `n2` is greater than the length of `str`, then it is treated as `length(str)`. +- If `n1` is greater than `n2`, slice returns the empty string. + +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. + +## Examples + +```rescript +Js.String2.slice("abcdefg", ~from=2, ~to_=5) == "cde" +Js.String2.slice("abcdefg", ~from=2, ~to_=9) == "cdefg" +Js.String2.slice("abcdefg", ~from=-4, ~to_=-2) == "de" +Js.String2.slice("abcdefg", ~from=5, ~to_=1) == "" +``` +*/ +external slice: (t, ~from: int, ~to_: int) => t = "slice" + +@send +/** +`sliceToEnd(str, from:n)` returns the substring of `str` starting at character +`n` to the end of the string. +- If `n` is negative, then it is evaluated as `length(str - n)`. +- If `n` is greater than the length of `str`, then sliceToEnd returns the empty string. + +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. + +## Examples + +```rescript +Js.String2.sliceToEnd("abcdefg", ~from=4) == "efg" +Js.String2.sliceToEnd("abcdefg", ~from=-2) == "fg" +Js.String2.sliceToEnd("abcdefg", ~from=7) == "" +``` +*/ +external sliceToEnd: (t, ~from: int) => t = "slice" + +@send +/** +`split(str, delimiter)` splits the given `str` at every occurrence of +`delimiter` and returns an array of the resulting substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String2.split("2018-01-02", "-") == ["2018", "01", "02"] +Js.String2.split("a,b,,c", ",") == ["a", "b", "", "c"] +Js.String2.split("good::bad as great::awful", "::") == ["good", "bad as great", "awful"] +Js.String2.split("has-no-delimiter", ";") == ["has-no-delimiter"] +``` +*/ +external split: (t, t) => array = "split" + +@send +/** +`splitAtMost delimiter ~limit: n str` splits the given `str` at every occurrence of `delimiter` and returns an array of the first `n` resulting substrings. If `n` is negative or greater than the number of substrings, the array will contain all the substrings. + +``` +splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 3 = [|"ant"; "bee"; "cat"|];; +splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 0 = [| |];; +splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 9 = [|"ant"; "bee"; "cat"; "dog"; "elk"|];; +``` +*/ +external splitAtMost: (t, t, ~limit: int) => array = "split" + +@send +/** +`splitByRe(str, regex)` splits the given `str` at every occurrence of `regex` +and returns an array of the resulting substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String2.splitByRe("art; bed , cog ;dad", %re("/\s*[,;]\s*TODO/")) == [ + Some("art"), + Some("bed"), + Some("cog"), + Some("dad"), + ] +``` +*/ +external splitByRe: (t, Js_re.t) => array> = "split" + +@send +/** +`splitByReAtMost(str, regex, ~limit:n)` splits the given `str` at every +occurrence of `regex` and returns an array of the first `n` resulting +substrings. If `n` is negative or greater than the number of substrings, the +array will contain all the substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +## Examples + +```rescript +Js.String2.splitByReAtMost("one: two: three: four", %re("/\s*:\s*TODO/"), ~limit=3) == [ + Some("one"), + Some("two"), + Some("three"), + ] + +Js.String2.splitByReAtMost("one: two: three: four", %re("/\s*:\s*TODO/"), ~limit=0) == [] + +Js.String2.splitByReAtMost("one: two: three: four", %re("/\s*:\s*TODO/"), ~limit=8) == [ + Some("one"), + Some("two"), + Some("three"), + Some("four"), + ] +``` +*/ +external splitByReAtMost: (t, Js_re.t, ~limit: int) => array> = "split" + +@send +/** +ES2015: `startsWith(str, substr)` returns `true` if the `str` starts with +`substr`, `false` otherwise. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. + +## Examples + +```rescript +Js.String2.startsWith("ReScript", "Re") == true +Js.String2.startsWith("ReScript", "") == true +Js.String2.startsWith("JavaScript", "Re") == false +``` +*/ +external startsWith: (t, t) => bool = "startsWith" + +@send +/** +ES2015: `startsWithFrom(str, substr, n)` returns `true` if the `str` starts +with `substr` starting at position `n`, false otherwise. If `n` is negative, +the search starts at the beginning of `str`. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. + +## Examples + +```rescript +Js.String2.startsWithFrom("ReScript", "Scri", 2) == true +Js.String2.startsWithFrom("ReScript", "", 2) == true +Js.String2.startsWithFrom("JavaScript", "Scri", 2) == false +``` +*/ +external startsWithFrom: (t, t, int) => bool = "startsWith" + +@send +/** +`substr(str, ~from:n)` returns the substring of `str` from position `n` to the +end of the string. +- If `n` is less than zero, the starting position is the length of `str - n`. +- If `n` is greater than or equal to the length of `str`, returns the empty string. + +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. + +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. + +## Examples + +```rescript +Js.String2.substr("abcdefghij", ~from=3) == "defghij" +Js.String2.substr("abcdefghij", ~from=-3) == "hij" +Js.String2.substr("abcdefghij", ~from=12) == "" +``` +*/ +external substr: (t, ~from: int) => t = "substr" + +@send +/** +`substrAtMost(str, ~from: pos, ~length: n)` returns the substring of `str` of +length `n` starting at position `pos`. +- If `pos` is less than zero, the starting position is the length of `str - pos`. +- If `pos` is greater than or equal to the length of `str`, returns the empty string. +- If `n` is less than or equal to zero, returns the empty string. + +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. + +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. + +## Examples + +```rescript +Js.String2.substrAtMost("abcdefghij", ~from=3, ~length=4) == "defg" +Js.String2.substrAtMost("abcdefghij", ~from=-3, ~length=4) == "hij" +Js.String2.substrAtMost("abcdefghij", ~from=12, ~length=2) == "" +``` +*/ +external substrAtMost: (t, ~from: int, ~length: int) => t = "substr" + +@send +/** +`substring(str, ~from: start, ~to_: finish)` returns characters `start` up to +but not including finish from `str`. +- If `start` is less than zero, it is treated as zero. +- If `finish` is zero or negative, the empty string is returned. +- If `start` is greater than `finish`, the `start` and `finish` points are swapped. + +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. + +## Examples + +```rescript +Js.String2.substring("playground", ~from=3, ~to_=6) == "ygr" +Js.String2.substring("playground", ~from=6, ~to_=3) == "ygr" +Js.String2.substring("playground", ~from=4, ~to_=12) == "ground" +``` +*/ +external substring: (t, ~from: int, ~to_: int) => t = "substring" + +@send +/** +`substringToEnd(str, ~from: start)` returns the substring of `str` from +position `start` to the end. +- If `start` is less than or equal to zero, the entire string is returned. +- If `start` is greater than or equal to the length of `str`, the empty string is returned. + +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. + +## Examples + +```rescript +Js.String2.substringToEnd("playground", ~from=4) == "ground" +Js.String2.substringToEnd("playground", ~from=-3) == "playground" +Js.String2.substringToEnd("playground", ~from=12) == "" +``` +*/ +external substringToEnd: (t, ~from: int) => t = "substring" + +@send +/** +`toLowerCase(str)` converts `str` to lower case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +give different results depending upon context, for example with the Greek +letter sigma, which has two different lower case forms; one when it is the last +character in a string and another when it is not. + +See [`String.toLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) +on MDN. + +## Examples + +```rescript +Js.String2.toLowerCase("ABC") == "abc" +Js.String2.toLowerCase(`ΣΠ`) == `σπ` +Js.String2.toLowerCase(`ΠΣ`) == `πς` +``` +*/ +external toLowerCase: t => t = "toLowerCase" + +@send +/** +`toLocaleLowerCase(str)` converts `str` to lower case using the current locale. +See [`String.toLocaleLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase) +on MDN. +*/ +external toLocaleLowerCase: t => t = "toLocaleLowerCase" + +@send +/** +`toUpperCase(str)` converts `str` to upper case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +expand the number of letters in the result; for example the German ß +capitalizes to two Ses in a row. + +See [`String.toUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) +on MDN. + +## Examples + +```rescript +Js.String2.toUpperCase("abc") == "ABC" +Js.String2.toUpperCase(`Straße`) == `STRASSE` +Js.String2.toUpperCase(`πς`) == `ΠΣ` +``` +*/ +external toUpperCase: t => t = "toUpperCase" + +@send +/** +`toLocaleUpperCase(str)` converts `str` to upper case using the current locale. +See [`String.to:LocaleUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase) +on MDN. +*/ +external toLocaleUpperCase: t => t = "toLocaleUpperCase" + +@send +/** +`trim(str)` returns a string that is `str` with whitespace stripped from both +ends. Internal whitespace is not removed. + +See [`String.trim`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim) +on MDN. + +## Examples + +```rescript +Js.String2.trim(" abc def ") == "abc def" +Js.String2.trim("\n\r\t abc def \n\n\t\r ") == "abc def" +``` +*/ +external trim: t => t = "trim" + +/* HTML wrappers */ + +@send +/** +`anchor(anchorText, anchorName)` creates a string with an HTML `` element +with name attribute of `anchorName` and `anchorText` as its content. Please do +not use this method, as it has been removed from the relevant web standards. + +See [`String.anchor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/anchor) +on MDN. + +## Examples + +```rescript +Js.String2.anchor("Page One", "page1") == "Page One" +``` +*/ +external anchor: (t, t) => t = "anchor" + +@send +/** +ES2015: `link(linkText, urlText)` creates a string with an HTML `` element +with href attribute of `urlText` and `linkText` as its content. Please do not +use this method, as it has been removed from the relevant web standards. See +[`String.link`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/link) +on MDN. + +## Examples + +```rescript +Js.String2.link("Go to page two", "page2.html") == "Go to page two" +``` +*/ +external link: (t, t) => t = "link" + +/* FIXME: we should not encourage people to use [%identity], better + to provide something using [@@val] so that we can track such + casting +*/ +/** +Casts its argument to an `array_like` entity that can be processed by functions +such as `Js.Array2.fromMap()` + +## Examples + +```rescript +let s = "abcde" +let arr = Js.Array2.fromMap(Js.String2.castToArrayLike(s), x => x) +arr == ["a", "b", "c", "d", "e"] +``` +*/ +external castToArrayLike: t => Js_array2.array_like = "%identity" diff --git a/js/src/js_typed_array.js b/js/src/js_typed_array.js new file mode 100644 index 0000000..c9a668f --- /dev/null +++ b/js/src/js_typed_array.js @@ -0,0 +1,48 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var $$ArrayBuffer = {}; + +var $$Int8Array = {}; + +var $$Uint8Array = {}; + +var $$Uint8ClampedArray = {}; + +var $$Int16Array = {}; + +var $$Uint16Array = {}; + +var $$Int32Array = {}; + +var $$Uint32Array = {}; + +var $$Float32Array = {}; + +var $$Float64Array = {}; + +var $$DataView = {}; + +var Int32_array; + +var Float32_array; + +var Float64_array; + +export { + $$ArrayBuffer , + $$Int8Array , + $$Uint8Array , + $$Uint8ClampedArray , + $$Int16Array , + $$Uint16Array , + $$Int32Array , + Int32_array , + $$Uint32Array , + $$Float32Array , + Float32_array , + $$Float64Array , + Float64_array , + $$DataView , +} +/* No side effect */ diff --git a/js/src/js_typed_array.res b/js/src/js_typed_array.res new file mode 100644 index 0000000..45e865c --- /dev/null +++ b/js/src/js_typed_array.res @@ -0,0 +1,1353 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +JavaScript Typed Array API + +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) +*/ + +@@warning("-103") + +type array_buffer = Js_typed_array2.array_buffer +type array_like<'a> = Js_typed_array2.array_like<'a> + +module type Type = { + type t +} +module ArrayBuffer = { + /*** + The underlying buffer that the typed arrays provide views of + + **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) + */ + + type t = array_buffer + + @new /** takes length. initializes elements to 0 */ + external make: int => t = "ArrayBuffer" + + /* ArrayBuffer.isView: seems pointless with a type system */ + /* experimental + external transfer : array_buffer -> t = "ArrayBuffer.transfer" [@@val] + external transferWithLength : array_buffer -> int -> t = "ArrayBuffer.transfer" [@@val] + */ + + @get external byteLength: t => int = "byteLength" + + @bs.send.pipe(: t) external slice: (~start: int, ~end_: int) => array_buffer = "slice" /* FIXME */ + @bs.send.pipe(: t) external sliceFrom: int => array_buffer = "slice" +} +module type S = { + /*** Implements functionality common to all the typed arrays */ + + type elt + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) + * --- + */ + @get external length: t => int = "length" + + /* Mutator functions + */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions + */ + @bs.send.pipe(: t) /** ES2016 */ + external includes: elt => bool = "includes" + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) external slice: (~start: int, ~end_: int) => t = "slice" + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) external subarray: (~start: int, ~end_: int) => t = "subarray" + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions + */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + /** should we use `bool` or `boolean` seems they are intechangeable here */ + @bs.send.pipe(: t) + external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + /* commented out until bs has a plan for iterators + external values : elt array_iter = "" [@@bs.send.pipe: t] + */ +} + +/* commented out until bs has a plan for iterators + external values : elt array_iter = "" [@@bs.send.pipe: t] + */ + +module Int8Array = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Int8Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Int8Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Int8Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Int8Array" + + /** + raise Js.Exn.Error raise Js exception + + param offset is in bytes + */ + @new + external fromBufferOffset: (array_buffer, int) => t = "Int8Array" + + @new + /** + raise Js.Exn.Error raises Js exception + + param offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int8Array" + + @new external fromLength: int => t = "Int8Array" + @val external from: array_like => t = "Int8Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint8Array = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Uint8Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint8Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint8Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint8Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint8Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8Array" + + @new external fromLength: int => t = "Uint8Array" + @val external from: array_like => t = "Uint8Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint8ClampedArray = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Uint8ClampedArray.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint8ClampedArray.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint8ClampedArray" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint8ClampedArray" + + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + @new + external fromBufferOffset: (array_buffer, int) => t = "Uint8ClampedArray" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8ClampedArray" + + @new external fromLength: int => t = "Uint8ClampedArray" + @val external from: array_like => t = "Uint8ClampedArray.from" + /* *Array.of is redundant, use make */ +} + +module Int16Array = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Int16Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Int16Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Int16Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Int16Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Int16Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int16Array" + + @new external fromLength: int => t = "Int16Array" + @val external from: array_like => t = "Int16Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint16Array = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Uint16Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint16Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint16Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint16Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint16Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint16Array" + + @new external fromLength: int => t = "Uint16Array" + @val external from: array_like => t = "Uint16Array.from" + /* *Array.of is redundant, use make */ +} + +module Int32Array = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Int32Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Int32Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Int32Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Int32Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Int32Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int32Array" + + @new external fromLength: int => t = "Int32Array" + @val external from: array_like => t = "Int32Array.from" + /* *Array.of is redundant, use make */ + @new @deprecated("use `make` instead") external create: array => t = "Int32Array" + @new @deprecated("use `fromBuffer` instead") external of_buffer: array_buffer => t = "Int32Array" +} +module Int32_array = Int32Array + +module Uint32Array = { + /** */ + type elt = int + type typed_array<'a> = Js_typed_array2.Uint32Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint32Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint32Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint32Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint32Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint32Array" + + @new external fromLength: int => t = "Uint32Array" + @val external from: array_like => t = "Uint32Array.from" + /* *Array.of is redundant, use make */ +} + +/* + it still return number, `float` in this case +*/ +module Float32Array = { + /** */ + type elt = float + type typed_array<'a> = Js_typed_array2.Float32Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Float32Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Float32Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Float32Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Float32Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float32Array" + + @new external fromLength: int => t = "Float32Array" + @val external from: array_like => t = "Float32Array.from" + /* *Array.of is redundant, use make */ + @new @deprecated("use `make` instead") external create: array => t = "Float32Array" + @new @deprecated("use `fromBuffer` instead") + external of_buffer: array_buffer => t = "Float32Array" +} +module Float32_array = Float32Array + +module Float64Array = { + /** */ + type elt = float + type typed_array<'a> = Js_typed_array2.Float64Array.typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @bs.send.pipe(: t) external setArray: array => unit = "set" + @bs.send.pipe(: t) external setArrayOffset: (array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" + @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" + @bs.send.pipe(: t) + external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" + @bs.send.pipe(: t) external fillFromInPlace: (elt, ~from: int) => t = "fill" + @bs.send.pipe(: t) external fillRangeInPlace: (elt, ~start: int, ~end_: int) => t = "fill" + + @bs.send.pipe(: t) external reverseInPlace: t = "reverse" + + @bs.send.pipe(: t) external sortInPlace: t = "sort" + @bs.send.pipe(: t) external sortInPlaceWith: ((. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @bs.send.pipe(: t) external includes: elt => bool = "includes" /* ES2016 */ + + @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" + @bs.send.pipe(: t) external indexOfFrom: (elt, ~from: int) => int = "indexOf" + + @bs.send.pipe(: t) external join: string = "join" + @bs.send.pipe(: t) external joinWith: string => string = "join" + + @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" + @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external slice: (~start: int, ~end_: int) => t = "slice" + + @bs.send.pipe(: t) external copy: t = "slice" + @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + + @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + external subarray: (~start: int, ~end_: int) => t = "subarray" + + @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" + + @bs.send.pipe(: t) external toString: string = "toString" + @bs.send.pipe(: t) external toLocaleString: string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : (int * elt) array_iter = "" [@@bs.send.pipe: t] + */ + @bs.send.pipe(: t) external every: ((. elt) => bool) => bool = "every" + @bs.send.pipe(: t) external everyi: ((. elt, int) => bool) => bool = "every" + + @bs.send.pipe(: t) external filter: ((. elt) => bool) => t = "filter" + @bs.send.pipe(: t) external filteri: ((. elt, int) => bool) => t = "filter" + + @bs.send.pipe(: t) external find: ((. elt) => bool) => Js_undefined.t = "find" + @bs.send.pipe(: t) external findi: ((. elt, int) => bool) => Js_undefined.t = "find" + + @bs.send.pipe(: t) external findIndex: ((. elt) => bool) => int = "findIndex" + @bs.send.pipe(: t) external findIndexi: ((. elt, int) => bool) => int = "findIndex" + + @bs.send.pipe(: t) external forEach: ((. elt) => unit) => unit = "forEach" + @bs.send.pipe(: t) external forEachi: ((. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : int array_iter = "" [@@bs.send.pipe: t] + */ + + @bs.send.pipe(: t) external map: ((. elt) => 'b) => typed_array<'b> = "map" + @bs.send.pipe(: t) external mapi: ((. elt, int) => 'b) => typed_array<'b> = "map" + + @bs.send.pipe(: t) external reduce: ((. 'b, elt) => 'b, 'b) => 'b = "reduce" + @bs.send.pipe(: t) external reducei: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @bs.send.pipe(: t) external reduceRight: ((. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @bs.send.pipe(: t) external reduceRighti: ((. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" + @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Float64Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Float64Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Float64Array" + + @new + /** + **raise** Js.Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Float64Array" + + @new + /** + **raise** Js.Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float64Array" + + @new external fromLength: int => t = "Float64Array" + @val external from: array_like => t = "Float64Array.from" + /* *Array.of is redundant, use make */ + @new @deprecated("use `make` instead") external create: array => t = "Float64Array" + @new @deprecated("use `fromBuffer` instead") + external of_buffer: array_buffer => t = "Float64Array" +} +module Float64_array = Float64Array + +/** +The DataView view provides a low-level interface for reading and writing +multiple number types in an ArrayBuffer irrespective of the platform's endianness. + +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) +*/ +module DataView = { + type t = Js_typed_array2.DataView.t + + @new external make: array_buffer => t = "DataView" + @new external fromBuffer: array_buffer => t = "DataView" + @new external fromBufferOffset: (array_buffer, int) => t = "DataView" + @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "DataView" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external getInt8: (t, int) => int = "getInt8" + @send external getUint8: (t, int) => int = "getUint8" + + @send external getInt16: (t, int) => int = "getInt16" + @send external getInt16LittleEndian: (t, int, @as(1) _) => int = "getInt16" + + @send external getUint16: (t, int) => int = "getUint16" + @send external getUint16LittleEndian: (t, int, @as(1) _) => int = "getUint16" + + @send external getInt32: (t, int) => int = "getInt32" + @send external getInt32LittleEndian: (t, int, @as(1) _) => int = "getInt32" + + @send external getUint32: (t, int) => int = "getUint32" + @send external getUint32LittleEndian: (t, int, @as(1) _) => int = "getUint32" + + @send external getFloat32: (t, int) => float = "getFloat32" + @send external getFloat32LittleEndian: (t, int, @as(1) _) => float = "getFloat32" + + @send external getFloat64: (t, int) => float = "getFloat64" + @send external getFloat64LittleEndian: (t, int, @as(1) _) => float = "getFloat64" + + @send external setInt8: (t, int, int) => unit = "setInt8" + @send external setUint8: (t, int, int) => unit = "setUint8" + + @send external setInt16: (t, int, int) => unit = "setInt16" + @send external setInt16LittleEndian: (t, int, int, @as(1) _) => unit = "setInt16" + + @send external setUint16: (t, int, int) => unit = "setUint16" + @send external setUint16LittleEndian: (t, int, int, @as(1) _) => unit = "setUint16" + + @send external setInt32: (t, int, int) => unit = "setInt32" + @send external setInt32LittleEndian: (t, int, int, @as(1) _) => unit = "setInt32" + + @send external setUint32: (t, int, int) => unit = "setUint32" + @send external setUint32LittleEndian: (t, int, int, @as(1) _) => unit = "setUint32" + + @send external setFloat32: (t, int, float) => unit = "setFloat32" + @send external setFloat32LittleEndian: (t, int, float, @as(1) _) => unit = "setFloat32" + + @send external setFloat64: (t, int, float) => unit = "setFloat64" + @send external setFloat64LittleEndian: (t, int, float, @as(1) _) => unit = "setFloat64" +} diff --git a/js/src/js_typed_array2.js b/js/src/js_typed_array2.js new file mode 100644 index 0000000..e9475d9 --- /dev/null +++ b/js/src/js_typed_array2.js @@ -0,0 +1,39 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +var $$ArrayBuffer = {}; + +var $$Int8Array = {}; + +var $$Uint8Array = {}; + +var $$Uint8ClampedArray = {}; + +var $$Int16Array = {}; + +var $$Uint16Array = {}; + +var $$Int32Array = {}; + +var $$Uint32Array = {}; + +var $$Float32Array = {}; + +var $$Float64Array = {}; + +var $$DataView = {}; + +export { + $$ArrayBuffer , + $$Int8Array , + $$Uint8Array , + $$Uint8ClampedArray , + $$Int16Array , + $$Uint16Array , + $$Int32Array , + $$Uint32Array , + $$Float32Array , + $$Float64Array , + $$DataView , +} +/* No side effect */ diff --git a/js/src/js_typed_array2.res b/js/src/js_typed_array2.res new file mode 100644 index 0000000..d4bdc68 --- /dev/null +++ b/js/src/js_typed_array2.res @@ -0,0 +1,1222 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** +JavaScript Typed Array API + +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) +*/ + +type array_buffer +type array_like<'a> /* should be shared with js_array */ + +module ArrayBuffer = { + /*** + The underlying buffer that the typed arrays provide views of + + **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) + */ + + type t = array_buffer + + @new /** takes length. initializes elements to 0 */ + external make: int => t = "ArrayBuffer" + + /* ArrayBuffer.isView: seems pointless with a type system */ + /* experimental + external transfer : array_buffer -> t = "ArrayBuffer.transfer" [@@val] + external transferWithLength : array_buffer -> int -> t = "ArrayBuffer.transfer" [@@val] + */ + + @get external byteLength: t => int = "byteLength" + + @send external slice: (t, ~start: int, ~end_: int) => array_buffer = "slice" + @send external sliceFrom: (t, int) => array_buffer = "slice" +} + +/* commented out until bs has a plan for iterators + external values : t -> elt array_iter = "" [@@send] + */ + +module Int8Array = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Int8Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Int8Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Int8Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Int8Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int8Array" + + @new external fromLength: int => t = "Int8Array" + @val external from: array_like => t = "Int8Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint8Array = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint8Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint8Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint8Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint8Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8Array" + + @new external fromLength: int => t = "Uint8Array" + @val external from: array_like => t = "Uint8Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint8ClampedArray = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint8ClampedArray.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint8ClampedArray" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint8ClampedArray" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint8ClampedArray" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8ClampedArray" + + @new external fromLength: int => t = "Uint8ClampedArray" + @val external from: array_like => t = "Uint8ClampedArray.from" + /* *Array.of is redundant, use make */ +} + +module Int16Array = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Int16Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Int16Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Int16Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Int16Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int16Array" + + @new external fromLength: int => t = "Int16Array" + @val external from: array_like => t = "Int16Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint16Array = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint16Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint16Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint16Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint16Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint16Array" + + @new external fromLength: int => t = "Uint16Array" + @val external from: array_like => t = "Uint16Array.from" + /* *Array.of is redundant, use make */ +} + +module Int32Array = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Int32Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Int32Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Int32Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Int32Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int32Array" + + @new external fromLength: int => t = "Int32Array" + @val external from: array_like => t = "Int32Array.from" + /* *Array.of is redundant, use make */ +} + +module Uint32Array = { + /** */ + type elt = int + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Uint32Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Uint32Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Uint32Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Uint32Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint32Array" + + @new external fromLength: int => t = "Uint32Array" + @val external from: array_like => t = "Uint32Array.from" + /* *Array.of is redundant, use make */ +} + +/* + it still return number, `float` in this case +*/ +module Float32Array = { + /** */ + type elt = float + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Float32Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Float32Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Float32Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Float32Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float32Array" + + @new external fromLength: int => t = "Float32Array" + @val external from: array_like => t = "Float32Array.from" + /* *Array.of is redundant, use make */ +} + +module Float64Array = { + /** */ + type elt = float + type typed_array<'a> + type t = typed_array + + @get_index external unsafe_get: (t, int) => elt = "" + @set_index external unsafe_set: (t, int, elt) => unit = "" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external setArray: (t, array) => unit = "set" + @send external setArrayOffset: (t, array, int) => unit = "set" + /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ + + /* Array interface(-ish) */ + @get external length: t => int = "length" + + /* Mutator functions */ + @send external copyWithin: (t, ~to_: int) => t = "copyWithin" + @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @send external fillInPlace: (t, elt) => t = "fill" + @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @send external reverseInPlace: t => t = "reverse" + + @send external sortInPlace: t => t = "sort" + @send external sortInPlaceWith: (t, (. elt, elt) => int) => t = "sort" + + /* Accessor functions */ + @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @send external indexOf: (t, elt) => int = "indexOf" + @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + + @send external join: t => string = "join" + @send external joinWith: (t, string) => string = "join" + + @send external lastIndexOf: (t, elt) => int = "lastIndexOf" + @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + + @send /** `start` is inclusive, `end_` exclusive */ + external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @send external copy: t => t = "slice" + @send external sliceFrom: (t, int) => t = "slice" + + @send /** `start` is inclusive, `end_` exclusive */ + external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @send external subarrayFrom: (t, int) => t = "subarray" + + @send external toString: t => string = "toString" + @send external toLocaleString: t => string = "toLocaleString" + + /* Iteration functions */ + /* commented out until bs has a plan for iterators + external entries : t -> (int * elt) array_iter = "" [@@send] + */ + @send external every: (t, (. elt) => bool) => bool = "every" + @send external everyi: (t, (. elt, int) => bool) => bool = "every" + + @send external filter: (t, (. elt) => bool) => t = "filter" + @send external filteri: (t, (. elt, int) => bool) => t = "filter" + + @send external find: (t, (. elt) => bool) => Js_undefined.t = "find" + @send external findi: (t, (. elt, int) => bool) => Js_undefined.t = "find" + + @send external findIndex: (t, (. elt) => bool) => int = "findIndex" + @send external findIndexi: (t, (. elt, int) => bool) => int = "findIndex" + + @send external forEach: (t, (. elt) => unit) => unit = "forEach" + @send external forEachi: (t, (. elt, int) => unit) => unit = "forEach" + + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ + + @send external map: (t, (. elt) => 'b) => typed_array<'b> = "map" + @send external mapi: (t, (. elt, int) => 'b) => typed_array<'b> = "map" + + @send external reduce: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduce" + @send external reducei: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduce" + + @send external reduceRight: (t, (. 'b, elt) => 'b, 'b) => 'b = "reduceRight" + @send external reduceRighti: (t, (. 'b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @send external some: (t, (. elt) => bool) => bool = "some" + @send external somei: (t, (. elt, int) => bool) => bool = "some" + + @val external _BYTES_PER_ELEMENT: int = "Float64Array.BYTES_PER_ELEMENT" + + @new external make: array => t = "Float64Array" + @new /** can throw */ + external fromBuffer: array_buffer => t = "Float64Array" + + @new + /** + **raise** Js_Exn.Error raise Js exception + + **param** offset is in bytes + */ + external fromBufferOffset: (array_buffer, int) => t = "Float64Array" + + @new + /** + **raise** Js_Exn.Error raises Js exception + + **param** offset is in bytes, length in elements + */ + external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float64Array" + + @new external fromLength: int => t = "Float64Array" + @val external from: array_like => t = "Float64Array.from" + /* *Array.of is redundant, use make */ +} + +/** +The DataView view provides a low-level interface for reading and writing +multiple number types in an ArrayBuffer irrespective of the platform's endianness. + +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) +*/ +module DataView = { + type t + + @new external make: array_buffer => t = "DataView" + @new external fromBuffer: array_buffer => t = "DataView" + @new external fromBufferOffset: (array_buffer, int) => t = "DataView" + @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "DataView" + + @get external buffer: t => array_buffer = "buffer" + @get external byteLength: t => int = "byteLength" + @get external byteOffset: t => int = "byteOffset" + + @send external getInt8: (t, int) => int = "getInt8" + @send external getUint8: (t, int) => int = "getUint8" + + @send external getInt16: (t, int) => int = "getInt16" + @send external getInt16LittleEndian: (t, int, @as(1) _) => int = "getInt16" + + @send external getUint16: (t, int) => int = "getUint16" + @send external getUint16LittleEndian: (t, int, @as(1) _) => int = "getUint16" + + @send external getInt32: (t, int) => int = "getInt32" + @send external getInt32LittleEndian: (t, int, @as(1) _) => int = "getInt32" + + @send external getUint32: (t, int) => int = "getUint32" + @send external getUint32LittleEndian: (t, int, @as(1) _) => int = "getUint32" + + @send external getFloat32: (t, int) => float = "getFloat32" + @send external getFloat32LittleEndian: (t, int, @as(1) _) => float = "getFloat32" + + @send external getFloat64: (t, int) => float = "getFloat64" + @send external getFloat64LittleEndian: (t, int, @as(1) _) => float = "getFloat64" + + @send external setInt8: (t, int, int) => unit = "setInt8" + @send external setUint8: (t, int, int) => unit = "setUint8" + + @send external setInt16: (t, int, int) => unit = "setInt16" + @send external setInt16LittleEndian: (t, int, int, @as(1) _) => unit = "setInt16" + + @send external setUint16: (t, int, int) => unit = "setUint16" + @send external setUint16LittleEndian: (t, int, int, @as(1) _) => unit = "setUint16" + + @send external setInt32: (t, int, int) => unit = "setInt32" + @send external setInt32LittleEndian: (t, int, int, @as(1) _) => unit = "setInt32" + + @send external setUint32: (t, int, int) => unit = "setUint32" + @send external setUint32LittleEndian: (t, int, int, @as(1) _) => unit = "setUint32" + + @send external setFloat32: (t, int, float) => unit = "setFloat32" + @send external setFloat32LittleEndian: (t, int, float, @as(1) _) => unit = "setFloat32" + + @send external setFloat64: (t, int, float) => unit = "setFloat64" + @send external setFloat64LittleEndian: (t, int, float, @as(1) _) => unit = "setFloat64" +} diff --git a/js/src/js_typeof.js b/js/src/js_typeof.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/js_typeof.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/js_typeof.res b/js/src/js_typeof.res new file mode 100644 index 0000000..2fcf89f --- /dev/null +++ b/js/src/js_typeof.res @@ -0,0 +1,5 @@ +/** +`typeof x` will be compiled as `typeof x` in JS. Please consider functions in +`Js.Types` for a type safe way of reflection. +*/ +external typeof: 'a => string = "#typeof" diff --git a/js/src/js_types.js b/js/src/js_types.js new file mode 100644 index 0000000..cca254c --- /dev/null +++ b/js/src/js_types.js @@ -0,0 +1,77 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function classify(x) { + var ty = typeof x; + if (ty === "undefined") { + return "JSUndefined"; + } else if (x === null) { + return "JSNull"; + } else if (ty === "number") { + return { + TAG: "JSNumber", + _0: x + }; + } else if (ty === "bigint") { + return { + TAG: "JSBigInt", + _0: x + }; + } else if (ty === "string") { + return { + TAG: "JSString", + _0: x + }; + } else if (ty === "boolean") { + if (x === true) { + return "JSTrue"; + } else { + return "JSFalse"; + } + } else if (ty === "symbol") { + return { + TAG: "JSSymbol", + _0: x + }; + } else if (ty === "function") { + return { + TAG: "JSFunction", + _0: x + }; + } else { + return { + TAG: "JSObject", + _0: x + }; + } +} + +function test(x, v) { + switch (v) { + case "Undefined" : + return typeof x === "undefined"; + case "Null" : + return x === null; + case "Boolean" : + return typeof x === "boolean"; + case "Number" : + return typeof x === "number"; + case "String" : + return typeof x === "string"; + case "Function" : + return typeof x === "function"; + case "Object" : + return typeof x === "object"; + case "Symbol" : + return typeof x === "symbol"; + case "BigInt" : + return typeof x === "bigint"; + + } +} + +export { + test , + classify , +} +/* No side effect */ diff --git a/js/src/js_types.res b/js/src/js_types.res new file mode 100644 index 0000000..9735ef0 --- /dev/null +++ b/js/src/js_types.res @@ -0,0 +1,101 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/** Js symbol type only available in ES6 */ +type symbol + +/** Js bigint type only available in ES2020 */ +type bigint_val = bigint + +type obj_val +/** This type has only one value `undefined` */ +type undefined_val + +/** This type has only one value `null` */ +type null_val + +type function_val + +type rec t<_> = + | Undefined: t + | Null: t + | Boolean: t + | Number: t + | String: t + | Function: t + | Object: t + | Symbol: t + | BigInt: t + +type tagged_t = + | JSFalse + | JSTrue + | JSNull + | JSUndefined + | JSNumber(float) + | JSString(string) + | JSFunction(function_val) + | JSObject(obj_val) + | JSSymbol(symbol) + | JSBigInt(bigint_val) + +let classify = (x: 'a): tagged_t => { + let ty = Js_typeof.typeof(x) + if ty == "undefined" { + JSUndefined + } else if x === Obj.magic(Js_null.empty) { + JSNull + } else if ty == "number" { + JSNumber(Obj.magic(x)) + } else if ty == "bigint" { + JSBigInt(Obj.magic(x)) + } else if ty == "string" { + JSString(Obj.magic(x)) + } else if ty == "boolean" { + if Obj.magic(x) == true { + JSTrue + } else { + JSFalse + } + } else if ty == "symbol" { + JSSymbol(Obj.magic(x)) + } else if ty == "function" { + JSFunction(Obj.magic(x)) + } else { + JSObject(Obj.magic(x)) + } +} + +let test = (type a, x: 'a, v: t): bool => + switch v { + | Number => Js_typeof.typeof(x) == "number" + | Boolean => Js_typeof.typeof(x) == "boolean" + | Undefined => Js_typeof.typeof(x) == "undefined" + | Null => x === Obj.magic(Js_null.empty) + | String => Js_typeof.typeof(x) == "string" + | Function => Js_typeof.typeof(x) == "function" + | Object => Js_typeof.typeof(x) == "object" + | Symbol => Js_typeof.typeof(x) == "symbol" + | BigInt => Js_typeof.typeof(x) == "bigint" + } diff --git a/js/src/js_types.resi b/js/src/js_types.resi new file mode 100644 index 0000000..f267cd2 --- /dev/null +++ b/js/src/js_types.resi @@ -0,0 +1,80 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provide utilities for manipulating JS types. */ + +/** Js symbol type (only available in ES6) */ +type symbol + +/** Js bigint type only available in ES2020 */ +type bigint_val + +type obj_val + +/** This type has only one value `undefined` */ +type undefined_val + +/** This type has only one value `null` */ +type null_val + +type function_val + +type rec t<_> = + | Undefined: t + | Null: t + | Boolean: t + | Number: t + | String: t + | Function: t + | Object: t + | Symbol: t + | BigInt: t + +/** +`test(value, t)` returns `true` if `value` is `typeof t`, otherwise `false`. +This is useful for doing runtime reflection on any given value. + +## Examples + +```rescript +test("test", String) == true +test(() => true, Function) == true +test("test", Boolean) == false +``` +*/ +let test: ('a, t<'b>) => bool + +type tagged_t = + | JSFalse + | JSTrue + | JSNull + | JSUndefined + | JSNumber(float) + | JSString(string) + | JSFunction(function_val) + | JSObject(obj_val) + | JSSymbol(symbol) + | JSBigInt(bigint_val) + +let classify: 'a => tagged_t diff --git a/js/src/js_undefined.js b/js/src/js_undefined.js new file mode 100644 index 0000000..6f8749e --- /dev/null +++ b/js/src/js_undefined.js @@ -0,0 +1,54 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Js_exn from "./js_exn.js"; +import * as Caml_option from "rescript/lib/es6/caml_option.js"; + +function test(x) { + return x === undefined; +} + +function testAny(x) { + return x === undefined; +} + +function getExn(f) { + if (f !== undefined) { + return f; + } else { + return Js_exn.raiseError("Js_undefined.getExn"); + } +} + +function bind(x, f) { + if (x !== undefined) { + return f(x); + } + +} + +function iter(x, f) { + if (x !== undefined) { + return f(x); + } + +} + +function fromOption(x) { + if (x !== undefined) { + return Caml_option.valFromOption(x); + } + +} + +var from_opt = fromOption; + +export { + test , + testAny , + getExn , + bind , + iter , + fromOption , + from_opt , +} +/* No side effect */ diff --git a/js/src/js_undefined.res b/js/src/js_undefined.res new file mode 100644 index 0000000..95c7666 --- /dev/null +++ b/js/src/js_undefined.res @@ -0,0 +1,61 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provides functionality for dealing with the `'a undefined` type */ + +type t<+'a> = Runtime_types.undefined<'a> +external to_opt: t<'a> => option<'a> = "#undefined_to_opt" +external toOption: t<'a> => option<'a> = "#undefined_to_opt" +external return: 'a => t<'a> = "%identity" + +external empty: t<'a> = "#undefined" +let test: t<'a> => bool = x => x == empty +let testAny: 'a => bool = x => Obj.magic(x) == empty +external getUnsafe: t<'a> => 'a = "%identity" + +let getExn = f => + switch toOption(f) { + | None => Js_exn.raiseError("Js_undefined.getExn") + | Some(x) => x + } + +let bind = (x, f) => + switch to_opt(x) { + | None => empty + | Some(x) => return(f(x)) + } + +let iter = (x, f) => + switch to_opt(x) { + | None => () + | Some(x) => f(x) + } + +let fromOption = x => + switch x { + | None => empty + | Some(x) => return(x) + } + +let from_opt = fromOption diff --git a/js/src/js_undefined.resi b/js/src/js_undefined.resi new file mode 100644 index 0000000..bd85f32 --- /dev/null +++ b/js/src/js_undefined.resi @@ -0,0 +1,95 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Provides functionality for dealing with the `Js.undefined<'a>` type */ + +/** Local alias for `Js.undefined<'a>` */ +type t<+'a> = Runtime_types.undefined<'a> + +/** Constructs a value of `Js.undefined<'a>` containing a value of `'a`. */ +external return: 'a => t<'a> = "%identity" + +@deprecated("Use = Js.undefined directly") +/** Returns `true` if the given value is empty (undefined), `false` otherwise. */ +let test: t<'a> => bool + +/** +Returns `true` if the given value is empty (undefined). + +**since 1.6.1** +*/ +let testAny: 'a => bool + +/** The empty value, `undefined` */ +external empty: t<'a> = "#undefined" + +external getUnsafe: t<'a> => 'a = "%identity" +let getExn: t<'a> => 'a + +/** +Maps the contained value using the given function. +If `Js.undefined<'a>` contains a value, that value is unwrapped, mapped to a +`'b` using the given function `a' => 'b`, then wrapped back up and returned as +`Js.undefined<'b>`. + +## Examples + +```rescript +let maybeGreetWorld = (maybeGreeting: Js.undefined) => + Js.Undefined.bind(maybeGreeting, (. greeting) => greeting ++ " world!") +``` +*/ +let bind: (t<'a>, 'a => 'b) => t<'b> + +/** +Iterates over the contained value with the given function. If +`Js.undefined<'a>` contains a value, that value is unwrapped and applied to the +given function. + +## Examples + +```rescript +let maybeSay = (maybeMessage: Js.undefined) => + Js.Undefined.iter(maybeMessage, (. message) => Js.log(message)) +``` +*/ +let iter: (t<'a>, 'a => unit) => unit + +/** +Maps `option<'a>` to `Js.undefined<'a>`. +`Some(a)` => `a` +`None` => `empty` +*/ +let fromOption: option<'a> => t<'a> + +@deprecated("Use fromOption instead") let from_opt: option<'a> => t<'a> + +/** +Maps `Js.undefined<'a>` to `option<'a>` +`a` => `Some(a)` +`empty` => `None` +*/ +external toOption: t<'a> => option<'a> = "#undefined_to_opt" + +@deprecated("use toOption instead") external to_opt: t<'a> => option<'a> = "#undefined_to_opt" diff --git a/js/src/js_vector.res b/js/src/js_vector.res new file mode 100644 index 0000000..15b1ff0 --- /dev/null +++ b/js/src/js_vector.res @@ -0,0 +1,149 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +type t<'a> = array<'a> + +external length: array<'a> => int = "%array_length" +external get: (array<'a>, int) => 'a = "%array_safe_get" +external set: (array<'a>, int, 'a) => unit = "%array_safe_set" +external make: (int, 'a) => array<'a> = "?make_vect" +external unsafe_get: (t<'a>, int) => 'a = "%array_unsafe_get" +external unsafe_set: (t<'a>, int, 'a) => unit = "%array_unsafe_set" + +/** +**param** a array + +**param** p predicate +*/ +let filterInPlace = (p, a) => { + let i = ref(0) + let j = ref(0) + while i.contents < Js_array2.length(a) { + let v = Js_array2.unsafe_get(a, i.contents) + if p(. v) { + Js_array2.unsafe_set(a, j.contents, v) + j.contents = j.contents + 1 + } + i.contents = i.contents + 1 + } + Js_array2.removeFromInPlace(a, ~pos=j.contents)->ignore +} + +let empty = a => Js_array2.removeFromInPlace(a, ~pos=0)->ignore + +let pushBack = (x, xs) => Js_array2.push(xs, x)->ignore + +/** Find by JS (===) equality */ +let memByRef = (x, xs) => Js_array2.indexOf(xs, x) >= 0 + +let iter = (f, xs) => + for i in 0 to Js_array2.length(xs) - 1 { + f(. Js_array2.unsafe_get(xs, i)) + } + +let iteri = (f, a) => + for i in 0 to length(a) - 1 { + f(. i, unsafe_get(a, i)) + } + +@new external createUnsafe: int => t<'a> = "Array" + +/* let ofList xs = */ +/* match xs with */ +/* | [] -> [||] */ +/* | l -> */ +/* let a = createUnsafe (Js_list.length l) in */ +/* let rec fill i = function */ +/* | [] -> a */ +/* | hd::tl -> Array.unsafe_set a i hd; fill (i+1) tl in */ +/* fill 0 l */ + +let toList = a => { + let rec tolist = (i, res) => + if i < 0 { + res + } else { + tolist(i - 1, list{unsafe_get(a, i), ...res}) + } + tolist(length(a) - 1, list{}) +} + +let init = (n, f) => { + let v = createUnsafe(n) + for i in 0 to n - 1 { + unsafe_set(v, i, f(. i)) + } + v +} + +let copy = x => { + let len = length(x) + let b = createUnsafe(len) + for i in 0 to len - 1 { + unsafe_set(b, i, unsafe_get(x, i)) + } + b +} + +let map = (f, a) => { + let l = Js_array2.length(a) + let r = createUnsafe(l) + for i in 0 to l - 1 { + unsafe_set(r, i, f(. unsafe_get(a, i))) + } + r +} + +let foldLeft = (f, x, a) => { + let r = ref(x) + for i in 0 to length(a) - 1 { + r.contents = f(. r.contents, unsafe_get(a, i)) + } + r.contents +} + +let foldRight = (f, a, x) => { + let r = ref(x) + for i in length(a) - 1 downto 0 { + r.contents = f(. unsafe_get(a, i), r.contents) + } + r.contents +} + +let mapi = (f, a) => { + let l = length(a) + if l == 0 { + [] + } else { + let r = createUnsafe(l) + for i in 0 to l - 1 { + unsafe_set(r, i, f(. i, unsafe_get(a, i))) + } + r + } +} + +let append = (x, a) => Js_array2.concat(a, [x]) + +/* TODO: add `append` */ diff --git a/js/src/js_vector.resi b/js/src/js_vector.resi new file mode 100644 index 0000000..6218e9a --- /dev/null +++ b/js/src/js_vector.resi @@ -0,0 +1,92 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +@@deprecated("Use Belt.Array instead") + +type t<'a> = array<'a> + +let filterInPlace: ((. 'a) => bool, t<'a>) => unit +let empty: t<'a> => unit +let pushBack: ('a, t<'a>) => unit + +/** shallow copy */ +let copy: t<'a> => t<'a> + +let memByRef: ('a, t<'a>) => bool +let iter: ((. 'a) => unit, t<'a>) => unit +let iteri: ((. int, 'a) => unit, t<'a>) => unit + +/* [@@deprecated "Use Js.List.toVector instead"] */ +/* val ofList : 'a list -> 'a t */ +/* removed, we choose that [`Js.List`]() depends on Vector to avoid cylic dependency + */ + +let toList: t<'a> => list<'a> +let map: ((. 'a) => 'b, t<'a>) => t<'b> +let mapi: ((. int, 'a) => 'b, t<'a>) => t<'b> +let foldLeft: ((. 'a, 'b) => 'a, 'a, t<'b>) => 'a +let foldRight: ((. 'b, 'a) => 'a, t<'b>, 'a) => 'a + +/** Return the length (number of elements) of the given array. */ +external length: t<'a> => int = "%array_length" + +/** +`Vector.get(a, n)` returns the element number `n` of vector `a`. The first +element has number 0. The last element has number `Vector.length(a) - 1`. You +can also write `a[n]` instead of `Vector.get(a, n)`. Raise `Invalid_argument +"index out of bounds"` if `n` is outside the range 0 to (`Array.length(a) - +1`). +*/ +external get: (t<'a>, int) => 'a = "%array_safe_get" + +/** +`Vector.set(a, n, x)` modifies vector `a` in place, replacing element number +`n` with `x`. Raise `Invalid_argument "index out of bounds"` if `n` is outside +the range 0 to `Array.length(a) - 1`. +*/ +external set: (t<'a>, int, 'a) => unit = "%array_safe_set" + +/** +`Vector.make(n, x)` returns a fresh vector of length `n`, initialized with `x`. +All the elements of this new vector are initially physically equal to `x` (in +the sense of the `==` predicate). Consequently, if `x` is mutable, it is shared +among all elements of the array, and modifying `x` through one of the array +entries will modify all other entries at the same time. Raise +`Invalid_argument` if `n < 0` or `n > Sys.max_array_length`. If the value of +`x` is a floating-point number, then the maximum size is only +`Sys.max_array_length / 2`. +*/ +external make: (int, 'a) => t<'a> = "?make_vect" + +/** +Raises `RangeError` when n is negative. +n : size +*/ +let init: (int, (. int) => 'a) => t<'a> + +/** `append(x, a)` returns a fresh vector with `x` appended to `a`. */ +let append: ('a, t<'a>) => t<'a> + +external unsafe_get: (t<'a>, int) => 'a = "%array_unsafe_get" +external unsafe_set: (t<'a>, int, 'a) => unit = "%array_unsafe_set" diff --git a/js/src/js_weakmap.res b/js/src/js_weakmap.res new file mode 100644 index 0000000..926ceaf --- /dev/null +++ b/js/src/js_weakmap.res @@ -0,0 +1,3 @@ +/*** ES6 WeakMap API */ + +type t<'k, 'v> diff --git a/js/src/js_weakset.res b/js/src/js_weakset.res new file mode 100644 index 0000000..e9652c4 --- /dev/null +++ b/js/src/js_weakset.res @@ -0,0 +1,3 @@ +/*** ES6 WeakSet API */ + +type t<'a> diff --git a/js/src/jsx.js b/js/src/jsx.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/jsx.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/jsx.res b/js/src/jsx.res new file mode 100644 index 0000000..70f3c67 --- /dev/null +++ b/js/src/jsx.res @@ -0,0 +1,20 @@ +/*** Internal: use Jsx directly. */ + +@@uncurried + +type element +type ref + +@val external null: element = "null" + +external float: float => element = "%identity" +external int: int => element = "%identity" +external string: string => element = "%identity" + +external array: array => element = "%identity" + +type componentLike<'props, 'return> = 'props => 'return +type component<'props> = componentLike<'props, element> + +/* this function exists to prepare for making `component` abstract */ +external component: componentLike<'props, element> => component<'props> = "%identity" diff --git a/js/src/jsxDOM.js b/js/src/jsxDOM.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/js/src/jsxDOM.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/js/src/jsxDOM.res b/js/src/jsxDOM.res new file mode 100644 index 0000000..b2fc927 --- /dev/null +++ b/js/src/jsxDOM.res @@ -0,0 +1,624 @@ +/* Copyright (C) 2022- Authors of ReScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Internal: use JsxDOM directly. */ + +@@uncurried + +type style = JsxDOMStyle.t +type domRef + +/* + This list isn't exhaustive. We'll add more as we go. +*/ +type domProps = { + key?: string, + children?: Jsx.element, + ref?: domRef, + /* accessibility */ + /* https://www.w3.org/TR/wai-aria-1.1/ */ + /* https://accessibilityresources.org/ is a great resource for these */ + @as("aria-current") + ariaCurrent?: [#page | #step | #location | #date | #time | #"true" | #"false"], + @as("aria-details") + ariaDetails?: string, + @as("aria-disabled") + ariaDisabled?: bool, + @as("aria-hidden") + ariaHidden?: bool, + @as("aria-invalid") ariaInvalid?: [#grammar | #"false" | #spelling | #"true"], + @as("aria-keyshortcuts") + ariaKeyshortcuts?: string, + @as("aria-label") + ariaLabel?: string, + @as("aria-roledescription") + ariaRoledescription?: string, + /* Widget Attributes */ + @as("aria-autocomplete") ariaAutocomplete?: [#inline | #list | #both | #none], + /* https://www.w3.org/TR/wai-aria-1.1/#valuetype_tristate */ + @as("aria-checked") + ariaChecked?: [#"true" | #"false" | #mixed], + @as("aria-expanded") + ariaExpanded?: bool, + @as("aria-haspopup") + ariaHaspopup?: [#menu | #listbox | #tree | #grid | #dialog | #"true" | #"false"], + @as("aria-level") + ariaLevel?: int, + @as("aria-modal") + ariaModal?: bool, + @as("aria-multiline") + ariaMultiline?: bool, + @as("aria-multiselectable") + ariaMultiselectable?: bool, + @as("aria-orientation") ariaOrientation?: [#horizontal | #vertical | #undefined], + @as("aria-placeholder") + ariaPlaceholder?: string, + /* https://www.w3.org/TR/wai-aria-1.1/#valuetype_tristate */ + @as("aria-pressed") ariaPressed?: [#"true" | #"false" | #mixed], + @as("aria-readonly") + ariaReadonly?: bool, + @as("aria-required") + ariaRequired?: bool, + @as("aria-selected") + ariaSelected?: bool, + @as("aria-sort") + ariaSort?: string, + @as("aria-valuemax") + ariaValuemax?: float, + @as("aria-valuemin") + ariaValuemin?: float, + @as("aria-valuenow") + ariaValuenow?: float, + @as("aria-valuetext") + ariaValuetext?: string, + /* Live Region Attributes */ + @as("aria-atomic") + ariaAtomic?: bool, + @as("aria-busy") + ariaBusy?: bool, + @as("aria-live") ariaLive?: [#off | #polite | #assertive | #rude], + @as("aria-relevant") + ariaRelevant?: string, + /* Drag-and-Drop Attributes */ + @as("aria-dropeffect") ariaDropeffect?: [#copy | #move | #link | #execute | #popup | #none], + @as("aria-grabbed") + ariaGrabbed?: bool, + /* Relationship Attributes */ + @as("aria-activedescendant") + ariaActivedescendant?: string, + @as("aria-colcount") + ariaColcount?: int, + @as("aria-colindex") + ariaColindex?: int, + @as("aria-colspan") + ariaColspan?: int, + @as("aria-controls") + ariaControls?: string, + @as("aria-describedby") + ariaDescribedby?: string, + @as("aria-errormessage") + ariaErrormessage?: string, + @as("aria-flowto") + ariaFlowto?: string, + @as("aria-labelledby") + ariaLabelledby?: string, + @as("aria-owns") + ariaOwns?: string, + @as("aria-posinset") + ariaPosinset?: int, + @as("aria-rowcount") + ariaRowcount?: int, + @as("aria-rowindex") + ariaRowindex?: int, + @as("aria-rowspan") + ariaRowspan?: int, + @as("aria-setsize") + ariaSetsize?: int, + /* react textarea/input */ + defaultChecked?: bool, + defaultValue?: string, + /* global html attributes */ + accessKey?: string, + className?: string /* substitute for "class" */, + contentEditable?: bool, + contextMenu?: string, + @as("data-testid") dataTestId?: string, + dir?: string /* "ltr", "rtl" or "auto" */, + draggable?: bool, + hidden?: bool, + id?: string, + lang?: string, + role?: string /* ARIA role */, + style?: style, + spellCheck?: bool, + tabIndex?: int, + title?: string, + /* html5 microdata */ + itemID?: string, + itemProp?: string, + itemRef?: string, + itemScope?: bool, + itemType?: string /* uri */, + /* tag-specific html attributes */ + accept?: string, + acceptCharset?: string, + action?: string /* uri */, + allowFullScreen?: bool, + alt?: string, + @as("as") + as_?: string, + async?: bool, + autoComplete?: string /* has a fixed, but large-ish, set of possible values */, + autoCapitalize?: string /* Mobile Safari specific */, + autoFocus?: bool, + autoPlay?: bool, + challenge?: string, + charSet?: string, + checked?: bool, + cite?: string /* uri */, + crossOrigin?: string /* anonymous, use-credentials */, + cols?: int, + colSpan?: int, + content?: string, + controls?: bool, + coords?: string /* set of values specifying the coordinates of a region */, + data?: string /* uri */, + dateTime?: string /* "valid date string with optional time" */, + default?: bool, + defer?: bool, + disabled?: bool, + download?: string /* should really be either a boolean, signifying presence, or a string */, + encType?: string /* "application/x-www-form-urlencoded", "multipart/form-data" or "text/plain" */, + form?: string, + formAction?: string /* uri */, + formTarget?: string /* "_blank", "_self", etc. */, + formMethod?: string /* "post", "get", "put" */, + headers?: string, + height?: string /* in html5 this can only be a number, but in html4 it can ba a percentage as well */, + high?: int, + href?: string /* uri */, + hrefLang?: string, + htmlFor?: string /* substitute for "for" */, + httpEquiv?: string /* has a fixed set of possible values */, + icon?: string /* uri? */, + inputMode?: string /* "verbatim", "latin", "numeric", etc. */, + integrity?: string, + keyType?: string, + kind?: string /* has a fixed set of possible values */, + label?: string, + list?: string, + loading?: [#"lazy" | #eager], + loop?: bool, + low?: int, + manifest?: string /* uri */, + max?: string /* should be int or Js.Date.t */, + maxLength?: int, + media?: string /* a valid media query */, + mediaGroup?: string, + method?: string /* "post" or "get" */, + min?: string, + minLength?: int, + multiple?: bool, + muted?: bool, + name?: string, + nonce?: string, + noValidate?: bool, + @as("open") + open_?: bool /* use this one. Previous one is deprecated */, + optimum?: int, + pattern?: string /* valid Js RegExp */, + placeholder?: string, + playsInline?: bool, + poster?: string /* uri */, + preload?: string /* "none", "metadata" or "auto" (and "" as a synonym for "auto") */, + radioGroup?: string, + readOnly?: bool, + rel?: string /* a space- or comma-separated (depending on the element) list of a fixed set of "link types" */, + required?: bool, + reversed?: bool, + rows?: int, + rowSpan?: int, + sandbox?: string /* has a fixed set of possible values */, + scope?: string /* has a fixed set of possible values */, + scoped?: bool, + scrolling?: string /* html4 only, "auto", "yes" or "no" */, + /* seamless - supported by React, but removed from the html5 spec */ + selected?: bool, + shape?: string, + size?: int, + sizes?: string, + span?: int, + src?: string /* uri */, + srcDoc?: string, + srcLang?: string, + srcSet?: string, + start?: int, + step?: float, + summary?: string /* deprecated */, + target?: string, + @as("type") + type_?: string /* has a fixed but large-ish set of possible values */ /* use this one. Previous one is deprecated */, + useMap?: string, + value?: string, + width?: string /* in html5 this can only be a number, but in html4 it can ba a percentage as well */, + wrap?: string /* "hard" or "soft" */, + /* Clipboard events */ + onCopy?: JsxEvent.Clipboard.t => unit, + onCut?: JsxEvent.Clipboard.t => unit, + onPaste?: JsxEvent.Clipboard.t => unit, + /* Composition events */ + onCompositionEnd?: JsxEvent.Composition.t => unit, + onCompositionStart?: JsxEvent.Composition.t => unit, + onCompositionUpdate?: JsxEvent.Composition.t => unit, + /* Keyboard events */ + onKeyDown?: JsxEvent.Keyboard.t => unit, + onKeyPress?: JsxEvent.Keyboard.t => unit, + onKeyUp?: JsxEvent.Keyboard.t => unit, + /* Focus events */ + onFocus?: JsxEvent.Focus.t => unit, + onBlur?: JsxEvent.Focus.t => unit, + /* Form events */ + onBeforeInput?: JsxEvent.Form.t => unit, + onChange?: JsxEvent.Form.t => unit, + onInput?: JsxEvent.Form.t => unit, + onReset?: JsxEvent.Form.t => unit, + onSubmit?: JsxEvent.Form.t => unit, + onInvalid?: JsxEvent.Form.t => unit, + /* Mouse events */ + onClick?: JsxEvent.Mouse.t => unit, + onContextMenu?: JsxEvent.Mouse.t => unit, + onDoubleClick?: JsxEvent.Mouse.t => unit, + onDrag?: JsxEvent.Mouse.t => unit, + onDragEnd?: JsxEvent.Mouse.t => unit, + onDragEnter?: JsxEvent.Mouse.t => unit, + onDragExit?: JsxEvent.Mouse.t => unit, + onDragLeave?: JsxEvent.Mouse.t => unit, + onDragOver?: JsxEvent.Mouse.t => unit, + onDragStart?: JsxEvent.Mouse.t => unit, + onDrop?: JsxEvent.Mouse.t => unit, + onMouseDown?: JsxEvent.Mouse.t => unit, + onMouseEnter?: JsxEvent.Mouse.t => unit, + onMouseLeave?: JsxEvent.Mouse.t => unit, + onMouseMove?: JsxEvent.Mouse.t => unit, + onMouseOut?: JsxEvent.Mouse.t => unit, + onMouseOver?: JsxEvent.Mouse.t => unit, + onMouseUp?: JsxEvent.Mouse.t => unit, + /* Selection events */ + onSelect?: JsxEvent.Selection.t => unit, + /* Touch events */ + onTouchCancel?: JsxEvent.Touch.t => unit, + onTouchEnd?: JsxEvent.Touch.t => unit, + onTouchMove?: JsxEvent.Touch.t => unit, + onTouchStart?: JsxEvent.Touch.t => unit, + // Pointer events + onPointerOver?: JsxEvent.Pointer.t => unit, + onPointerEnter?: JsxEvent.Pointer.t => unit, + onPointerDown?: JsxEvent.Pointer.t => unit, + onPointerMove?: JsxEvent.Pointer.t => unit, + onPointerUp?: JsxEvent.Pointer.t => unit, + onPointerCancel?: JsxEvent.Pointer.t => unit, + onPointerOut?: JsxEvent.Pointer.t => unit, + onPointerLeave?: JsxEvent.Pointer.t => unit, + onGotPointerCapture?: JsxEvent.Pointer.t => unit, + onLostPointerCapture?: JsxEvent.Pointer.t => unit, + /* UI events */ + onScroll?: JsxEvent.UI.t => unit, + /* Wheel events */ + onWheel?: JsxEvent.Wheel.t => unit, + /* Media events */ + onAbort?: JsxEvent.Media.t => unit, + onCanPlay?: JsxEvent.Media.t => unit, + onCanPlayThrough?: JsxEvent.Media.t => unit, + onDurationChange?: JsxEvent.Media.t => unit, + onEmptied?: JsxEvent.Media.t => unit, + onEncrypted?: JsxEvent.Media.t => unit, + onEnded?: JsxEvent.Media.t => unit, + onError?: JsxEvent.Media.t => unit, + onLoadedData?: JsxEvent.Media.t => unit, + onLoadedMetadata?: JsxEvent.Media.t => unit, + onLoadStart?: JsxEvent.Media.t => unit, + onPause?: JsxEvent.Media.t => unit, + onPlay?: JsxEvent.Media.t => unit, + onPlaying?: JsxEvent.Media.t => unit, + onProgress?: JsxEvent.Media.t => unit, + onRateChange?: JsxEvent.Media.t => unit, + onSeeked?: JsxEvent.Media.t => unit, + onSeeking?: JsxEvent.Media.t => unit, + onStalled?: JsxEvent.Media.t => unit, + onSuspend?: JsxEvent.Media.t => unit, + onTimeUpdate?: JsxEvent.Media.t => unit, + onVolumeChange?: JsxEvent.Media.t => unit, + onWaiting?: JsxEvent.Media.t => unit, + /* Image events */ + onLoad?: JsxEvent.Image.t => unit /* duplicate */ /* ~onError: ReactEvent.Image.t => unit=?, */, + /* Animation events */ + onAnimationStart?: JsxEvent.Animation.t => unit, + onAnimationEnd?: JsxEvent.Animation.t => unit, + onAnimationIteration?: JsxEvent.Animation.t => unit, + /* Transition events */ + onTransitionEnd?: JsxEvent.Transition.t => unit, + /* svg */ + accentHeight?: string, + accumulate?: string, + additive?: string, + alignmentBaseline?: string, + allowReorder?: string, + alphabetic?: string, + amplitude?: string, + arabicForm?: string, + ascent?: string, + attributeName?: string, + attributeType?: string, + autoReverse?: string, + azimuth?: string, + baseFrequency?: string, + baseProfile?: string, + baselineShift?: string, + bbox?: string, + begin?: string, + @deprecated("Please use begin") + begin_?: string, + bias?: string, + by?: string, + calcMode?: string, + capHeight?: string, + clip?: string, + clipPath?: string, + clipPathUnits?: string, + clipRule?: string, + colorInterpolation?: string, + colorInterpolationFilters?: string, + colorProfile?: string, + colorRendering?: string, + contentScriptType?: string, + contentStyleType?: string, + cursor?: string, + cx?: string, + cy?: string, + d?: string, + decelerate?: string, + descent?: string, + diffuseConstant?: string, + direction?: string, + display?: string, + divisor?: string, + dominantBaseline?: string, + dur?: string, + dx?: string, + dy?: string, + edgeMode?: string, + elevation?: string, + enableBackground?: string, + end?: string, + @deprecated("Please use end") + end_?: string, + exponent?: string, + externalResourcesRequired?: string, + fill?: string, + fillOpacity?: string, + fillRule?: string, + filter?: string, + filterRes?: string, + filterUnits?: string, + floodColor?: string, + floodOpacity?: string, + focusable?: string, + fontFamily?: string, + fontSize?: string, + fontSizeAdjust?: string, + fontStretch?: string, + fontStyle?: string, + fontVariant?: string, + fontWeight?: string, + fomat?: string, + from?: string, + fx?: string, + fy?: string, + g1?: string, + g2?: string, + glyphName?: string, + glyphOrientationHorizontal?: string, + glyphOrientationVertical?: string, + glyphRef?: string, + gradientTransform?: string, + gradientUnits?: string, + hanging?: string, + horizAdvX?: string, + horizOriginX?: string, + ideographic?: string, + imageRendering?: string, + @as("in") + in_?: string /* use this one. Previous one is deprecated */, + in2?: string, + intercept?: string, + k?: string, + k1?: string, + k2?: string, + k3?: string, + k4?: string, + kernelMatrix?: string, + kernelUnitLength?: string, + kerning?: string, + keyPoints?: string, + keySplines?: string, + keyTimes?: string, + lengthAdjust?: string, + letterSpacing?: string, + lightingColor?: string, + limitingConeAngle?: string, + local?: string, + markerEnd?: string, + markerHeight?: string, + markerMid?: string, + markerStart?: string, + markerUnits?: string, + markerWidth?: string, + mask?: string, + maskContentUnits?: string, + maskUnits?: string, + mathematical?: string, + mode?: string, + numOctaves?: string, + offset?: string, + opacity?: string, + operator?: string, + order?: string, + orient?: string, + orientation?: string, + origin?: string, + overflow?: string, + overflowX?: string, + overflowY?: string, + overlinePosition?: string, + overlineThickness?: string, + paintOrder?: string, + panose1?: string, + pathLength?: string, + patternContentUnits?: string, + patternTransform?: string, + patternUnits?: string, + pointerEvents?: string, + points?: string, + pointsAtX?: string, + pointsAtY?: string, + pointsAtZ?: string, + preserveAlpha?: string, + preserveAspectRatio?: string, + primitiveUnits?: string, + r?: string, + radius?: string, + refX?: string, + refY?: string, + renderingIntent?: string, + repeatCount?: string, + repeatDur?: string, + requiredExtensions?: string, + requiredFeatures?: string, + restart?: string, + result?: string, + rotate?: string, + rx?: string, + ry?: string, + scale?: string, + seed?: string, + shapeRendering?: string, + slope?: string, + spacing?: string, + specularConstant?: string, + specularExponent?: string, + speed?: string, + spreadMethod?: string, + startOffset?: string, + stdDeviation?: string, + stemh?: string, + stemv?: string, + stitchTiles?: string, + stopColor?: string, + stopOpacity?: string, + strikethroughPosition?: string, + strikethroughThickness?: string, + string?: string, + stroke?: string, + strokeDasharray?: string, + strokeDashoffset?: string, + strokeLinecap?: string, + strokeLinejoin?: string, + strokeMiterlimit?: string, + strokeOpacity?: string, + strokeWidth?: string, + surfaceScale?: string, + systemLanguage?: string, + tableValues?: string, + targetX?: string, + targetY?: string, + textAnchor?: string, + textDecoration?: string, + textLength?: string, + textRendering?: string, + to?: string, + @deprecated("Please use to") + to_?: string, + transform?: string, + u1?: string, + u2?: string, + underlinePosition?: string, + underlineThickness?: string, + unicode?: string, + unicodeBidi?: string, + unicodeRange?: string, + unitsPerEm?: string, + vAlphabetic?: string, + vHanging?: string, + vIdeographic?: string, + vMathematical?: string, + values?: string, + vectorEffect?: string, + version?: string, + vertAdvX?: string, + vertAdvY?: string, + vertOriginX?: string, + vertOriginY?: string, + viewBox?: string, + viewTarget?: string, + visibility?: string, + /* width::string? => */ + widths?: string, + wordSpacing?: string, + writingMode?: string, + x?: string, + x1?: string, + x2?: string, + xChannelSelector?: string, + xHeight?: string, + xlinkActuate?: string, + xlinkArcrole?: string, + xlinkHref?: string, + xlinkRole?: string, + xlinkShow?: string, + xlinkTitle?: string, + xlinkType?: string, + xmlns?: string, + xmlnsXlink?: string, + xmlBase?: string, + xmlLang?: string, + xmlSpace?: string, + y?: string, + y1?: string, + y2?: string, + yChannelSelector?: string, + z?: string, + zoomAndPan?: string, + /* RDFa */ + about?: string, + datatype?: string, + inlist?: string, + prefix?: string, + property?: string, + resource?: string, + typeof?: string, + vocab?: string, + /* react-specific */ + dangerouslySetInnerHTML?: {"__html": string}, + suppressContentEditableWarning?: bool, +} diff --git a/js/src/jsxDOMStyle.res b/js/src/jsxDOMStyle.res new file mode 100644 index 0000000..283607e --- /dev/null +++ b/js/src/jsxDOMStyle.res @@ -0,0 +1,437 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +type t = { + azimuth?: string, + backdropFilter?: string, + background?: string, + backgroundAttachment?: string, + backgroundColor?: string, + backgroundImage?: string, + backgroundPosition?: string, + backgroundRepeat?: string, + border?: string, + borderCollapse?: string, + borderColor?: string, + borderSpacing?: string, + borderStyle?: string, + borderTop?: string, + borderRight?: string, + borderBottom?: string, + borderLeft?: string, + borderTopColor?: string, + borderRightColor?: string, + borderBottomColor?: string, + borderLeftColor?: string, + borderTopStyle?: string, + borderRightStyle?: string, + borderBottomStyle?: string, + borderLeftStyle?: string, + borderTopWidth?: string, + borderRightWidth?: string, + borderBottomWidth?: string, + borderLeftWidth?: string, + borderWidth?: string, + bottom?: string, + captionSide?: string, + clear?: string, + clip?: string, + color?: string, + content?: string, + counterIncrement?: string, + counterReset?: string, + cue?: string, + cueAfter?: string, + cueBefore?: string, + cursor?: string, + direction?: string, + display?: string, + elevation?: string, + emptyCells?: string, + float?: string, + font?: string, + fontFamily?: string, + fontSize?: string, + fontSizeAdjust?: string, + fontStretch?: string, + fontStyle?: string, + fontVariant?: string, + fontWeight?: string, + height?: string, + left?: string, + letterSpacing?: string, + lineHeight?: string, + listStyle?: string, + listStyleImage?: string, + listStylePosition?: string, + listStyleType?: string, + margin?: string, + marginTop?: string, + marginRight?: string, + marginBottom?: string, + marginLeft?: string, + markerOffset?: string, + marks?: string, + maxHeight?: string, + maxWidth?: string, + minHeight?: string, + minWidth?: string, + orphans?: string, + outline?: string, + outlineColor?: string, + outlineStyle?: string, + outlineWidth?: string, + overflow?: string, + overflowX?: string, + overflowY?: string, + padding?: string, + paddingTop?: string, + paddingRight?: string, + paddingBottom?: string, + paddingLeft?: string, + page?: string, + pageBreakAfter?: string, + pageBreakBefore?: string, + pageBreakInside?: string, + pause?: string, + pauseAfter?: string, + pauseBefore?: string, + pitch?: string, + pitchRange?: string, + playDuring?: string, + position?: string, + quotes?: string, + richness?: string, + right?: string, + size?: string, + speak?: string, + speakHeader?: string, + speakNumeral?: string, + speakPunctuation?: string, + speechRate?: string, + stress?: string, + tableLayout?: string, + textAlign?: string, + textDecoration?: string, + textIndent?: string, + textShadow?: string, + textTransform?: string, + top?: string, + unicodeBidi?: string, + verticalAlign?: string, + visibility?: string, + voiceFamily?: string, + volume?: string, + whiteSpace?: string, + widows?: string, + width?: string, + wordSpacing?: string, + zIndex?: string, + /* Below properties based on https://www.w3.org/Style/CSS/all-properties */ + /* Color Level 3 - REC */ + opacity?: string, + /* Backgrounds and Borders Level 3 - CR */ + /* backgroundRepeat - already defined by CSS2Properties */ + /* backgroundAttachment - already defined by CSS2Properties */ + backgroundOrigin?: string, + backgroundSize?: string, + backgroundClip?: string, + borderRadius?: string, + borderTopLeftRadius?: string, + borderTopRightRadius?: string, + borderBottomLeftRadius?: string, + borderBottomRightRadius?: string, + borderImage?: string, + borderImageSource?: string, + borderImageSlice?: string, + borderImageWidth?: string, + borderImageOutset?: string, + borderImageRepeat?: string, + boxShadow?: string, + columns?: string, + /* Multi-column Layout - CR */ + columnCount?: string, + columnFill?: string, + columnGap?: string, + columnRule?: string, + columnRuleColor?: string, + columnRuleStyle?: string, + columnRuleWidth?: string, + columnSpan?: string, + columnWidth?: string, + breakAfter?: string, + breakBefore?: string, + breakInside?: string, + rest?: string, + /* Speech - CR */ + restAfter?: string, + restBefore?: string, + speakAs?: string, + voiceBalance?: string, + voiceDuration?: string, + voicePitch?: string, + voiceRange?: string, + voiceRate?: string, + voiceStress?: string, + voiceVolume?: string, + objectFit?: string, + /* Image Values and Replaced Content Level 3 - CR */ + objectPosition?: string, + imageResolution?: string, + imageOrientation?: string, + alignContent?: string, + /* Flexible Box Layout - CR */ + alignItems?: string, + alignSelf?: string, + flex?: string, + flexBasis?: string, + flexDirection?: string, + flexFlow?: string, + flexGrow?: string, + flexShrink?: string, + flexWrap?: string, + justifyContent?: string, + order?: string, + gap?: string, + textDecorationColor?: string, + /* Text Decoration Level 3 - CR */ + /* textDecoration - already defined by CSS2Properties */ + textDecorationLine?: string, + textDecorationSkip?: string, + textDecorationStyle?: string, + textEmphasis?: string, + textEmphasisColor?: string, + textEmphasisPosition?: string, + textEmphasisStyle?: string, + textUnderlinePosition?: string, + /* textShadow - already defined by CSS2Properties */ + fontFeatureSettings?: string, + /* Fonts Level 3 - CR */ + fontKerning?: string, + fontLanguageOverride?: string, + fontSynthesis?: string, + /* fontSizeAdjust - already defined by CSS2Properties */ + /* fontStretch - already defined by CSS2Properties */ + forntVariantAlternates?: string, + fontVariantCaps?: string, + fontVariantEastAsian?: string, + fontVariantLigatures?: string, + fontVariantNumeric?: string, + fontVariantPosition?: string, + all?: string, + /* Cascading and Inheritance Level 3 - CR */ + glyphOrientationVertical?: string, + /* Writing Modes Level 3 - CR */ + textCombineUpright?: string, + textOrientation?: string, + writingMode?: string, + shapeImageThreshold?: string, + /* Shapes Level 1 - CR */ + shapeMargin?: string, + shapeOutside?: string, + clipPath?: string, + /* Masking Level 1 - CR */ + clipRule?: string, + mask?: string, + maskBorder?: string, + maskBorderMode?: string, + maskBorderOutset?: string, + maskBorderRepeat?: string, + maskBorderSlice?: string, + maskBorderSource?: string, + maskBorderWidth?: string, + maskClip?: string, + maskComposite?: string, + maskImage?: string, + maskMode?: string, + maskOrigin?: string, + maskPosition?: string, + maskRepeat?: string, + maskSize?: string, + maskType?: string, + backgroundBlendMode?: string, + /* Compositing and Blending Level 1 - CR */ + isolation?: string, + mixBlendMode?: string, + boxDecorationBreak?: string, + /* Fragmentation Level 3 - CR */ + boxSizing?: string, + /* breakAfter - already defined by Multi-column Layout */ + /* breakBefore - already defined by Multi-column Layout */ + /* breakInside - already defined by Multi-column Layout */ + /* Basic User Interface Level 3 - CR */ + caretColor?: string, + navDown?: string, + navLeft?: string, + navRight?: string, + navUp?: string, + outlineOffset?: string, + resize?: string, + textOverflow?: string, + grid?: string, + /* Grid Layout Level 1 - CR */ + gridArea?: string, + gridAutoColumns?: string, + gridAutoFlow?: string, + gridAutoRows?: string, + gridColumn?: string, + gridColumnEnd?: string, + gridColumnGap?: string, + gridColumnStart?: string, + gridGap?: string, + gridRow?: string, + gridRowEnd?: string, + gridRowGap?: string, + gridRowStart?: string, + gridTemplate?: string, + gridTemplateAreas?: string, + gridTemplateColumns?: string, + gridTemplateRows?: string, + willChange?: string, + /* Will Change Level 1 - CR */ + hangingPunctuation?: string, + /* Text Level 3 - LC */ + hyphens?: string, + lineBreak?: string, + /* letterSpacing - already defined by CSS2Properties */ + overflowWrap?: string, + tabSize?: string, + textAlignLast?: string, + /* textAlign - already defined by CSS2Properties */ + textJustify?: string, + wordBreak?: string, + wordWrap?: string, + animation?: string, + /* Animations - WD */ + animationDelay?: string, + animationDirection?: string, + animationDuration?: string, + animationFillMode?: string, + animationIterationCount?: string, + animationName?: string, + animationPlayState?: string, + animationTimingFunction?: string, + transition?: string, + /* Transitions - WD */ + transitionDelay?: string, + transitionDuration?: string, + transitionProperty?: string, + transitionTimingFunction?: string, + backfaceVisibility?: string, + /* Transforms Level 1 - WD */ + perspective?: string, + perspectiveOrigin?: string, + transform?: string, + transformOrigin?: string, + transformStyle?: string, + justifyItems?: string, + /* Box Alignment Level 3 - WD */ + /* alignContent - already defined by Flexible Box Layout */ + /* alignItems - already defined by Flexible Box Layout */ + justifySelf?: string, + placeContent?: string, + placeItems?: string, + placeSelf?: string, + appearance?: string, + /* Basic User Interface Level 4 - FPWD */ + caret?: string, + caretAnimation?: string, + caretShape?: string, + userSelect?: string, + maxLines?: string, + /* Overflow Level 3 - WD */ + marqueeDirection?: string, + /* Basix Box Model - WD */ + marqueeLoop?: string, + marqueeSpeed?: string, + marqueeStyle?: string, + overflowStyle?: string, + rotation?: string, + rotationPoint?: string, + alignmentBaseline?: string, + /* SVG 1.1 - REC */ + baselineShift?: string, + colorInterpolation?: string, + colorInterpolationFilters?: string, + colorProfile?: string, + colorRendering?: string, + dominantBaseline?: string, + fill?: string, + fillOpacity?: string, + fillRule?: string, + filter?: string, + floodColor?: string, + floodOpacity?: string, + glyphOrientationHorizontal?: string, + imageRendering?: string, + kerning?: string, + lightingColor?: string, + markerEnd?: string, + markerMid?: string, + markerStart?: string, + pointerEvents?: string, + shapeRendering?: string, + stopColor?: string, + stopOpacity?: string, + stroke?: string, + strokeDasharray?: string, + strokeDashoffset?: string, + strokeLinecap?: string, + strokeLinejoin?: string, + strokeMiterlimit?: string, + strokeOpacity?: string, + strokeWidth?: string, + textAnchor?: string, + textRendering?: string, + rubyAlign?: string, + /* Ruby Layout Level 1 - WD */ + rubyMerge?: string, + rubyPosition?: string, + /* Lists and Counters Level 3 - WD */ + /* listStyle - already defined by CSS2Properties */ + /* listStyleImage - already defined by CSS2Properties */ + /* listStylePosition - already defined by CSS2Properties */ + /* listStyleType - already defined by CSS2Properties */ + /* counterIncrement - already defined by CSS2Properties */ + /* counterReset - already defined by CSS2Properties */ + /* Not added yet + * ------------- + * Generated Content for Paged Media - WD + * Generated Content Level 3 - WD + * Line Grid Level 1 - WD + * Regions - WD + * Inline Layout Level 3 - WD + * Round Display Level 1 - WD + * Image Values and Replaced Content Level 4 - WD + * Positioned Layout Level 3 - WD + * Filter Effects Level 1 - -WD + * Exclusions Level 1 - WD + * Text Level 4 - FPWD + * SVG Markers - FPWD + * Motion Path Level 1 - FPWD + * Color Level 4 - FPWD + * SVG Strokes - FPWD + * Table Level 3 - FPWD + */ +} diff --git a/js/src/jsxEvent.js b/js/src/jsxEvent.js new file mode 100644 index 0000000..b1b7eae --- /dev/null +++ b/js/src/jsxEvent.js @@ -0,0 +1,59 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function MakeEventWithType(Type) { + return {}; +} + +var Synthetic = {}; + +var Clipboard = {}; + +var Composition = {}; + +var Keyboard = {}; + +var Focus = {}; + +var Form = {}; + +var Mouse = {}; + +var Pointer = {}; + +var $$Selection = {}; + +var $$Touch = {}; + +var UI = {}; + +var Wheel = {}; + +var Media = {}; + +var $$Image = {}; + +var $$Animation = {}; + +var Transition = {}; + +export { + MakeEventWithType , + Synthetic , + Clipboard , + Composition , + Keyboard , + Focus , + Form , + Mouse , + Pointer , + $$Selection , + $$Touch , + UI , + Wheel , + Media , + $$Image , + $$Animation , + Transition , +} +/* No side effect */ diff --git a/js/src/jsxEvent.res b/js/src/jsxEvent.res new file mode 100644 index 0000000..0d67f22 --- /dev/null +++ b/js/src/jsxEvent.res @@ -0,0 +1,350 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/*** Internal: use JsxEvent directly. */ + +@@uncurried + +type synthetic<'a> + +module MakeEventWithType = ( + Type: { + type t + }, +) => { + @get external bubbles: Type.t => bool = "bubbles" + @get external cancelable: Type.t => bool = "cancelable" + @get external currentTarget: Type.t => {..} = "currentTarget" + + /* Should return Dom.eventTarget */ + @get external defaultPrevented: Type.t => bool = "defaultPrevented" + @get external eventPhase: Type.t => int = "eventPhase" + @get external isTrusted: Type.t => bool = "isTrusted" + @get external nativeEvent: Type.t => {..} = "nativeEvent" + + /* Should return Dom.event */ + @send external preventDefault: Type.t => unit = "preventDefault" + + @send external isDefaultPrevented: Type.t => bool = "isDefaultPrevented" + + @send external stopPropagation: Type.t => unit = "stopPropagation" + + @send external isPropagationStopped: Type.t => bool = "isPropagationStopped" + + @get external target: Type.t => {..} = "target" + + /* Should return Dom.eventTarget */ + @get external timeStamp: Type.t => float = "timeStamp" + @get external type_: Type.t => string = "type" + @send external persist: Type.t => unit = "persist" +} + +module Synthetic = { + type tag + type t = synthetic + + @get external bubbles: synthetic<'a> => bool = "bubbles" + @get external cancelable: synthetic<'a> => bool = "cancelable" + @get external currentTarget: synthetic<'a> => {..} = "currentTarget" + /* Should return Dom.eventTarget */ + + @get external defaultPrevented: synthetic<'a> => bool = "defaultPrevented" + + @get external eventPhase: synthetic<'a> => int = "eventPhase" + @get external isTrusted: synthetic<'a> => bool = "isTrusted" + @get external nativeEvent: synthetic<'a> => {..} = "nativeEvent" + + /* Should return Dom.event */ + @send external preventDefault: synthetic<'a> => unit = "preventDefault" + + @send external isDefaultPrevented: synthetic<'a> => bool = "isDefaultPrevented" + + @send external stopPropagation: synthetic<'a> => unit = "stopPropagation" + + @send external isPropagationStopped: synthetic<'a> => bool = "isPropagationStopped" + + @get external target: synthetic<'a> => {..} = "target" + + /* Should return Dom.eventTarget */ + @get external timeStamp: synthetic<'a> => float = "timeStamp" + @get external type_: synthetic<'a> => string = "type" + @send external persist: synthetic<'a> => unit = "persist" +} + +/* Cast any event type to the general synthetic type. This is safe, since synthetic is more general */ +external toSyntheticEvent: synthetic<'a> => Synthetic.t = "%identity" + +module Clipboard = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external clipboardData: t => {..} = "clipboardData" + /* Should return Dom.dataTransfer */ +} + +module Composition = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external data: t => string = "data" +} + +module Keyboard = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external altKey: t => bool = "altKey" + @get external charCode: t => int = "charCode" + @get external ctrlKey: t => bool = "ctrlKey" + + @send external getModifierState: (t, string) => bool = "getModifierState" + + @get external key: t => string = "key" + @get external keyCode: t => int = "keyCode" + @get external locale: t => string = "locale" + @get external location: t => int = "location" + @get external metaKey: t => bool = "metaKey" + @get external repeat: t => bool = "repeat" + @get external shiftKey: t => bool = "shiftKey" + @get external which: t => int = "which" +} + +module Focus = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get @return(nullable) external relatedTarget: t => option<{..}> = "relatedTarget" + /* Should return Dom.eventTarget */ +} + +module Form = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) +} + +module Mouse = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external altKey: t => bool = "altKey" + @get external button: t => int = "button" + @get external buttons: t => int = "buttons" + @get external clientX: t => int = "clientX" + @get external clientY: t => int = "clientY" + @get external ctrlKey: t => bool = "ctrlKey" + + @get external getModifierState: (t => string) => bool = "getModifierState" + + @get external metaKey: t => bool = "metaKey" + @get external movementX: t => int = "movementX" + @get external movementY: t => int = "movementY" + @get external pageX: t => int = "pageX" + @get external pageY: t => int = "pageY" + + @get @return(nullable) external relatedTarget: t => option<{..}> = "relatedTarget" + + /* Should return Dom.eventTarget */ + @get external screenX: t => int = "screenX" + @get external screenY: t => int = "screenY" + @get external shiftKey: t => bool = "shiftKey" +} + +module Pointer = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + /* UIEvent */ + @get @get + external detail: t => int = "detail" + + /* external view : t -> Dom.window = "view" */ + /* Should return DOMAbstractView/WindowProxy */ + + /* MouseEvent */ + @get external screenX: t => int = "screenX" + @get external screenY: t => int = "screenY" + @get external clientX: t => int = "clientX" + @get external clientY: t => int = "clientY" + @get external pageX: t => int = "pageX" + @get external pageY: t => int = "pageY" + @get external movementX: t => int = "movementX" + @get external movementY: t => int = "movementY" + @get external ctrlKey: t => bool = "ctrlKey" + @get external shiftKey: t => bool = "shiftKey" + @get external altKey: t => bool = "altKey" + @get external metaKey: t => bool = "metaKey" + + @get external getModifierState: (t => string) => bool = "getModifierState" + + @get external button: t => int = "button" + @get external buttons: t => int = "buttons" + + @get @return(nullable) external relatedTarget: t => option<{..}> = "relatedTarget" + /* Should return Dom.eventTarget */ + + /* PointerEvent */ + /* external pointerId : t -> Dom.eventPointerId = "pointerId" [@@get] */ + @get external width: t => float = "width" + @get external height: t => float = "height" + @get external pressure: t => float = "pressure" + @get external tangentialPressure: t => float = "tangentialPressure" + @get external tiltX: t => int = "tiltX" + @get external tiltY: t => int = "tiltY" + @get external twist: t => int = "twist" + @get external pointerType: t => string = "pointerType" + @get external isPrimary: t => bool = "isPrimary" +} + +module Selection = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) +} + +module Touch = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external altKey: t => bool = "altKey" + @get external changedTouches: t => {..} = "changedTouches" + /* Should return Dom.touchList */ + + @get external ctrlKey: t => bool = "ctrlKey" + + @send external getModifierState: (t => string) => bool = "getModifierState" + + @get external metaKey: t => bool = "metaKey" + @get external shiftKey: t => bool = "shiftKey" + @get external targetTouches: t => {..} = "targetTouches" + /* Should return Dom.touchList */ + + @get external touches: t => {..} = "touches" + /* Should return Dom.touchList */ +} + +module UI = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external detail: t => int = "detail" + /* external view : t -> Dom.window = "view" [@@get] */ + /* Should return DOMAbstractView/WindowProxy */ +} + +module Wheel = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external deltaMode: t => int = "deltaMode" + @get external deltaX: t => float = "deltaX" + @get external deltaY: t => float = "deltaY" + @get external deltaZ: t => float = "deltaZ" +} + +module Media = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) +} + +module Image = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) +} + +module Animation = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external animationName: t => string = "animationName" + @get external pseudoElement: t => string = "pseudoElement" + @get external elapsedTime: t => float = "elapsedTime" +} + +module Transition = { + type tag + type t = synthetic + + include MakeEventWithType({ + type t = t + }) + + @get external propertyName: t => string = "propertyName" + @get external pseudoElement: t => string = "pseudoElement" + @get external elapsedTime: t => float = "elapsedTime" +} diff --git a/js/src/jsxPPXReactSupport.js b/js/src/jsxPPXReactSupport.js new file mode 100644 index 0000000..4701f07 --- /dev/null +++ b/js/src/jsxPPXReactSupport.js @@ -0,0 +1,26 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as React from "react"; +import * as Caml_splice_call from "rescript/lib/es6/caml_splice_call.js"; + +function createElementWithKey(key, component, props) { + return React.createElement(component, key !== undefined ? Object.assign({ + key: key + }, props) : props); +} + +function createElementVariadicWithKey(key, component, props, elements) { + return Caml_splice_call.spliceApply(React.createElement, [ + component, + key !== undefined ? Object.assign({ + key: key + }, props) : props, + elements + ]); +} + +export { + createElementWithKey , + createElementVariadicWithKey , +} +/* react Not a pure module */ diff --git a/js/src/jsxPPXReactSupport.res b/js/src/jsxPPXReactSupport.res new file mode 100644 index 0000000..483b28c --- /dev/null +++ b/js/src/jsxPPXReactSupport.res @@ -0,0 +1,52 @@ +/* Copyright (C) 2022- Authors of ReScript + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +%%private( + @val + external propsWithKey: ({"key": string}, 'props) => 'props = "Object.assign" + + @inline + let addKeyProp = (~key: option=?, p: 'props): 'props => + switch key { + | Some(key) => propsWithKey({"key": key}, p) + | None => p + } +) + +@@uncurried // Can't move this up as @inline not working with uncurried + +@module("react") +external createElement: (Jsx.component<'props>, 'props) => Jsx.element = "createElement" + +@variadic @module("react") +external createElementVariadic: (Jsx.component<'props>, 'props, array) => Jsx.element = + "createElement" + +let createElementWithKey = (~key=?, component, props) => + createElement(component, addKeyProp(~key?, props)) + +let createElementVariadicWithKey = (~key=?, component, props, elements) => + createElementVariadic(component, addKeyProp(~key?, props), elements) + +external asyncComponent: promise => Jsx.element = "%identity" diff --git a/package-lock.json b/package-lock.json index 99e8849..a5ce8b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "stdlib-mini", "core", "belt", - "runtime" + "runtime", + "js" ], "dependencies": { "rescript": "^11.1.3-rc.1" @@ -26,6 +27,9 @@ "core": { "version": "1.5.0" }, + "js": { + "version": "0.0.0" + }, "node_modules/@rolandpeelen/rewatch": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@rolandpeelen/rewatch/-/rewatch-1.0.8.tgz", @@ -44,6 +48,10 @@ "resolved": "core", "link": true }, + "node_modules/js": { + "resolved": "js", + "link": true + }, "node_modules/rescript": { "version": "11.1.3-rc.1", "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.1.3-rc.1.tgz", diff --git a/package.json b/package.json index 5bf8092..79651d5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "stdlib-mini", "core", "belt", - "runtime" + "runtime", + "js" ], "scripts": { "start": "rewatch watch", diff --git a/rescript.json b/rescript.json index 3bca1a6..f66bd3b 100644 --- a/rescript.json +++ b/rescript.json @@ -6,6 +6,6 @@ "in-source": true }, "suffix": ".js", - "bs-dependencies": ["stdlib-mini", "core", "belt", "runtime"], + "bs-dependencies": ["stdlib-mini", "core", "belt", "runtime", "js"], "bsc-flags": ["-nostdlib", "-nopervasives"] } diff --git a/stdlib-mini/src/runtime_types.js b/stdlib-mini/src/runtime_types.js new file mode 100644 index 0000000..d856702 --- /dev/null +++ b/stdlib-mini/src/runtime_types.js @@ -0,0 +1,2 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/stdlib-mini/src/js_types.res b/stdlib-mini/src/runtime_types.res similarity index 100% rename from stdlib-mini/src/js_types.res rename to stdlib-mini/src/runtime_types.res diff --git a/stdlib-mini/src/stdlib_mini.res b/stdlib-mini/src/stdlib_mini.res index 42ca8ae..027fa8f 100644 --- a/stdlib-mini/src/stdlib_mini.res +++ b/stdlib-mini/src/stdlib_mini.res @@ -95,14 +95,14 @@ module Js = { /** Nullable value of this type can be either null or 'a. This type is equivalent to Js.Null.t. */ - type null<+'a> = Js_types.null<'a> + type null<+'a> = Runtime_types.null<'a> /** A value of this type can be either undefined or 'a. This type is equivalent to Js.Undefined.t. */ - type undefined<+'a> = Js_types.undefined<'a> + type undefined<+'a> = Runtime_types.undefined<'a> - type nullable<+'a> = Js_types.nullable<'a> + type nullable<+'a> = Runtime_types.nullable<'a> module Undefined = { external empty: undefined<'a> = "#undefined"