diff --git a/bsconfig.json b/bsconfig.json index f5c04d1e..f3e7a69d 100644 --- a/bsconfig.json +++ b/bsconfig.json @@ -1,6 +1,6 @@ { "name": "@rescript/core", - "version": "0.5.0", + "version": "1.0.0", "sources": [ { "dir": "src", diff --git a/package-lock.json b/package-lock.json index 8544d3cc..573cb4fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "@rescript/core", - "version": "0.5.0", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@rescript/core", - "version": "0.5.0", + "version": "1.0.0", "license": "MIT", "devDependencies": { "@babel/code-frame": "7.18.6", - "rescript": "10.1.4" + "rescript": "11.0.0-beta.3" }, "peerDependencies": { - "rescript": "^10.1.0 || ^11.0.0-alpha.0 || next" + "rescript": ">= 11.0.0-beta.3" } }, "node_modules/@babel/code-frame": { @@ -117,16 +117,18 @@ "dev": true }, "node_modules/rescript": { - "version": "10.1.4", - "resolved": "https://registry.npmjs.org/rescript/-/rescript-10.1.4.tgz", - "integrity": "sha512-FFKlS9AG/XrLepWsyw7B+A9DtQBPWEPDPDKghV831Y2KGbie+eeFBOS0xtRHp0xbt7S0N2Dm6hhX+kTZQ/3Ybg==", + "version": "11.0.0-beta.3", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.0-beta.3.tgz", + "integrity": "sha512-j3YT3VdWMoHgwL4RydKJm9O/VIpN3NTI6keP18rZVJ8ansRKgkHYGLaIwoG6iVqSYYwBjb6d8l8oZ1Jz0fmTeQ==", "dev": true, "hasInstallScript": true, "bin": { "bsc": "bsc", - "bsrefmt": "bsrefmt", "bstracing": "lib/bstracing", "rescript": "rescript" + }, + "engines": { + "node": ">=10" } }, "node_modules/supports-color": { @@ -223,9 +225,9 @@ "dev": true }, "rescript": { - "version": "10.1.4", - "resolved": "https://registry.npmjs.org/rescript/-/rescript-10.1.4.tgz", - "integrity": "sha512-FFKlS9AG/XrLepWsyw7B+A9DtQBPWEPDPDKghV831Y2KGbie+eeFBOS0xtRHp0xbt7S0N2Dm6hhX+kTZQ/3Ybg==", + "version": "11.0.0-beta.3", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.0-beta.3.tgz", + "integrity": "sha512-j3YT3VdWMoHgwL4RydKJm9O/VIpN3NTI6keP18rZVJ8ansRKgkHYGLaIwoG6iVqSYYwBjb6d8l8oZ1Jz0fmTeQ==", "dev": true }, "supports-color": { diff --git a/package.json b/package.json index ec1b97ed..a73c5cc1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rescript/core", - "version": "0.5.0", + "version": "1.0.0", "scripts": { "clean": "rescript clean", "build": "rescript", @@ -23,10 +23,10 @@ "src/**/*.mjs" ], "peerDependencies": { - "rescript": "^10.1.0 || ^11.0.0-alpha.0 || next" + "rescript": ">= 11.0.0-beta.3" }, "devDependencies": { - "rescript": "10.1.4", - "@babel/code-frame": "7.18.6" + "@babel/code-frame": "7.18.6", + "rescript": "11.0.0-beta.3" } } diff --git a/src/Core__Error.mjs b/src/Core__Error.mjs index 5c9e853f..e5334cf8 100644 --- a/src/Core__Error.mjs +++ b/src/Core__Error.mjs @@ -14,7 +14,7 @@ var $$TypeError = {}; var $$URIError = {}; function panic(msg) { - throw new Error("Panic! " + msg + ""); + throw new Error("Panic! " + msg); } export { diff --git a/src/Core__JSON.mjs b/src/Core__JSON.mjs index e26011ca..c330447b 100644 --- a/src/Core__JSON.mjs +++ b/src/Core__JSON.mjs @@ -7,29 +7,29 @@ function classify(value) { switch (match) { case "[object Array]" : return { - TAG: /* Array */4, + TAG: "Array", _0: value }; case "[object Boolean]" : return { - TAG: /* Bool */0, + TAG: "Bool", _0: value }; case "[object Null]" : - return /* Null */0; + return "Null"; case "[object Number]" : return { - TAG: /* Number */2, + TAG: "Number", _0: value }; case "[object String]" : return { - TAG: /* String */1, + TAG: "String", _0: value }; default: return { - TAG: /* Object */3, + TAG: "Object", _0: value }; } diff --git a/src/Core__JSON.res b/src/Core__JSON.res index 16f28e36..35f3946d 100644 --- a/src/Core__JSON.res +++ b/src/Core__JSON.res @@ -1,4 +1,12 @@ -type t = Js.Json.t +@unboxed +type rec t = Js.Json.t = + | @as(false) False + | @as(true) True + | @as(null) Null + | String(string) + | Number(float) + | Object(Js.Dict.t) + | Array(array) @raises @val external parseExn: string => t = "JSON.parse" @raises @val external parseExnWithReviver: (string, (string, t) => t) => t = "JSON.parse" diff --git a/src/Core__JSON.resi b/src/Core__JSON.resi index 32389d70..8c111890 100644 --- a/src/Core__JSON.resi +++ b/src/Core__JSON.resi @@ -3,9 +3,17 @@ Functions for interacting with JSON. */ /** -A type representing a JSON object. +A type representing a valid JSON value. */ -type t = Js.Json.t +@unboxed +type rec t = Js.Json.t = + | @as(false) False + | @as(true) True + | @as(null) Null + | String(string) + | Number(float) + | Object(Js.Dict.t) + | Array(array) /** `parseExn(string)` diff --git a/src/Core__List.res b/src/Core__List.res index 44d92857..9e963fc3 100644 --- a/src/Core__List.res +++ b/src/Core__List.res @@ -870,14 +870,14 @@ let partitionU = (l, p) => nextX, switch nextY { | list{_, ...tail} => tail - | list{} => assert false + | list{} => assert(false) }, ) } else { ( switch nextX { | list{_, ...tail} => tail - | list{} => assert false + | list{} => assert(false) }, nextY, ) diff --git a/src/Core__Null.res b/src/Core__Null.res index ee5bdc48..40b4b767 100644 --- a/src/Core__Null.res +++ b/src/Core__Null.res @@ -1,4 +1,4 @@ -type t<'a> = Js.Null.t<'a> +@unboxed type t<'a> = Js.Null.t<'a> = Value('a) | @as(null) Null external asNullable: t<'a> => Core__Nullable.t<'a> = "%identity" diff --git a/src/Core__Null.resi b/src/Core__Null.resi index 6bcbf52a..430678cf 100644 --- a/src/Core__Null.resi +++ b/src/Core__Null.resi @@ -7,7 +7,8 @@ If you also need to cover `undefined`, check out `Nullable` instead. /** A type representing a value that can be either `'a` or `null`. */ -type t<'a> = Js.Null.t<'a> +@unboxed +type t<'a> = Js.Null.t<'a> = Value('a) | @as(null) Null /** Converts a `Null.t` into a `Nullable.t`. diff --git a/src/Core__Nullable.res b/src/Core__Nullable.res index 0fe1718f..af4c404c 100644 --- a/src/Core__Nullable.res +++ b/src/Core__Nullable.res @@ -1,4 +1,4 @@ -type t<'a> = Js.Nullable.t<'a> +@unboxed type t<'a> = Js.Nullable.t<'a> = Value('a) | @as(null) Null | @as(undefined) Undefined external null: t<'a> = "#null" diff --git a/src/Core__Nullable.resi b/src/Core__Nullable.resi index 4f304755..c79b9ea3 100644 --- a/src/Core__Nullable.resi +++ b/src/Core__Nullable.resi @@ -8,7 +8,8 @@ Primarily useful when interoping with JavaScript when you don't know whether you Type representing a nullable value. A nullable value can be the value `'a`, `null` or `undefined`. */ -type t<'a> = Js.Nullable.t<'a> +@unboxed +type t<'a> = Js.Nullable.t<'a> = Value('a) | @as(null) Null | @as(undefined) Undefined /** The value `null`. diff --git a/src/Core__Result.mjs b/src/Core__Result.mjs index 5f7e0c28..dbc43225 100644 --- a/src/Core__Result.mjs +++ b/src/Core__Result.mjs @@ -3,7 +3,7 @@ import * as Curry from "rescript/lib/es6/curry.js"; function getExn(x) { - if (x.TAG === /* Ok */0) { + if (x.TAG === "Ok") { return x._0; } throw { @@ -13,7 +13,7 @@ function getExn(x) { } function mapOr(opt, $$default, f) { - if (opt.TAG === /* Ok */0) { + if (opt.TAG === "Ok") { return Curry._1(f, opt._0); } else { return $$default; @@ -21,9 +21,9 @@ function mapOr(opt, $$default, f) { } function map(opt, f) { - if (opt.TAG === /* Ok */0) { + if (opt.TAG === "Ok") { return { - TAG: /* Ok */0, + TAG: "Ok", _0: Curry._1(f, opt._0) }; } else { @@ -32,7 +32,7 @@ function map(opt, f) { } function flatMap(opt, f) { - if (opt.TAG === /* Ok */0) { + if (opt.TAG === "Ok") { return Curry._1(f, opt._0); } else { return opt; @@ -40,7 +40,7 @@ function flatMap(opt, f) { } function getOr(opt, $$default) { - if (opt.TAG === /* Ok */0) { + if (opt.TAG === "Ok") { return opt._0; } else { return $$default; @@ -48,7 +48,7 @@ function getOr(opt, $$default) { } function isOk(x) { - if (x.TAG === /* Ok */0) { + if (x.TAG === "Ok") { return true; } else { return false; @@ -56,7 +56,7 @@ function isOk(x) { } function isError(x) { - if (x.TAG === /* Ok */0) { + if (x.TAG === "Ok") { return false; } else { return true; @@ -64,13 +64,13 @@ function isError(x) { } function equal(a, b, f) { - if (a.TAG === /* Ok */0) { - if (b.TAG === /* Ok */0) { + if (a.TAG === "Ok") { + if (b.TAG === "Ok") { return Curry._2(f, a._0, b._0); } else { return false; } - } else if (b.TAG === /* Ok */0) { + } else if (b.TAG === "Ok") { return false; } else { return true; @@ -78,13 +78,13 @@ function equal(a, b, f) { } function compare(a, b, f) { - if (a.TAG === /* Ok */0) { - if (b.TAG === /* Ok */0) { + if (a.TAG === "Ok") { + if (b.TAG === "Ok") { return Curry._2(f, a._0, b._0); } else { return 1; } - } else if (b.TAG === /* Ok */0) { + } else if (b.TAG === "Ok") { return -1; } else { return 0; @@ -92,18 +92,18 @@ function compare(a, b, f) { } function forEach(r, f) { - if (r.TAG === /* Ok */0) { + if (r.TAG === "Ok") { return Curry._1(f, r._0); } } function mapError(r, f) { - if (r.TAG === /* Ok */0) { + if (r.TAG === "Ok") { return r; } else { return { - TAG: /* Error */1, + TAG: "Error", _0: Curry._1(f, r._0) }; } diff --git a/src/Core__Type.mjs b/src/Core__Type.mjs index ec38c9ca..a27e6e74 100644 --- a/src/Core__Type.mjs +++ b/src/Core__Type.mjs @@ -6,43 +6,43 @@ function classify(value) { switch (match) { case "[object BigInt]" : return { - TAG: /* BigInt */6, + TAG: "BigInt", _0: value }; case "[object Boolean]" : return { - TAG: /* Bool */0, + TAG: "Bool", _0: value }; case "[object AsyncFunction]" : case "[object Function]" : case "[object GeneratorFunction]" : return { - TAG: /* Function */4, + TAG: "Function", _0: value }; case "[object Null]" : - return /* Null */0; + return "Null"; case "[object Number]" : return { - TAG: /* Number */2, + TAG: "Number", _0: value }; case "[object String]" : return { - TAG: /* String */1, + TAG: "String", _0: value }; case "[object Symbol]" : return { - TAG: /* Symbol */5, + TAG: "Symbol", _0: value }; case "[object Undefined]" : - return /* Undefined */1; + return "Undefined"; default: return { - TAG: /* Object */3, + TAG: "Object", _0: value }; } diff --git a/src/RescriptCore.res b/src/RescriptCore.res index 0cdb0025..fd3f2531 100644 --- a/src/RescriptCore.res +++ b/src/RescriptCore.res @@ -65,6 +65,11 @@ type null<+'a> = Js.null<'a> type undefined<+'a> = Js.undefined<'a> -type nullable<+'a> = Js.nullable<'a> +// We're intentionally only bringing the constructors of `nullable` into scope +// here. Reason is if we do the same for `null`, we'll get issues with inference +// in the global scope, and we prioritize nullable higher because that covers +// more cases. +@unboxed +type nullable<+'a> = Js.nullable<'a> = Value('a) | @as(null) Null | @as(undefined) Undefined let panic = Core__Error.panic diff --git a/test/JsonTests.mjs b/test/JsonTests.mjs new file mode 100644 index 00000000..d2841a26 --- /dev/null +++ b/test/JsonTests.mjs @@ -0,0 +1,47 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Test from "./Test.mjs"; + +function decodeJsonTest(param) { + var json = {"someProp":{"otherProp": null, "thirdProp": [true, false]}}; + var decodedCorrectly; + if (!Array.isArray(json) && (json === null || typeof json !== "object") && typeof json !== "number" && typeof json !== "string" || !(typeof json === "object" && !Array.isArray(json))) { + decodedCorrectly = false; + } else { + var match = json["someProp"]; + if (match !== undefined && !(!Array.isArray(match) && (match === null || typeof match !== "object") && typeof match !== "number" && typeof match !== "string" || !(typeof match === "object" && !Array.isArray(match)))) { + var match$1 = match["thirdProp"]; + if (match$1 !== undefined && !(!Array.isArray(match$1) && (match$1 === null || typeof match$1 !== "object") && typeof match$1 !== "number" && typeof match$1 !== "string" || !(Array.isArray(match$1) && match$1.length === 2))) { + var match$2 = match$1[0]; + if (!Array.isArray(match$2) && (match$2 === null || typeof match$2 !== "object") && typeof match$2 !== "number" && typeof match$2 !== "string" && match$2 === true) { + var match$3 = match$1[1]; + decodedCorrectly = !Array.isArray(match$3) && (match$3 === null || typeof match$3 !== "object") && typeof match$3 !== "number" && typeof match$3 !== "string" && match$3 === false ? true : false; + } else { + decodedCorrectly = false; + } + } else { + decodedCorrectly = false; + } + } else { + decodedCorrectly = false; + } + } + Test.run([ + [ + "JsonTests.res", + 19, + 22, + 55 + ], + "Should decode JSON successfully" + ], decodedCorrectly, (function (prim0, prim1) { + return prim0 === prim1; + }), true); +} + +decodeJsonTest(undefined); + +export { + decodeJsonTest , +} +/* Not a pure module */ diff --git a/test/JsonTests.res b/test/JsonTests.res new file mode 100644 index 00000000..3aff98b6 --- /dev/null +++ b/test/JsonTests.res @@ -0,0 +1,22 @@ +open RescriptCore + +let decodeJsonTest = () => { + let json: JSON.t = %raw(`{"someProp":{"otherProp": null, "thirdProp": [true, false]}}`) + + let decodedCorrectly = switch json { + | Object(dict) => + switch dict->Dict.get("someProp") { + | Some(Object(dict)) => + switch dict->Dict.get("thirdProp") { + | Some(Array([True, False])) => true + | _ => false + } + | _ => false + } + | _ => false + } + + Test.run(__POS_OF__("Should decode JSON successfully"), decodedCorrectly, \"==", true) +} + +decodeJsonTest() diff --git a/test/NullableTests.mjs b/test/NullableTests.mjs new file mode 100644 index 00000000..31b536fa --- /dev/null +++ b/test/NullableTests.mjs @@ -0,0 +1,55 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Test from "./Test.mjs"; + +function shouldHandleNullableValues(param) { + var tNull = null; + var tUndefined = undefined; + var tValue = "hello"; + var tmp; + tmp = (tNull === null || tNull === undefined) && tNull === null ? true : false; + Test.run([ + [ + "NullableTests.res", + 9, + 15, + 35 + ], + "Should handle null" + ], tmp, (function (prim0, prim1) { + return prim0 === prim1; + }), true); + var tmp$1; + tmp$1 = (tUndefined === null || tUndefined === undefined) && tUndefined !== null ? true : false; + Test.run([ + [ + "NullableTests.res", + 19, + 15, + 40 + ], + "Should handle undefined" + ], tmp$1, (function (prim0, prim1) { + return prim0 === prim1; + }), true); + var tmp$2; + tmp$2 = tValue === null || tValue === undefined || tValue !== "hello" ? false : true; + Test.run([ + [ + "NullableTests.res", + 29, + 15, + 36 + ], + "Should handle value" + ], tmp$2, (function (prim0, prim1) { + return prim0 === prim1; + }), true); +} + +shouldHandleNullableValues(undefined); + +export { + shouldHandleNullableValues , +} +/* Not a pure module */ diff --git a/test/NullableTests.res b/test/NullableTests.res new file mode 100644 index 00000000..ca97174d --- /dev/null +++ b/test/NullableTests.res @@ -0,0 +1,39 @@ +open RescriptCore + +let shouldHandleNullableValues = () => { + let tNull: Nullable.t = %raw("null") + let tUndefined: Nullable.t = %raw("undefined") + let tValue: Nullable.t = %raw(`"hello"`) + + Test.run( + __POS_OF__("Should handle null"), + switch tNull { + | Null => true + | Value(_) | Undefined => false + }, + \"==", + true, + ) + + Test.run( + __POS_OF__("Should handle undefined"), + switch tUndefined { + | Undefined => true + | Value(_) | Null => false + }, + \"==", + true, + ) + + Test.run( + __POS_OF__("Should handle value"), + switch tValue { + | Value("hello") => true + | _ => false + }, + \"==", + true, + ) +} + +shouldHandleNullableValues() diff --git a/test/ObjectTests.mjs b/test/ObjectTests.mjs index fe5c70a6..627e2931 100644 --- a/test/ObjectTests.mjs +++ b/test/ObjectTests.mjs @@ -430,7 +430,7 @@ function assignOverwritesTarget(title, source) { 22, 39 ], - "assign " + title + "" + "assign " + title ], Object.assign({ a: 1 }, sourceObj), eq, sourceObj); @@ -441,7 +441,7 @@ function assignOverwritesTarget(title, source) { 22, 39 ], - "assign " + title + "" + "assign " + title ], Object.assign({ a: undefined }, sourceObj), eq, sourceObj); @@ -452,7 +452,7 @@ function assignOverwritesTarget(title, source) { 22, 39 ], - "assign " + title + "" + "assign " + title ], Object.assign({ a: null }, sourceObj), eq, sourceObj); @@ -474,7 +474,7 @@ function runGetTest(i) { 22, 46 ], - "Object.get: " + i.title + "" + "Object.get: " + i.title ], Curry._1(i.get, Curry._1(i.source, undefined)), eq, i.expected); } diff --git a/test/ResultTests.mjs b/test/ResultTests.mjs index d7f8245a..030f43ee 100644 --- a/test/ResultTests.mjs +++ b/test/ResultTests.mjs @@ -11,7 +11,7 @@ function forEachIfOkCallFunction(param) { contents: [] }; Core__Result.forEach({ - TAG: /* Ok */0, + TAG: "Ok", _0: 3 }, (function (i) { called.contents.push(i); @@ -34,7 +34,7 @@ function forEachIfErrorDoNotCallFunction(param) { contents: [] }; Core__Result.forEach({ - TAG: /* Error */1, + TAG: "Error", _0: 3 }, (function (i) { called.contents.push(i); @@ -61,12 +61,12 @@ Test.run([ ], "mapError: if ok, return it" ], Core__Result.mapError({ - TAG: /* Ok */0, + TAG: "Ok", _0: 5 }, (function (i) { return Math.imul(i, 3); })), eq, { - TAG: /* Ok */0, + TAG: "Ok", _0: 5 }); @@ -79,12 +79,12 @@ Test.run([ ], "mapError: if error, apply f" ], Core__Result.mapError({ - TAG: /* Error */1, + TAG: "Error", _0: 5 }, (function (i) { return Math.imul(i, 3); })), eq, { - TAG: /* Error */1, + TAG: "Error", _0: 15 }); diff --git a/test/TempTests.mjs b/test/TempTests.mjs index 9807a51a..fbbe204d 100644 --- a/test/TempTests.mjs +++ b/test/TempTests.mjs @@ -121,11 +121,11 @@ var json$1 = Core__JSON.Classify.classify(json); var tmp; -if (typeof json$1 === "number" || json$1.TAG !== /* Object */3) { +if (typeof json$1 !== "object" || json$1.TAG !== "Object") { tmp = undefined; } else { var value = Core__JSON.Classify.classify(json$1._0["foo"]); - tmp = typeof value === "number" || value.TAG !== /* String */1 ? undefined : value._0; + tmp = typeof value !== "object" || value.TAG !== "String" ? undefined : value._0; } console.log(tmp); @@ -283,7 +283,7 @@ var x = Symbol.for("Foo"); console.log(x); -var array$1 = Array.from("foo"[Symbol.iterator]()); +var array$1 = Array.from("foo"[Symbol.iterator](undefined)); console.log(array$1); diff --git a/test/TestSuite.mjs b/test/TestSuite.mjs index f8005b37..9c620d48 100644 --- a/test/TestSuite.mjs +++ b/test/TestSuite.mjs @@ -1,6 +1,7 @@ // Generated by ReScript, PLEASE EDIT WITH CARE import * as IntTests from "./IntTests.mjs"; +import * as JsonTests from "./JsonTests.mjs"; import * as TestTests from "./TestTests.mjs"; import * as ArrayTests from "./ArrayTests.mjs"; import * as ErrorTests from "./ErrorTests.mjs"; @@ -8,6 +9,7 @@ import * as FloatTests from "./FloatTests.mjs"; import * as ObjectTests from "./ObjectTests.mjs"; import * as PromiseTest from "./PromiseTest.mjs"; import * as ResultTests from "./ResultTests.mjs"; +import * as NullableTests from "./NullableTests.mjs"; import * as TypedArrayTests from "./TypedArrayTests.mjs"; var bign = TestTests.bign; @@ -66,6 +68,10 @@ var o = TypedArrayTests.o; var eq = FloatTests.eq; +var decodeJsonTest = JsonTests.decodeJsonTest; + +var shouldHandleNullableValues = NullableTests.shouldHandleNullableValues; + export { bign , TestError , @@ -95,5 +101,7 @@ export { areSame , o , eq , + decodeJsonTest , + shouldHandleNullableValues , } /* IntTests Not a pure module */ diff --git a/test/TestSuite.res b/test/TestSuite.res index 62e51b02..90b89666 100644 --- a/test/TestSuite.res +++ b/test/TestSuite.res @@ -7,3 +7,5 @@ include ObjectTests include ResultTests include TypedArrayTests include FloatTests +include JsonTests +include NullableTests