From a12004f55ba541539fb37aec535beb5599bfcc73 Mon Sep 17 00:00:00 2001 From: Jelle De Loecker Date: Fri, 26 Apr 2024 18:17:41 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20`Optional`=20value-wrapper=20?= =?UTF-8?q?class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + lib/init.js | 1 + lib/optional.js | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 lib/optional.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 17e727a..f734b60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * Fix comments breaking the SSE request handler * Add `Blast.isAppleWebkit` boolean * Add `Blast.environment` string property and `isProduction`, `isDevelopment` and `isStaging` booleans +* Add `Optional` value-wrapper class ## 0.9.2 (2024-02-25) diff --git a/lib/init.js b/lib/init.js index c3ae71b..b136eec 100644 --- a/lib/init.js +++ b/lib/init.js @@ -483,6 +483,7 @@ function BlastInit(modifyPrototype) { 'Error', 'Placeholder', 'Trail', + 'Optional', 'Informer', 'State', 'Request', diff --git a/lib/optional.js b/lib/optional.js new file mode 100644 index 0000000..8055183 --- /dev/null +++ b/lib/optional.js @@ -0,0 +1,134 @@ +const VALUE = Symbol('value'), + CALLBACKS = Symbol('callbacks'); + +/** + * An optional value + * + * @constructor + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @param {*} value + */ +const Optional = Fn.inherits('Develry.Placeholder', function Optional(value) { + this[VALUE] = value; + this[CALLBACKS] = []; +}); + +/** + * Undry the value + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @param {Object} value + * + * @return {Optional} + */ +Optional.setStatic(function unDry(value) { + let result = Object.create(this.prototype); + result[VALUE] = value.value; + return result; +}); + +/** + * Get the current value + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @return {*} + */ +Optional.setProperty(function value() { + return this[VALUE]; +}, function setValue(new_value) { + this[VALUE] = new_value; + + let callbacks = this[CALLBACKS], + i; + + for (i = 0; i < callbacks.length; i++) { + callbacks[i](new_value); + } +}); + +/** + * Return the serialized json-dry representation + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + */ +Optional.setMethod(function toDry() { + + let value = { + value: this[VALUE] + }; + + return { + value: value + }; +}); + +/** + * Add a listener + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @param {Function} callback + */ +Optional.setMethod(function onChange(callback) { + this[CALLBACKS].push(callback); +}); + +/** + * Is there a value present? + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @return {boolean} + */ +Optional.setMethod(function isPresent() { + return this[VALUE] != null; +}); + +/** + * Get the current value if it is present of the given fallback value if it is not + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @param {*} fallback + * + * @return {*} + */ +Optional.setMethod(function orElse(fallback) { + + if (this.isPresent()) { + return this[VALUE]; + } + + return fallback; +}); + +/** + * This method should return the actual value + * + * @author Jelle De Loecker + * @since 0.9.3 + * @version 0.9.3 + * + * @return {*} + */ +Optional.setMethod(function getResolvedValue() { + return this[VALUE]; +}); \ No newline at end of file