From 7ddef45ec4c76b7fc710e2c44d2087dfc2e7fa16 Mon Sep 17 00:00:00 2001 From: Timur Shemsedinov Date: Fri, 29 Nov 2024 20:19:59 +0200 Subject: [PATCH 1/4] Add Future implementation --- dist.js | 1 + lib/future.js | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ metautil.js | 1 + 3 files changed, 65 insertions(+) create mode 100644 lib/future.js diff --git a/dist.js b/dist.js index dbda61ba..5c1af92b 100644 --- a/dist.js +++ b/dist.js @@ -6,6 +6,7 @@ module.exports = { ...require('./lib/datetime.js'), ...require('./lib/error.js'), ...require('./lib/events.js'), + ...require('./lib/future.js'), ...require('./lib/http.js'), ...require('./lib/objects.js'), ...require('./lib/pool.js'), diff --git a/lib/future.js b/lib/future.js new file mode 100644 index 00000000..cbfd5969 --- /dev/null +++ b/lib/future.js @@ -0,0 +1,63 @@ +'use strict'; + +class Future { + #executor; + + constructor(executor) { + this.#executor = executor; + } + + static of(value) { + return new Future((resolve) => resolve(value)); + } + + chain(fn) { + return new Future((resolve, reject) => + this.fork( + (value) => fn(value).fork(resolve, reject), + (error) => reject(error), + ), + ); + } + + map(fn) { + return new Future((resolve, reject) => + this.fork( + (value) => + new Future((resolve, reject) => { + try { + resolve(fn(value)); + } catch (error) { + reject(error); + } + }).fork(resolve, reject), + (error) => reject(error), + ), + ); + } + + fork(successed, failed) { + this.#executor(successed, failed); + } + + promise() { + return new Promise((resolve, reject) => { + this.fork( + (value) => resolve(value), + (error) => reject(error), + ); + }); + } +} + +const futurify = + (fn) => + (...args) => + new Future((resolve, reject) => { + fn(...args, (err, data) => { + if (err) reject(err); + else resolve(data); + }); + }); + +module.exports = { Future, futurify }; diff --git a/metautil.js b/metautil.js index c748ee43..14fc374c 100644 --- a/metautil.js +++ b/metautil.js @@ -9,6 +9,7 @@ module.exports = { ...require('./lib/error.js'), ...require('./lib/events.js'), ...require('./lib/fs.js'), + ...require('./lib/future.js'), ...require('./lib/http.js'), ...require('./lib/network.js'), ...require('./lib/objects.js'), From afc5a109cbdf3a82a35e83af14b4a88dd45d5e62 Mon Sep 17 00:00:00 2001 From: Timur Shemsedinov Date: Sat, 30 Nov 2024 23:35:27 +0200 Subject: [PATCH 2/4] fixup! Add Future implementation --- lib/future.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/future.js b/lib/future.js index cbfd5969..0ba5b950 100644 --- a/lib/future.js +++ b/lib/future.js @@ -40,12 +40,9 @@ class Future { this.#executor(successed, failed); } - promise() { + toPromise() { return new Promise((resolve, reject) => { - this.fork( - (value) => resolve(value), - (error) => reject(error), - ); + this.fork(resolve, reject); }); } } From 1726eb3b08eb2e5e770abc935964ca03b9a5eed5 Mon Sep 17 00:00:00 2001 From: Timur Shemsedinov Date: Sat, 30 Nov 2024 23:39:25 +0200 Subject: [PATCH 3/4] Add Future..toThenable() --- lib/future.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/future.js b/lib/future.js index 0ba5b950..2b21db6e 100644 --- a/lib/future.js +++ b/lib/future.js @@ -45,6 +45,13 @@ class Future { this.fork(resolve, reject); }); } + + toThenable() { + const then = (resolve, reject) => { + this.fork(resolve, reject); + }; + return { then }; + } } const futurify = From 348b298c251f145cc5a9a04bf4a4a9415d90825a Mon Sep 17 00:00:00 2001 From: Timur Shemsedinov Date: Sat, 30 Nov 2024 23:41:43 +0200 Subject: [PATCH 4/4] fixup! Add Future implementation --- lib/future.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/future.js b/lib/future.js index 2b21db6e..974318b4 100644 --- a/lib/future.js +++ b/lib/future.js @@ -41,9 +41,9 @@ class Future { } toPromise() { - return new Promise((resolve, reject) => { - this.fork(resolve, reject); - }); + const { promise, resolve, reject } = Promise.withResolvers(); + this.fork(resolve, reject); + return promise; } toThenable() {