From 2717e6585f7585559631fc388d65d7d0cec401f5 Mon Sep 17 00:00:00 2001 From: customcommander Date: Thu, 21 Jan 2021 00:27:20 +0000 Subject: [PATCH] refactor: deprecate tags composition and user-defined tags This simplifies a few things and some code has been deleted as a result. BREAKING CHANGE: users cannot define their own tags or compose tags anymore These two features have never been "advertised" anyway so there is very little risk that anybody ever used them. However this is in effect a breakin change and therefore warrants a major release. --- src/index.js | 43 ++++++---------------- src/utils/intersperse.js | 19 ---------- src/utils/tag-function.js | 76 +++++++++++++++++++++++++++++++++++---- src/utils/transform.js | 20 ----------- src/utils/use-tag.js | 32 ----------------- test.js | 47 ------------------------ 6 files changed, 80 insertions(+), 157 deletions(-) delete mode 100644 src/utils/intersperse.js delete mode 100644 src/utils/transform.js delete mode 100644 src/utils/use-tag.js diff --git a/src/index.js b/src/index.js index cf6a03e..f4174d4 100644 --- a/src/index.js +++ b/src/index.js @@ -3,36 +3,13 @@ * @copyright (c) 2021 Julien Gonzalez */ -const tag_function = require('./utils/tag-function'); -const use_tag = require('./utils/use-tag'); -const intersperse = require('./utils/intersperse'); -const defaults = require('./defaults'); -const hide = require('./hide'); -const list = require('./list'); -const lower = require('./lower'); -const pluralize = require('./pluralize'); -const time = require('./time'); -const trim = require('./trim'); -const upper = require('./upper'); - -const - { compose - , join - } = require('./utils/fp'); - -const tag = (...fns) => - (strs, ...vals) => - compose(join(''), ...fns.map(use_tag.unwrap)) - (intersperse(strs, vals)); - -tag.defaults = use_tag(defaults); -tag.list = use_tag(list); -tag.hide = use_tag(hide); -tag.lower = use_tag(lower); -tag.pluralize = use_tag(pluralize); -tag.time = use_tag(time); -tag.trim = use_tag(trim); -tag.upper = use_tag(upper); -tag.of = compose(use_tag, tag_function); - -module.exports = tag; \ No newline at end of file +module.exports = { + defaults: require('./defaults'), + hide: require('./hide'), + list: require('./list'), + lower: require('./lower'), + pluralize: require('./pluralize'), + time: require('./time'), + trim: require('./trim'), + upper: require('./upper') +}; diff --git a/src/utils/intersperse.js b/src/utils/intersperse.js deleted file mode 100644 index d04fa24..0000000 --- a/src/utils/intersperse.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @license MIT - * @copyright (c) 2021 Julien Gonzalez - */ - -const {init} = require('./fp'); - -/** - * Put `ys` inside `xs` at regular intervals. - * - * @example - * intersperse([1, 3, 5], [2, 4]) - * //=> [1, 2, 3, 4, 5] - * - * @param {Array} xs - * @param {Array} ys - * @return {Array} - */ -module.exports = (xs, ys) => init(xs.flatMap((x, i) => [x, ys[i]])); diff --git a/src/utils/tag-function.js b/src/utils/tag-function.js index ff32bd1..187d65a 100644 --- a/src/utils/tag-function.js +++ b/src/utils/tag-function.js @@ -3,15 +3,79 @@ * @copyright (c) 2021 Julien Gonzalez */ +const {cont, init} = require('./fp'); + +/** + * Put `ys` inside `xs` at regular intervals. + * + * @example + * intersperse([1, 3, 5], [2, 4]) + * //=> [1, 2, 3, 4, 5] + * + * @param {Array} xs + * @param {Array} ys + * @return {Array} + */ +const intersperse = + (xs, ys) => + init(xs.flatMap((x, i) => [x, ys[i]])); + +/** + * Given `fn` a function that takes three parameters and returns + * a tuple 'x' of three elements, apply `fn` to tuples 'y' of three elements. + * The first tuple 'y' is made of the first three elements of `xs`. + * The next tuple 'y' (and all others) takes its first element from the + * last element of tuple 'x' returned by `fn` when applied to the previous tuple 'y'. + * The last two elements of tuple 'y' are taken from the next two consecutive elements of `xs`. + * + * Example: + * + * ```javascript + * const fn = (a, b, c) => [a+1, b+2, c+3]; + * const xs = [10, 20, 30, 40, 50, 60]; + * transformer(fn, xs); + * // [10, 20, 30, 40, 50, 60, 70] + * // ^^ ^^ ^^ + * // [11, 22, 33, 40, 50, 60, 70] + * // ^^ ^^ ^^ + * // [11, 22, 34, 42, 53, 60, 70] + * // ^^ ^^ ^^ + * //=> [11, 22, 34, 43, 54, 62, 73] + * ``` + * + * @param {function()} fn + * @param {Array} xs + * @param {number} [i=1] + * @return {Array} + */ +const transformer = + (fn, xs, i=1) => + i >= xs.length + ? xs + : cont(fn(...xs.slice(i-1, i+2))) + ( ret => + transformer + ( fn + , xs.slice(0, i-1).concat(ret, xs.slice(i+2)) + , i+2 + )); + +const read_user_config = + fn => (strings_or_config, ...values) => + Array.isArray(strings_or_config) + ? fn({}, strings_or_config, values) + : (strings, ...values) => fn(strings_or_config, strings, values); + /** * @param {TagFunction} fn * @param {!TagOptions=} opts * @return {TagFunction|TagConfigFunction} */ module.exports = - (fn, opts = {}) => (...args) => - { const is_config_call = typeof args[0] === 'object'; // foo`…` vs foo({…})`…` - return (is_config_call - ? (l, x, r) => fn(l, x, r, {...opts, ...args[0]}) - : fn(...args, opts)); - }; + (fn, default_config = {}, postprocess = xs => xs.join('')) => + read_user_config((user_config, strings, values) => + { const final_config = {...default_config, ...user_config}; + const parts = intersperse(strings, values); + const preprocess = (l, x, r) => fn(l, x, r, final_config); + return postprocess(transformer(preprocess, parts)); + }); \ No newline at end of file diff --git a/src/utils/transform.js b/src/utils/transform.js deleted file mode 100644 index 296aa44..0000000 --- a/src/utils/transform.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @license MIT - * @copyright (c) 2021 Julien Gonzalez - */ - -const {cont} = require('./fp'); - -const transformer = (fn, xs, i=1) => - i >= xs.length - ? xs - : cont(fn(...xs.slice(i-1, i+2))) - ( ret => - transformer - ( fn - , xs.slice(0, i-1).concat(ret, xs.slice(i+2)) - , i+2 - ) - ); - -module.exports = fn => xs => transformer(fn, xs); diff --git a/src/utils/use-tag.js b/src/utils/use-tag.js deleted file mode 100644 index 33b7ce1..0000000 --- a/src/utils/use-tag.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @license MIT - * @copyright (c) 2021 Julien Gonzalez - */ - -const {compose, join} = require('./fp'); -const intersperse = require('./intersperse'); -const transform = require('./transform'); - -const KEY = Symbol(); - -const is_opts = - x => - x !== null - && !Array.isArray(x) - && typeof x === 'object'; - -const tag_function = fn => { - const tag_fn = - (strs, ...vals) => - is_opts(strs) - ? tag_function(fn(strs)) - : compose(join(''), transform(fn), intersperse) - (strs, vals); - - tag_fn[KEY] = transform(fn); - return tag_fn; -}; - -tag_function.unwrap = fn => fn[KEY] || fn; - -module.exports = tag_function; diff --git a/test.js b/test.js index 86e8fe0..52e8c74 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,4 @@ const test = require('tape'); -const tag = require('./dist'); const { defaults , hide @@ -11,15 +10,6 @@ const , upper } = require('./dist'); -test('tag: can compose other tags', t => { - t.plan(1); - - t.is - ( tag(upper, trim)`foo=${' foo '}, bar=${' bar '}` - , "foo=FOO, bar=BAR" - ); -}); - test('defaults: replace empty values', t => { t.plan(2); @@ -36,43 +26,6 @@ test('defaults: replace empty values', t => { ); }); -test('tag: can compose user-defined tags', t => { - t.plan(1); - - const myTag = - tag.of( - (l, x, r) => - [ '|' - , x - , '|' - ]); - - t.is - ( tag(upper, myTag, trim)`foo=${' foo '}, bar=${' bar '}` - , "|FOO|BAR|" - ); -}); - -test('user-defined tags can receive options', t => { - t.plan(1); - - const myTag = - tag.of - ( (l, x, r, {foo}) => - [ l - , foo - , r - ] - , { foo: 'fooooooo' - } - ); - - t.is - ( myTag({foo: 'baaar'})`Hello ${'world'}!` - , 'Hello baaar!' - ); -}); - test('hide: hides all values', t => { t.plan(5);