diff --git a/benchmarks/benchmarks.js b/benchmarks/benchmarks.js index 4014eb4..a20970e 100644 --- a/benchmarks/benchmarks.js +++ b/benchmarks/benchmarks.js @@ -1,11 +1,14 @@ import { Bench } from 'tinybench'; +import { markdownTable } from 'markdown-table'; import local from 'classnames-local'; +import bind from 'classnames-local/bind.js'; import dedupe from 'classnames-local/dedupe.js'; import localPackage from 'classnames-local/package.json' with { type: 'json' }; import npm from 'classnames-npm'; import npmDedupe from 'classnames-npm/dedupe.js'; +import npmBind from 'classnames-npm/bind.js'; import npmPackage from 'classnames-npm/package.json' with { type: 'json' }; if (localPackage.version !== npmPackage.version) { @@ -40,9 +43,9 @@ const benchmarks = [ export async function runBenchmarks () { for (const benchmark of benchmarks) { - console.log(`Benchmarking '${benchmark.description}'.`); + console.log(`Benchmarking '${benchmark.description}'.\n`); const bench = await runBenchmark(benchmark); - console.table(bench.table()); + printTable(bench); } console.log('Finished!'); @@ -51,22 +54,23 @@ export async function runBenchmarks () { async function runBenchmark (benchmark) { const bench = new Bench(); - bench.add(`local#${benchmark.description}`, () => { - local(...benchmark.args); - }); + bench.add('default/local', () => local(...benchmark.args)); + bench.add('default/npm', () => npm(...benchmark.args)); - bench.add(`npm#${benchmark.description}`, () => { - npm(...benchmark.args); - }); + bench.add('bind/local', () => bind(...benchmark.args)); + bench.add('bind/npm', () => npmBind(...benchmark.args)); - bench.add(`local/dedupe#${benchmark.description}`, () => { - dedupe(...benchmark.args); - }); - - bench.add(`npm/dedupe#${benchmark.description}`, () => { - npmDedupe(...benchmark.args); - }); + bench.add('dedupe/local', () => dedupe(...benchmark.args)); + bench.add('dedupe/npm', () => npmDedupe(...benchmark.args)); await bench.run(); return bench; } + +function printTable(bench) { + const table = bench.table(); + const headers = Object.keys(table[0]); + const data = table.map((entry) => headers.map((header) => entry[header])); + + console.log(markdownTable([headers, ...data]) + '\n'); +} diff --git a/benchmarks/package.json b/benchmarks/package.json index 79814f2..cbb5e9f 100644 --- a/benchmarks/package.json +++ b/benchmarks/package.json @@ -12,6 +12,7 @@ "classnames-local": "file:../", "classnames-npm": "npm:classnames@*", "http-server": "^14.1.1", + "markdown-table": "^3.0.3", "rollup": "^4.9.1", "tinybench": "^2.5.1" } diff --git a/bind.js b/bind.js index 591f859..3add1d6 100644 --- a/bind.js +++ b/bind.js @@ -11,33 +11,56 @@ var hasOwn = {}.hasOwnProperty; function classNames () { - var classes = []; + var classes = ''; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; - if (!arg) continue; - - var argType = typeof arg; - - if (argType === 'string' || argType === 'number') { - classes.push(this && this[arg] || arg); - } else if (Array.isArray(arg)) { - classes.push(classNames.apply(this, arg)); - } else if (argType === 'object') { - if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { - classes.push(arg.toString()); - continue; - } - - for (var key in arg) { - if (hasOwn.call(arg, key) && arg[key]) { - classes.push(this && this[key] || key); - } - } + if (arg) { + classes = appendClass(classes, parseValue.call(this, arg)); } } - return classes.join(' '); + return classes; + } + + function parseValue (arg) { + if (typeof arg === 'string' || typeof arg === 'number') { + return this && this[arg] || arg; + } + + if (typeof arg !== 'object') { + return ''; + } + + if (Array.isArray(arg)) { + return classNames.apply(this, arg); + } + + if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { + return arg.toString(); + } + + var classes = ''; + + for (var key in arg) { + if (hasOwn.call(arg, key) && arg[key]) { + classes = appendClass(classes, this && this[key] || key); + } + } + + return classes; + } + + function appendClass (value, newClass) { + if (!newClass) { + return value; + } + + if (value) { + return value + ' ' + newClass; + } + + return value + newClass; } if (typeof module !== 'undefined' && module.exports) { diff --git a/index.js b/index.js index 8fba6af..a42ea92 100644 --- a/index.js +++ b/index.js @@ -10,39 +10,57 @@ var hasOwn = {}.hasOwnProperty; - function classNames() { - var classes = []; + function classNames () { + var classes = ''; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; - if (!arg) continue; - - var argType = typeof arg; - - if (argType === 'string' || argType === 'number') { - classes.push(arg); - } else if (Array.isArray(arg)) { - if (arg.length) { - var inner = classNames.apply(null, arg); - if (inner) { - classes.push(inner); - } - } - } else if (argType === 'object') { - if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { - classes.push(arg.toString()); - continue; - } - - for (var key in arg) { - if (hasOwn.call(arg, key) && arg[key]) { - classes.push(key); - } - } + if (arg) { + classes = appendClass(classes, parseValue(arg)); } } - return classes.join(' '); + return classes; + } + + function parseValue (arg) { + if (typeof arg === 'string' || typeof arg === 'number') { + return arg; + } + + if (typeof arg !== 'object') { + return ''; + } + + if (Array.isArray(arg)) { + return classNames.apply(null, arg); + } + + if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { + return arg.toString(); + } + + var classes = ''; + + for (var key in arg) { + if (hasOwn.call(arg, key) && arg[key]) { + classes = appendClass(classes, key); + } + } + + return classes; + } + + function appendClass (value, newClass) { + if (!newClass) { + return value; + } + + if (value) { + return value + ' ' + newClass; + } + + return value + newClass; } if (typeof module !== 'undefined' && module.exports) { diff --git a/package-lock.json b/package-lock.json index 194b504..4a1db42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "classnames-local": "file:../", "classnames-npm": "npm:classnames@*", "http-server": "^14.1.1", + "markdown-table": "^3.0.3", "rollup": "^4.9.1", "tinybench": "^2.5.1" } @@ -1531,6 +1532,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/meow": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",