diff --git a/package-lock.json b/package-lock.json index 2098edd..a2b24dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,8 @@ "devDependencies": { "@rollup/plugin-typescript": "^11.1.2", "@rollup/pluginutils": "^5.0.2", + "benchmark": "^2.1.4", + "benny": "^3.7.1", "esbuild": "^0.17.19", "rollup": "^3.26.1", "tslib": "^2.6.0", @@ -24,6 +26,48 @@ "vite": "^4.3.9" } }, + "node_modules/@arrows/array": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@arrows/array/-/array-1.4.1.tgz", + "integrity": "sha512-MGYS8xi3c4tTy1ivhrVntFvufoNzje0PchjEz6G/SsWRgUKxL4tKwS6iPdO8vsaJYldagAeWMd5KRD0aX3Q39g==", + "dev": true, + "dependencies": { + "@arrows/composition": "^1.2.2" + } + }, + "node_modules/@arrows/composition": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@arrows/composition/-/composition-1.2.2.tgz", + "integrity": "sha512-9fh1yHwrx32lundiB3SlZ/VwuStPB4QakPsSLrGJFH6rCXvdrd060ivAZ7/2vlqPnEjBkPRRXOcG1YOu19p2GQ==", + "dev": true + }, + "node_modules/@arrows/dispatch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@arrows/dispatch/-/dispatch-1.0.3.tgz", + "integrity": "sha512-v/HwvrFonitYZM2PmBlAlCqVqxrkIIoiEuy5bQgn0BdfvlL0ooSBzcPzTMrtzY8eYktPyYcHg8fLbSgyybXEqw==", + "dev": true, + "dependencies": { + "@arrows/composition": "^1.2.2" + } + }, + "node_modules/@arrows/error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@arrows/error/-/error-1.0.2.tgz", + "integrity": "sha512-yvkiv1ay4Z3+Z6oQsUkedsQm5aFdyPpkBUQs8vejazU/RmANABx6bMMcBPPHI4aW43VPQmXFfBzr/4FExwWTEA==", + "dev": true + }, + "node_modules/@arrows/multimethod": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@arrows/multimethod/-/multimethod-1.4.1.tgz", + "integrity": "sha512-AZnAay0dgPnCJxn3We5uKiB88VL+1ZIF2SjZohLj6vqY2UyvB/sKdDnFP+LZNVsTC5lcnGPmLlRRkAh4sXkXsQ==", + "dev": true, + "dependencies": { + "@arrows/array": "^1.4.1", + "@arrows/composition": "^1.2.2", + "@arrows/error": "^1.0.2", + "fast-deep-equal": "^3.1.3" + } + }, "node_modules/@babel/parser": { "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", @@ -819,6 +863,30 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -849,12 +917,86 @@ "node": "*" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "node_modules/benny": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/benny/-/benny-3.7.1.tgz", + "integrity": "sha512-USzYxODdVfOS7JuQq/L0naxB788dWCiUgUTxvN+WLPt/JfcDURNNj8kN/N+uK6PDvuR67/9/55cVKGPleFQINA==", + "dev": true, + "dependencies": { + "@arrows/composition": "^1.0.0", + "@arrows/dispatch": "^1.0.2", + "@arrows/multimethod": "^1.1.6", + "benchmark": "^2.1.4", + "common-tags": "^1.8.0", + "fs-extra": "^10.0.0", + "json2csv": "^5.0.6", + "kleur": "^4.1.4", + "log-update": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/benny/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/benny/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/benny/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -900,6 +1042,36 @@ "node": "*" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", @@ -919,6 +1091,15 @@ "node": "^12.20.0 || >=14" } }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", @@ -963,6 +1144,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/esbuild": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", @@ -1109,6 +1296,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/jju": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", @@ -1121,6 +1317,34 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json2csv": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.7.tgz", + "integrity": "sha512-YRZbUnyaJZLZUJSRi2G/MqahCyRv9n/ds+4oIetjDF3jWQA7AG7iSeKTiZiCNqtMZM7HDyt0e/W6lEnoGEmMGA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "dependencies": { + "commander": "^6.1.0", + "jsonparse": "^1.3.1", + "lodash.get": "^4.4.2" + }, + "bin": { + "json2csv": "bin/json2csv.js" + }, + "engines": { + "node": ">= 10", + "npm": ">= 6.13.0" + } + }, + "node_modules/json2csv/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", @@ -1136,6 +1360,24 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/kolorist": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", @@ -1172,6 +1414,24 @@ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", "dev": true }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", @@ -1205,6 +1465,15 @@ "node": ">=12" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", @@ -1262,6 +1531,21 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", @@ -1327,6 +1611,12 @@ "pathe": "^1.1.0" } }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "dev": true + }, "node_modules/postcss": { "version": "8.4.24", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", @@ -1401,6 +1691,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/rollup": { "version": "3.26.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.1.tgz", @@ -1438,6 +1741,44 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1483,6 +1824,32 @@ "node": ">=0.6.19" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1558,6 +1925,18 @@ "node": ">=4" } }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", @@ -1821,6 +2200,35 @@ "node": ">=8" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 60e0968..49feb5f 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "build": "vite build", "pretest": "npm run build:test", "test": "vitest run", + "benchmark": "node test/benchmark.js", "build:test:esbuild": "node test/esbuild.js", "build:test:rollup": "rollup -c test/rollup.config.ts --configPlugin typescript", "build:test:vite": "vite build --config test/vite.config.ts", @@ -61,6 +62,8 @@ "devDependencies": { "@rollup/plugin-typescript": "^11.1.2", "@rollup/pluginutils": "^5.0.2", + "benchmark": "^2.1.4", + "benny": "^3.7.1", "esbuild": "^0.17.19", "rollup": "^3.26.1", "tslib": "^2.6.0", diff --git a/src/esbuild.ts b/src/esbuild.ts index ea296b8..1867bb4 100644 --- a/src/esbuild.ts +++ b/src/esbuild.ts @@ -5,11 +5,14 @@ import { getCompiler } from "./utils"; import { Options } from "./types"; export * from "./types"; -export default function inlineFunction({ macros = {} }: Options): Plugin { +export default function inlineFunction({ + macros = {}, + verbose = false, +}: Options): Plugin { return { name, setup(build) { - const compile = getCompiler(macros); + const compile = getCompiler(macros, verbose); build.onLoad({ filter: /.*/ }, async (args) => { const source = await fs.promises.readFile(args.path, "utf8"); // Replace the calculate function calls with 42 diff --git a/src/rollup.ts b/src/rollup.ts index a501ac8..4c95da5 100644 --- a/src/rollup.ts +++ b/src/rollup.ts @@ -3,8 +3,11 @@ import { Plugin } from "rollup"; import { getCompiler } from "./utils"; import { Options } from "./types"; -export default function inlineFunction({ macros = {} }: Options): Plugin { - const compile = getCompiler(macros); +export default function inlineFunction({ + macros = {}, + verbose = false, +}: Options): Plugin { + const compile = getCompiler(macros, verbose); return { name, transform(code) { diff --git a/src/types.ts b/src/types.ts index f35269b..af67211 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,4 +2,5 @@ export type Macros = (...args: unknown[]) => string; export type MacrosMap = Record string>; export interface Options { macros: MacrosMap; + verbose?: boolean; } diff --git a/src/utils.ts b/src/utils.ts index 076d0b9..513dd01 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,13 +2,20 @@ import { MacrosMap } from "./types"; const CALLS_RE = /^( *)(\w+)\((.+)\);/gm; const replaceMacros = - (macros: MacrosMap) => (_, indent: string, id: string, args: string) => { - return macros[id](...args.split(/, +/)) + (macros: MacrosMap, verbose: boolean) => + (_, indent: string, id: string, args: string) => { + const selectedMacros = macros[id]; + if (!selectedMacros) return _; + const replacement = selectedMacros(...args.split(/, +/)) .split("\n") .filter((str) => str.match(/\S/)) .map((str) => indent + str.trim()) .join("\n"); + if (verbose) + console.log(`\n${id}(${args}):\n====\n${replacement}\n=====\n`); + return replacement; }; -export const getCompiler = (macros: MacrosMap) => (src: string) => - src.replace(CALLS_RE, replaceMacros(macros)); +export const getCompiler = + (macros: MacrosMap, verbose: boolean) => (src: string) => + src.replace(CALLS_RE, replaceMacros(macros, verbose)); diff --git a/src/vite.ts b/src/vite.ts index ccf5aef..4ab513f 100644 --- a/src/vite.ts +++ b/src/vite.ts @@ -3,8 +3,11 @@ import { transformWithEsbuild, Plugin } from "vite"; import { Options } from "./types"; import { getCompiler } from "./utils"; -export default function inlineFunction({ macros = {} }: Options): Plugin { - const compile = getCompiler(macros); +export default function inlineFunction({ + macros = {}, + verbose = false, +}: Options): Plugin { + const compile = getCompiler(macros, verbose); return { name, enforce: "pre", diff --git a/test/__snapshots__/index.test.ts.snap b/test/__snapshots__/index.test.ts.snap index 3032757..fa3ebc4 100644 --- a/test/__snapshots__/index.test.ts.snap +++ b/test/__snapshots__/index.test.ts.snap @@ -1,30 +1,80 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`plugins > esbuild 1`] = ` -"(() => { - // test/utils.ts - var fn2 = (a, b) => a + b; +"// test/utils.ts +function add(u, v) { + u[0] = u[0] + v[0]; + u[1] = u[1] + v[1]; +} +var fn2 = (a, b) => a + b; - // test/test.ts - var foo = [4, 5]; - var bar = [5, fn2(6, 12)]; - var ZERO = () => [0, 0]; - var baz = [33, 22]; - var _a0 = baz; - var _b1 = ZERO(); - _a0[0] = _a0[0] + _b1[0]; - _a0[1] = _a0[1] + _b1[1]; - console.log(foo, baz); - var _a2 = ZERO(); - var _b3 = bar; - _a2[0] = _a2[0] + _b3[0]; - _a2[1] = _a2[1] + _b3[1]; -})(); +// test/test.ts +var foo = [4, 5]; +var bar = [5, fn2(6, 12)]; +var ZERO = () => [0, 0]; +var baz = [33, 22]; +var _a0 = baz; +var _b1 = ZERO(); +_a0[0] = _a0[0] + _b1[0]; +_a0[1] = _a0[1] + _b1[1]; +console.log(foo, baz); +var _a2 = ZERO(); +var _b3 = bar; +_a2[0] = _a2[0] + _b3[0]; +_a2[1] = _a2[1] + _b3[1]; +var crossProduct = (u, v, dest) => u[0] * v[1] - u[1] * v[0]; +var crossProduct2 = crossProduct; +var add2 = add; +function inlined() { + const foo2 = [4, 5]; + const bar2 = [5, fn2(6, 12)]; + const baz2 = [33, 22]; + for (let i = 0; i < 100; i++) { + const _a4 = foo2; + const _b5 = bar2; + _a4[0] = _a4[0] + _b5[0]; + _a4[1] = _a4[1] + _b5[1]; + const _a6 = baz2; + const _b7 = bar2; + _a6[0] = _a6[0] + _b7[0]; + _a6[1] = _a6[1] + _b7[1]; + const _a8 = foo2; + const _b9 = baz2; + _a8[0] = _a8[0] + _b9[0]; + _a8[1] = _a8[1] + _b9[1]; + const _a10 = foo2; + const _b11 = bar2; + const _d12 = baz2; + _d12[0] = _a10[0] * _b11[0]; + _d12[1] = _a10[1] * _b11[1]; + } + return foo2; +} +function notInlined() { + const foo2 = [4, 5]; + const bar2 = [5, fn2(6, 12)]; + const baz2 = [33, 22]; + for (let i = 0; i < 100; i++) { + add2(foo2, bar2); + add2(baz2, bar2); + add2(foo2, baz2); + crossProduct2(foo2, bar2, baz2); + } + return foo2; +} +export { + inlined, + notInlined +}; " `; exports[`plugins > rollup 1`] = ` -"'use strict'; +"function add(u, v) { + u[0] = u[0] + v[0]; + u[1] = u[1] + v[1]; +} +var fn2 = function (a, b) { return a + b; }; var foo = [4, 5]; var ZERO = function () { return [0, 0]; }; @@ -37,11 +87,60 @@ _a0[0] = _a0[0] + _b1[0]; _a0[1] = _a0[1] + _b1[1]; // so that dead code removal doesn't remove the function altogether console.log(foo, baz); +var crossProduct = function (u, v, dest) { + return u[0] * v[1] - u[1] * v[0]; +}; +var crossProduct2 = crossProduct; +var add2 = add; +function inlined() { + var foo = [4, 5]; + var bar = [5, fn2(6, 12)]; + var baz = [33, 22]; + for (var i = 0; i < 100; i++) { + const _a4 = foo; + const _b5 = bar; + _a4[0] = _a4[0] + _b5[0]; + _a4[1] = _a4[1] + _b5[1]; + const _a6 = baz; + const _b7 = bar; + _a6[0] = _a6[0] + _b7[0]; + _a6[1] = _a6[1] + _b7[1]; + const _a8 = foo; + const _b9 = baz; + _a8[0] = _a8[0] + _b9[0]; + _a8[1] = _a8[1] + _b9[1]; + const _a10 = foo; + const _b11 = bar; + const _d12 = baz; + _d12[0] = _a10[0] * _b11[0]; + _d12[1] = _a10[1] * _b11[1]; + } + return foo; +} +function notInlined() { + var foo = [4, 5]; + var bar = [5, fn2(6, 12)]; + var baz = [33, 22]; + for (var i = 0; i < 100; i++) { + add2(foo, bar); + add2(baz, bar); + add2(foo, baz); + crossProduct2(foo, bar); + } + return foo; +} + +export { inlined, notInlined }; " `; exports[`plugins > vite 1`] = ` -"const foo = [4, 5]; +"function add(u, v) { + u[0] = u[0] + v[0]; + u[1] = u[1] + v[1]; +} +const fn2 = (a, b) => a + b; +const foo = [4, 5]; const ZERO = () => [0, 0]; const baz = [33, 22]; const _a0 = baz; @@ -49,5 +148,49 @@ const _b1 = ZERO(); _a0[0] = _a0[0] + _b1[0]; _a0[1] = _a0[1] + _b1[1]; console.log(foo, baz); +const crossProduct = (u, v, dest) => u[0] * v[1] - u[1] * v[0]; +const crossProduct2 = crossProduct; +const add2 = add; +function inlined() { + const foo2 = [4, 5]; + const bar2 = [5, fn2(6, 12)]; + const baz2 = [33, 22]; + for (let i = 0; i < 100; i++) { + const _a4 = foo2; + const _b5 = bar2; + _a4[0] = _a4[0] + _b5[0]; + _a4[1] = _a4[1] + _b5[1]; + const _a6 = baz2; + const _b7 = bar2; + _a6[0] = _a6[0] + _b7[0]; + _a6[1] = _a6[1] + _b7[1]; + const _a8 = foo2; + const _b9 = baz2; + _a8[0] = _a8[0] + _b9[0]; + _a8[1] = _a8[1] + _b9[1]; + const _a10 = foo2; + const _b11 = bar2; + const _d12 = baz2; + _d12[0] = _a10[0] * _b11[0]; + _d12[1] = _a10[1] * _b11[1]; + } + return foo2; +} +function notInlined() { + const foo2 = [4, 5]; + const bar2 = [5, fn2(6, 12)]; + const baz2 = [33, 22]; + for (let i = 0; i < 100; i++) { + add2(foo2, bar2); + add2(baz2, bar2); + add2(foo2, baz2); + crossProduct2(foo2, bar2); + } + return foo2; +} +export { + inlined, + notInlined +}; " `; diff --git a/test/benchmark.js b/test/benchmark.js new file mode 100644 index 0000000..9f79cd5 --- /dev/null +++ b/test/benchmark.js @@ -0,0 +1,10 @@ +import bench from "benny"; +import { inlined, notInlined } from "./dist/esbuild.js"; + +bench.suite( + "My suite", + bench.add("Inlined", inlined), + bench.add("Not inlined", notInlined), + bench.cycle(), + bench.complete() +); diff --git a/test/esbuild.js b/test/esbuild.js index ae55d0e..5cb7ee6 100644 --- a/test/esbuild.js +++ b/test/esbuild.js @@ -1,25 +1,13 @@ import esbuild from "esbuild"; import inlineFunction from "../dist/esbuild.js"; - -let counter = 0; -const macros = { - add: (a, b) => { - const _a = `_a${counter++}`; - const _b = `_b${counter++}`; - return ` - const ${_a} = ${a}; - const ${_b} = ${b}; - ${_a}[0] = ${_a}[0] + ${_b}[0]; - ${_a}[1] = ${_a}[1] + ${_b}[1]; - `; - }, -}; +import { macros } from "./macros.js"; esbuild .build({ entryPoints: ["./test/test.ts"], bundle: true, + format: "esm", outfile: "./test/dist/esbuild.js", - plugins: [inlineFunction({ macros })], + plugins: [inlineFunction({ macros, verbose: false })], }) .catch(() => process.exit(1)); diff --git a/test/macros.js b/test/macros.js new file mode 100644 index 0000000..e0fc089 --- /dev/null +++ b/test/macros.js @@ -0,0 +1,25 @@ +let counter = 0; +export const macros = { + add: (a, b) => { + const _a = `_a${counter++}`; + const _b = `_b${counter++}`; + return ` + const ${_a} = ${a}; + const ${_b} = ${b}; + ${_a}[0] = ${_a}[0] + ${_b}[0]; + ${_a}[1] = ${_a}[1] + ${_b}[1]; + `; + }, + crossProduct: (a, b, d) => { + const _a = `_a${counter++}`; + const _b = `_b${counter++}`; + const _d = `_d${counter++}`; + return ` + const ${_a} = ${a}; + const ${_b} = ${b}; + const ${_d} = ${d}; + ${_d}[0] = ${_a}[0] * ${_b}[0]; + ${_d}[1] = ${_a}[1] * ${_b}[1]; + `; + }, +}; diff --git a/test/rollup.config.ts b/test/rollup.config.ts index 3fae597..8f4ace7 100644 --- a/test/rollup.config.ts +++ b/test/rollup.config.ts @@ -1,28 +1,14 @@ import { RollupOptions } from "rollup"; import typescript from "@rollup/plugin-typescript"; import inlineFunction from "../dist/rollup"; - -let counter = 0; -const macros = { - x: (a, b) => a + b, - add: (a, b) => { - const _a = `_a${counter++}`; - const _b = `_b${counter++}`; - return ` - const ${_a} = ${a}; - const ${_b} = ${b}; - ${_a}[0] = ${_a}[0] + ${_b}[0]; - ${_a}[1] = ${_a}[1] + ${_b}[1]; - `; - }, -}; +import { macros } from "./macros"; const config: RollupOptions = { input: "./test/test.ts", output: { file: "./test/dist/rollup.js", - name: "rollup", - format: "cjs", + name: "inlineFunction", + format: "esm", exports: "named", }, plugins: [typescript(), inlineFunction({ macros })], diff --git a/test/test.ts b/test/test.ts index 5d969bc..0d30735 100644 --- a/test/test.ts +++ b/test/test.ts @@ -15,3 +15,38 @@ console.log(foo, baz); // this will work, but will be removed as dead code add(ZERO(), bar); + +const crossProduct = (u: Vec2, v: Vec2, dest: Vec2): number => + u[0] * v[1] - u[1] * v[0]; +const crossProduct2 = crossProduct; + +const add2 = add; +export function inlined() { + const foo: Vec2 = [4, 5]; + const bar: Vec2 = [5, fn2(6, 12)]; + const baz: Vec2 = [33, 22]; + + for (let i = 0; i < 100; i++) { + add(foo, bar); + add(baz, bar); + add(foo, baz); + crossProduct(foo, bar, baz); + } + + return foo; +} + +export function notInlined() { + const foo: Vec2 = [4, 5]; + const bar: Vec2 = [5, fn2(6, 12)]; + const baz: Vec2 = [33, 22]; + + for (let i = 0; i < 100; i++) { + add2(foo, bar); + add2(baz, bar); + add2(foo, baz); + crossProduct2(foo, bar, baz); + } + + return foo; +} diff --git a/test/vite.config.ts b/test/vite.config.ts index 34622c2..d861017 100644 --- a/test/vite.config.ts +++ b/test/vite.config.ts @@ -1,21 +1,7 @@ import { defineConfig } from "vite"; import inlineFunction from "../dist/vite"; import { resolve } from "path"; - -let counter = 0; -const macros = { - x: (a, b) => a + b, - add: (a, b) => { - const _a = `_a${counter++}`; - const _b = `_b${counter++}`; - return ` - const ${_a} = ${a}; - const ${_b} = ${b}; - ${_a}[0] = ${_a}[0] + ${_b}[0]; - ${_a}[1] = ${_a}[1] + ${_b}[1]; - `; - }, -}; +import { macros } from "./macros"; export default defineConfig({ build: { diff --git a/vite.config.ts b/vite.config.ts index da58d44..5f8e105 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,6 +6,7 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ build: { + minify: false, lib: { entry: [ "./src/esbuild.ts",