From d5dd0e45f514051858c61a9c582f41eac1ed926b Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 22 Oct 2025 11:06:51 +0200 Subject: [PATCH 1/6] Add global docstrings --- packages/@rescript/runtime/Stdlib.res | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/packages/@rescript/runtime/Stdlib.res b/packages/@rescript/runtime/Stdlib.res index 285aedc656..6c88c06ee0 100644 --- a/packages/@rescript/runtime/Stdlib.res +++ b/packages/@rescript/runtime/Stdlib.res @@ -62,6 +62,19 @@ type lazy_t<+'a> = Lazy.t<'a> @deprecated("Use rescript-webapi instead") @val external window: Dom.window = "window" @deprecated("Use rescript-webapi instead") @val external document: Dom.document = "document" +/** +`globalThis` exposes the host global object (`window` in browsers, `global` in Node, etc.). +Use it to access platform-specific globals without branching. + +## Examples + +```rescript +typeof(globalThis["setTimeout"]) == #function + +globalThis["myAppName"] = "SuperApp"; +globalThis["myAppName"] == "SuperApp" +``` +*/ @val external globalThis: {..} = "globalThis" /** @@ -106,6 +119,20 @@ async function main() { */ external import: 'a => promise<'a> = "%import" +/** +`panic(message)` throws a JavaScript `Error` prefixed with `Panic!`. +Use it for unrecoverable situations where the program should stop immediately. + +## Examples + +```rescript +let caught = try panic("Invariant violated") catch { +| JsExn(err) => JsExn.message(err)->Option.getOrThrow +} + +caught == "Panic! Invariant violated" +``` +*/ let panic = JsError.panic /** @@ -123,6 +150,37 @@ let assertEqual = (a, b) => { } } +/** +`null` returns the JavaScript `null` value as a `nullable<'a>`. +Pair it with the `Nullable` helpers to inspect or convert it safely. + +## Examples + +```rescript +null->Nullable.toOption == None +``` +*/ external null: nullable<'a> = "#null" +/** +`undefined` returns the JavaScript `undefined` value as a `nullable<'a>`. +Combine it with `Nullable` utilities to interoperate with optional JS fields. + +## Examples + +```rescript +undefined->Nullable.toOption == None +``` +*/ external undefined: nullable<'a> = "#undefined" +/** +`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum. +Useful when narrowing values from dynamic sources. + +## Examples + +```rescript +typeof(1) == #number +typeof("a") == #string +``` +*/ external typeof: 'a => Type.t = "#typeof" From 6de0d61d38529391abc678b109e69dec38e38956 Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 22 Oct 2025 14:02:41 +0200 Subject: [PATCH 2/6] Completions --- .../tests/src/expected/CompletionExpressions.res.txt | 2 +- .../tests/src/expected/CompletionFunctionArguments.res.txt | 4 ++-- .../tests/src/expected/CompletionJsxProps.res.txt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt b/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt index 31c667898b..5fec6a7fc3 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt @@ -374,7 +374,7 @@ Path fnTakingRecord "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": null + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionExpressions.res 69:25 diff --git a/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt b/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt index 3beb757a82..498167f25f 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt @@ -48,7 +48,7 @@ Path someFn "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": null + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionFunctionArguments.res 16:25 @@ -372,7 +372,7 @@ Path someOtherFn "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": null + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionFunctionArguments.res 76:25 diff --git a/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt b/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt index 686f4f5ec9..c5af7eb2b9 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt @@ -40,7 +40,7 @@ Path CompletionSupport.TestComponent.make "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": null + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionJsxProps.res 6:50 @@ -378,7 +378,7 @@ Path CompletionSupport.TestComponent.make "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": null + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionJsxProps.res 44:44 From 2c8554f79d7d0b2ae67f6fde4ab9a39dccc9f593 Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 22 Oct 2025 14:07:15 +0200 Subject: [PATCH 3/6] Fix --- packages/@rescript/runtime/lib/es6/Stdlib.js | 2 +- packages/@rescript/runtime/lib/js/Stdlib.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@rescript/runtime/lib/es6/Stdlib.js b/packages/@rescript/runtime/lib/es6/Stdlib.js index bbb1fc648d..042a69ee3d 100644 --- a/packages/@rescript/runtime/lib/es6/Stdlib.js +++ b/packages/@rescript/runtime/lib/es6/Stdlib.js @@ -12,7 +12,7 @@ function assertEqual(a, b) { RE_EXN_ID: "Assert_failure", _1: [ "Stdlib.res", - 122, + 149, 4 ], Error: new Error() diff --git a/packages/@rescript/runtime/lib/js/Stdlib.js b/packages/@rescript/runtime/lib/js/Stdlib.js index 283c1d3303..3b853566f5 100644 --- a/packages/@rescript/runtime/lib/js/Stdlib.js +++ b/packages/@rescript/runtime/lib/js/Stdlib.js @@ -12,7 +12,7 @@ function assertEqual(a, b) { RE_EXN_ID: "Assert_failure", _1: [ "Stdlib.res", - 122, + 149, 4 ], Error: new Error() From 2394302691ea9a572d38e661034b628ae9ca0a22 Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 22 Oct 2025 14:30:10 +0200 Subject: [PATCH 4/6] Simplify --- packages/@rescript/runtime/Stdlib.res | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/@rescript/runtime/Stdlib.res b/packages/@rescript/runtime/Stdlib.res index 6c88c06ee0..05e18b3182 100644 --- a/packages/@rescript/runtime/Stdlib.res +++ b/packages/@rescript/runtime/Stdlib.res @@ -63,8 +63,8 @@ type lazy_t<+'a> = Lazy.t<'a> @deprecated("Use rescript-webapi instead") @val external window: Dom.window = "window" @deprecated("Use rescript-webapi instead") @val external document: Dom.document = "document" /** -`globalThis` exposes the host global object (`window` in browsers, `global` in Node, etc.). -Use it to access platform-specific globals without branching. +`globalThis` gives you the host global object (`window` in browsers, `global` in Node, etc.). +You can reach shared globals from any runtime without special checks. ## Examples @@ -121,7 +121,7 @@ external import: 'a => promise<'a> = "%import" /** `panic(message)` throws a JavaScript `Error` prefixed with `Panic!`. -Use it for unrecoverable situations where the program should stop immediately. +Call it when something went wrong and the program should stop right away. ## Examples @@ -152,7 +152,7 @@ let assertEqual = (a, b) => { /** `null` returns the JavaScript `null` value as a `nullable<'a>`. -Pair it with the `Nullable` helpers to inspect or convert it safely. +Use the `Nullable` helpers to convert it into an `option` or to read the value. ## Examples @@ -163,7 +163,7 @@ null->Nullable.toOption == None external null: nullable<'a> = "#null" /** `undefined` returns the JavaScript `undefined` value as a `nullable<'a>`. -Combine it with `Nullable` utilities to interoperate with optional JS fields. +Use the `Nullable` helpers to convert it into an `option` or to read the value. ## Examples @@ -174,7 +174,7 @@ undefined->Nullable.toOption == None external undefined: nullable<'a> = "#undefined" /** `typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum. -Useful when narrowing values from dynamic sources. +It helps you inspect values that come from JavaScript APIs. ## Examples From 5adf893f772eb0ae9d391adb7becb6cb3bad0fe8 Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 22 Oct 2025 15:15:28 +0200 Subject: [PATCH 5/6] Completions again --- .../tests/src/expected/CompletionExpressions.res.txt | 2 +- .../tests/src/expected/CompletionFunctionArguments.res.txt | 4 ++-- .../tests/src/expected/CompletionJsxProps.res.txt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt b/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt index 5fec6a7fc3..2e1b28d5f5 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionExpressions.res.txt @@ -374,7 +374,7 @@ Path fnTakingRecord "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nIt helps you inspect values that come from JavaScript APIs.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionExpressions.res 69:25 diff --git a/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt b/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt index 498167f25f..48c89535fb 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionFunctionArguments.res.txt @@ -48,7 +48,7 @@ Path someFn "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nIt helps you inspect values that come from JavaScript APIs.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionFunctionArguments.res 16:25 @@ -372,7 +372,7 @@ Path someOtherFn "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nIt helps you inspect values that come from JavaScript APIs.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionFunctionArguments.res 76:25 diff --git a/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt b/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt index c5af7eb2b9..af410bf97a 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionJsxProps.res.txt @@ -40,7 +40,7 @@ Path CompletionSupport.TestComponent.make "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nIt helps you inspect values that come from JavaScript APIs.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionJsxProps.res 6:50 @@ -378,7 +378,7 @@ Path CompletionSupport.TestComponent.make "kind": 12, "tags": [], "detail": "'a => Type.t", - "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nUseful when narrowing values from dynamic sources.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`typeof(value)` exposes JavaScript's `typeof` operator and returns a `Type.t` enum.\nIt helps you inspect values that come from JavaScript APIs.\n\n## Examples\n\n```rescript\ntypeof(1) == #number\ntypeof(\"a\") == #string\n```\n"} }] Complete src/CompletionJsxProps.res 44:44 From c06f5cf6680160cffed3fda6b8a05f0b47c65a51 Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 22 Oct 2025 15:38:30 +0200 Subject: [PATCH 6/6] Add warning about rather writing own bindings --- packages/@rescript/runtime/Stdlib.res | 4 ++++ packages/@rescript/runtime/lib/es6/Stdlib.js | 2 +- packages/@rescript/runtime/lib/js/Stdlib.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/@rescript/runtime/Stdlib.res b/packages/@rescript/runtime/Stdlib.res index 05e18b3182..52f2771c69 100644 --- a/packages/@rescript/runtime/Stdlib.res +++ b/packages/@rescript/runtime/Stdlib.res @@ -68,6 +68,10 @@ You can reach shared globals from any runtime without special checks. ## Examples +**Note:** These are demonstrative examples. In real code, prefer writing your own type-safe bindings. +See [`Bind to Global JS Values`](https://rescript-lang.org/docs/manual/v12.0.0/bind-to-global-js-values). + + ```rescript typeof(globalThis["setTimeout"]) == #function diff --git a/packages/@rescript/runtime/lib/es6/Stdlib.js b/packages/@rescript/runtime/lib/es6/Stdlib.js index 042a69ee3d..ff17e733ec 100644 --- a/packages/@rescript/runtime/lib/es6/Stdlib.js +++ b/packages/@rescript/runtime/lib/es6/Stdlib.js @@ -12,7 +12,7 @@ function assertEqual(a, b) { RE_EXN_ID: "Assert_failure", _1: [ "Stdlib.res", - 149, + 153, 4 ], Error: new Error() diff --git a/packages/@rescript/runtime/lib/js/Stdlib.js b/packages/@rescript/runtime/lib/js/Stdlib.js index 3b853566f5..0a61b412cd 100644 --- a/packages/@rescript/runtime/lib/js/Stdlib.js +++ b/packages/@rescript/runtime/lib/js/Stdlib.js @@ -12,7 +12,7 @@ function assertEqual(a, b) { RE_EXN_ID: "Assert_failure", _1: [ "Stdlib.res", - 149, + 153, 4 ], Error: new Error()