From 3c99674c450002f34491e2721f09d647c26b0108 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 12 Sep 2025 11:16:42 +0200 Subject: [PATCH 1/3] Add Promise.sleep to std --- packages/@rescript/runtime/Stdlib_Promise.res | 5 +++++ packages/@rescript/runtime/Stdlib_Promise.resi | 15 +++++++++++++++ .../@rescript/runtime/lib/es6/Stdlib_Promise.js | 7 +++++++ .../@rescript/runtime/lib/js/Stdlib_Promise.js | 7 +++++++ .../tests/src/expected/Completion.res.txt | 6 ------ .../src/expected/DotPipeCompletionSpec.res.txt | 12 ------------ 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/packages/@rescript/runtime/Stdlib_Promise.res b/packages/@rescript/runtime/Stdlib_Promise.res index 05f41fa834..1fc411efe3 100644 --- a/packages/@rescript/runtime/Stdlib_Promise.res +++ b/packages/@rescript/runtime/Stdlib_Promise.res @@ -112,3 +112,8 @@ external any: array> => t<'a> = "any" external done: promise<'a> => unit = "%ignore" external ignore: promise<'a> => unit = "%ignore" + +let sleep = ms => + make((resolve, _) => { + let _ = Stdlib_Global.setTimeout(resolve, ms) + }) diff --git a/packages/@rescript/runtime/Stdlib_Promise.resi b/packages/@rescript/runtime/Stdlib_Promise.resi index 626ae5f70c..773bc2d0d9 100644 --- a/packages/@rescript/runtime/Stdlib_Promise.resi +++ b/packages/@rescript/runtime/Stdlib_Promise.resi @@ -441,3 +441,18 @@ external done: promise<'a> => unit = "%ignore" without having to store or process it further. */ external ignore: promise<'a> => unit = "%ignore" + +/** +`sleep(ms)` creates a promise that resolves after `ms` milliseconds. + +## Examples + +```rescript +Promise.sleep(1000) +->Promise.thenResolve(() => { + Console.log("1 second has passed") +}) +->Promise.ignore +``` +*/ +let sleep: int => promise diff --git a/packages/@rescript/runtime/lib/es6/Stdlib_Promise.js b/packages/@rescript/runtime/lib/es6/Stdlib_Promise.js index 475b96b4d9..a01d65f131 100644 --- a/packages/@rescript/runtime/lib/es6/Stdlib_Promise.js +++ b/packages/@rescript/runtime/lib/es6/Stdlib_Promise.js @@ -6,7 +6,14 @@ function $$catch(promise, callback) { return promise.catch(err => callback(Primitive_exceptions.internalToException(err))); } +function sleep(ms) { + return new Promise((resolve, param) => { + setTimeout(resolve, ms); + }); +} + export { $$catch, + sleep, } /* No side effect */ diff --git a/packages/@rescript/runtime/lib/js/Stdlib_Promise.js b/packages/@rescript/runtime/lib/js/Stdlib_Promise.js index eb6fd42776..d0ab9ce4f3 100644 --- a/packages/@rescript/runtime/lib/js/Stdlib_Promise.js +++ b/packages/@rescript/runtime/lib/js/Stdlib_Promise.js @@ -6,5 +6,12 @@ function $$catch(promise, callback) { return promise.catch(err => callback(Primitive_exceptions.internalToException(err))); } +function sleep(ms) { + return new Promise((resolve, param) => { + setTimeout(resolve, ms); + }); +} + exports.$$catch = $$catch; +exports.sleep = sleep; /* No side effect */ diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index 0e525703b2..85b675f957 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -238,12 +238,6 @@ Path Array. "tags": [], "detail": "(array<'a>, ('a, 'a) => Ordering.t) => unit", "documentation": {"kind": "markdown", "value": "\n`sort(array, comparator)` sorts `array` in-place using the `comparator` function.\n\nBeware this will *mutate* the array.\n\nSee [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.\n\n## Examples\n\n```rescript\nlet array = [3, 2, 1]\narray->Array.sort((a, b) => float(a - b))\narray == [1, 2, 3]\n```\n"} - }, { - "label": "filterMapWithIndex", - "kind": 12, - "tags": [], - "detail": "(array<'a>, ('a, int) => option<'b>) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`filterMapWithIndex(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]->Array.filterMapWithIndex((item, index) =>\n switch item {\n | \"Hello\" => Some(index)\n | _ => None\n }\n) == [0]\n```\n"} }, { "label": "length", "kind": 12, diff --git a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt index 27187512fb..f9947b67ff 100644 --- a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt +++ b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt @@ -374,18 +374,6 @@ Path filt "range": {"start": {"line": 86, "character": 34}, "end": {"line": 86, "character": 35}}, "newText": "" }] - }, { - "label": "->Array.filterMapWithIndex", - "kind": 12, - "tags": [], - "detail": "(array<'a>, ('a, int) => option<'b>) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`filterMapWithIndex(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]->Array.filterMapWithIndex((item, index) =>\n switch item {\n | \"Hello\" => Some(index)\n | _ => None\n }\n) == [0]\n```\n"}, - "sortText": "filterMapWithIndex", - "insertText": "->Array.filterMapWithIndex", - "additionalTextEdits": [{ - "range": {"start": {"line": 86, "character": 34}, "end": {"line": 86, "character": 35}}, - "newText": "" - }] }, { "label": "->Array.filter", "kind": 12, From b4fcbfd98e35fc179aa1592db3a7faa006f9fc82 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 12 Sep 2025 11:16:55 +0200 Subject: [PATCH 2/3] Add instruction how to format codeblocks --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b1efc73834..243695fa6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -350,6 +350,7 @@ Some tips: - Always use `@deprecated` when applicable. - Always use `@raise` when applicable. - Always provide a `@see` tag pointing to MDN for more information when available. +- Format code samples in doc comments via `./cli/rescript-tools.js format-codeblocks ` See [Ocamldoc documentation](http://caml.inria.fr/pub/docs/manual-ocaml/ocamldoc.html#sec333) for more details. @@ -389,6 +390,7 @@ Adding a new entry there requires re-running the analysis tests. Follow these st (If a `make` command fails, consider using the [DevContainer](#b-devcontainer).) Finally, add a line to [CHANGELOG.md](CHANGELOG.md), using the `#### :nail_care: Polish` section. + ## Code structure The highlevel architecture is illustrated as below: From 4f5e15433b8e09f55401ae5f3b0f2702ec431a4d Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 12 Sep 2025 13:17:35 +0200 Subject: [PATCH 3/3] Classic --- .../tests/src/expected/Completion.res.txt | 6 ++++++ .../tests/src/expected/DotPipeCompletionSpec.res.txt | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index 85b675f957..0e525703b2 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -238,6 +238,12 @@ Path Array. "tags": [], "detail": "(array<'a>, ('a, 'a) => Ordering.t) => unit", "documentation": {"kind": "markdown", "value": "\n`sort(array, comparator)` sorts `array` in-place using the `comparator` function.\n\nBeware this will *mutate* the array.\n\nSee [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.\n\n## Examples\n\n```rescript\nlet array = [3, 2, 1]\narray->Array.sort((a, b) => float(a - b))\narray == [1, 2, 3]\n```\n"} + }, { + "label": "filterMapWithIndex", + "kind": 12, + "tags": [], + "detail": "(array<'a>, ('a, int) => option<'b>) => array<'b>", + "documentation": {"kind": "markdown", "value": "\n`filterMapWithIndex(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]->Array.filterMapWithIndex((item, index) =>\n switch item {\n | \"Hello\" => Some(index)\n | _ => None\n }\n) == [0]\n```\n"} }, { "label": "length", "kind": 12, diff --git a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt index f9947b67ff..27187512fb 100644 --- a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt +++ b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt @@ -374,6 +374,18 @@ Path filt "range": {"start": {"line": 86, "character": 34}, "end": {"line": 86, "character": 35}}, "newText": "" }] + }, { + "label": "->Array.filterMapWithIndex", + "kind": 12, + "tags": [], + "detail": "(array<'a>, ('a, int) => option<'b>) => array<'b>", + "documentation": {"kind": "markdown", "value": "\n`filterMapWithIndex(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]->Array.filterMapWithIndex((item, index) =>\n switch item {\n | \"Hello\" => Some(index)\n | _ => None\n }\n) == [0]\n```\n"}, + "sortText": "filterMapWithIndex", + "insertText": "->Array.filterMapWithIndex", + "additionalTextEdits": [{ + "range": {"start": {"line": 86, "character": 34}, "end": {"line": 86, "character": 35}}, + "newText": "" + }] }, { "label": "->Array.filter", "kind": 12,