{"_id":"showify","_rev":"16-64fe499849a23d120a922171726a48ec","name":"showify","dist-tags":{"latest":"0.2.8"},"versions":{"0.1.1":{"name":"showify","version":"0.1.1","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.1.1","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"bb4c5f310afddae0373a72cae24636f10291227d","tarball":"https://registry.npmjs.org/showify/-/showify-0.1.1.tgz","fileCount":7,"integrity":"sha512-9w3Dyph8wem90jPRT4CXoiuySYpcU6X9CvNm9goq90xe0nr+r+lBUkgMNeP0uO8sydmTFDTEDTG4dH9NkKwokw==","signatures":[{"sig":"MEYCIQDARVskWw82DE5cCL+m0GSUKW/Dvwj07faI94H+LbVZRAIhALscMUTaJnPEDl/tdDyEroy88kTsCAIaERuqTREWkw2x","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":193483},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"9eb0344e1b6e75e4907a46f721fd0bd88466a7d4","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.1.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"23.8.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.1.1_1740067555583_0.010895704925987904","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"showify","version":"0.1.2","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.1.2","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"5eae9f88576dd0b43681a5c8b23d0011a1668f1d","tarball":"https://registry.npmjs.org/showify/-/showify-0.1.2.tgz","fileCount":7,"integrity":"sha512-zACTOkzszFtMPsJpFIP+ocovalp50Lj+21QcSccO5ZxA+ru2zo2HdUSVwCcZc38SWDKMsKU7j9D+ZDBJTQ1Oww==","signatures":[{"sig":"MEYCIQDNNqCP94UToWnL4TOSWm2lul0wsXaw/72pX/wdFPuWSAIhANGqkO4Rf4a7F3tzDDHoHXeJRQ9O5q+JOAMg21Sb5wFS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":197782},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"7759b8778d54f686c85eba4d88b2dac2afdbcdd6","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.1.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"23.8.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.1.2_1740306396434_0.12357392214825569","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"showify","version":"0.1.3","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.1.3","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"2570ff707768ad7795ea028830a16545a640ca9a","tarball":"https://registry.npmjs.org/showify/-/showify-0.1.3.tgz","fileCount":7,"integrity":"sha512-YLXhZVX+clP7Qz5SfMCrpT5XTHQzZjJfYeYSODsqlhfYTCaA2EP8d5WdcdzdRsgbnYYoqZjFubc4nNti2p3oGQ==","signatures":[{"sig":"MEQCIE40L/dCOwL+0b66EsOtvMFFv/t/CIwYgh+0XqzK2m/pAiBfVDHJUblzzvcl2lzM/z2mUd8Tbg5KGWhmBDlCAC4KGw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200493},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"637f1fcc9c7a01a4231ed321f9a4ecb952224d1f","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.2.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"23.8.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.1.3_1743005968392_0.30212939274480544","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"showify","version":"0.1.4","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.1.4","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"78a0fb62b13a92d47ee2c9d69f83cf5488a856b8","tarball":"https://registry.npmjs.org/showify/-/showify-0.1.4.tgz","fileCount":7,"integrity":"sha512-1pgpg5k47Cp9WQrjF/cH8hLgeVR9LsUO0Hi0vYAy/6jCWfcJBQonFuK2vzEBg4AOqm0HxFLC6I2dORGjdAlySQ==","signatures":[{"sig":"MEUCIQCLpSVuN2nBaWBGufBt2uaOgrWwLLKtMRNEErB69rX25wIgUJdRwZzN2cNqnB03Z6JjsWT6Ph1OmV8DCT7Cfg7+Oxc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":219774},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"82c57fbcea1ca630b77e8c37329ca37a19098945","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.2.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"23.10.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.1.4_1743195208428_0.07769952959689186","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"showify","version":"0.1.5","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.1.5","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"b15fd15f6a70cf47e0c3167b31fef967594c9c90","tarball":"https://registry.npmjs.org/showify/-/showify-0.1.5.tgz","fileCount":7,"integrity":"sha512-LvenlhWhjOOggTIWf/y51qiLN2IU8h0dYTn7lOs/+6HpfRosbU29CT05BJTRTaoJJuZBOfV040F4yGK5hHVUng==","signatures":[{"sig":"MEYCIQDeGUM63GHZtJu+ij7ACcf/BtOzDsyZgLTHW2fGkHJP8gIhAOlhCQYW4gNeovysCujV7uOMu6YoiRYGlIl2nM2TXPx2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208486},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"58db38493c6426a9209a3f053c5d8c841ecadb39","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.2.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"23.10.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.1.5_1743311672831_0.37838407822072595","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"showify","version":"0.2.0","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.0","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"63d0e979abd643292a712d161beee2b2982f2fee","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.0.tgz","fileCount":7,"integrity":"sha512-P6HOWR6js338m1LXfYyQXBGZ/t+yhP2J4rWI4tF6ZnHynS2clEao6KayJA3KDxq2dae67QTBkLIF0xbNZp3aOQ==","signatures":[{"sig":"MEQCICmEliqf0sHaOAUg8/gmLcCKvzNfnXSP7zHc+M9cDN3qAiB33AjcNCNLdpAinzgmCVZod1zD2meeHuyFsMcLjyymcg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208747},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"f9c4e55318dd1147aaf4ba43b83dc97476d276b7","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.3.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"24.0.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.0_1747323087721_0.23845431652790672","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"showify","version":"0.2.1","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.1","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"f4fbc697cf6c3a5a9e1affb5170052db6417383e","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.1.tgz","fileCount":7,"integrity":"sha512-nt8G8KtuPankI0tCwWH7qEXdhViP36uSfNeGH1RkncOFGny99ZjwKpUH13/60vJwj/sWI3BYfnYVKcXKZaOCFQ==","signatures":[{"sig":"MEYCIQCByGs0T9pbpG+5Tpgj3MMD396ZF0SiZBxeqUNuuTbiDgIhAJnYjw/LAU7GJmEytBycE1CPsXE8pA3G7Wy7f2FMvG8G","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":212154},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"c20ad2bff2473fee9462ba2cbf1ccd275bf82507","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.3.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"24.0.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.1_1747329106456_0.10599548377160972","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"showify","version":"0.2.2","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.2","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"6b24df230b16dc5f47391bf3abde84347da8be62","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.2.tgz","fileCount":7,"integrity":"sha512-fQu/Dp8a1Wkv79z8tKRW61HH50pO8nbqvPo8Z1gcE9nQ89iNiGZkT7K5rkD8HQF7USScLT9Db2SP3G7N9Bg3vA==","signatures":[{"sig":"MEUCIQDh8bf/MA2bVJB2UCY69lZBQg4ylBtOaV0bvlIYHXppNQIgM4X+pfrRVbNW6ugVTopji5QPYit82pqMRofN8FzTUa0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":213004},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"c7797952482c4f71139e9979176ae989299a5aee","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.5.2","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"24.8.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.2_1758565655305_0.15989342794592565","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"showify","version":"0.2.3","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.3","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"d4aef4a217278daafc7064a250514b9dbae1a326","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.3.tgz","fileCount":7,"integrity":"sha512-ESBFX1g/DYd4LHTP+c+FTA2MPrsIonH8vU5VS14Ath6XfeV2pco9kksSkRe7ybsa9tzsN79FALoDP5nIr6D4yA==","signatures":[{"sig":"MEUCIQDxkiIO+ekcYitqJ03yxsfVHdV6zqKoFOglaodeJx9CkwIgT6ja0CID3/lJFmsMOPGv75TblYshy5aGWU/A3YOtpV4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":214773},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"18730e1e215401029cdfaef89bd593e10a835965","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.6.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"24.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.3_1760936936180_0.8468412670604897","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"showify","version":"0.2.4","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.4","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"43adac1b2fbc9dbe3420c50af1ed8db968869c8b","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.4.tgz","fileCount":7,"integrity":"sha512-kfx+fZMRR0SBj91TwOYNiUJDBGnvkKoRRKMZDs+4Cma85HshT2RyByELb/YGZ5E1lU5x+nPcwnyikeHdOWn80A==","signatures":[{"sig":"MEUCIBr+LQXbUW55z5KzCeUORlvXRJKCk6Fq6KO1jxcIh6i4AiEA+ifP8Fq35CydPh5zlnhDGsAarFgnBPrXAENImbCpiqk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":226113},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"7a9163eac49a7c9a0fe1eb354398b9434c8d0d94","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.6.0","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"25.1.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.4_1761888911961_0.283167935577491","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"showify","version":"0.2.5","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.5","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"26e0ff8a135b3af7920539b436d4acae6688d01d","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.5.tgz","fileCount":7,"integrity":"sha512-vpLc8eXBUlHgzwQiaNYDCel/qfVsSo0ALHcal/Mtd4gt/8n3dtUh+X1NgV2ekT2DPV8Y9yZ2+KjcihUuOb7aQQ==","signatures":[{"sig":"MEUCIBz4/QbNFSfgJWT6AQJ1fIPsYAwMmt0etOALz78UMSQ0AiEA+LRWUZ1jtKXQpkaFYyxIJRRKw6GkrKzPACzNEXzEvWc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":245179},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"78ac31791eef78fb943fa82f3cb9b2aea7859d95","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.6.2","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"25.1.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.5_1762058651377_0.3555243862025903","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"name":"showify","version":"0.2.6","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.6","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"4053d3aa3d8b5124234e5ea41549c89edbcad006","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.6.tgz","fileCount":7,"integrity":"sha512-prg8VgJmUgBm2l3HW0Fh53jpAgngZjAg4hFsqSzvzaTq4SHJEULwwJpM+XO4V2QWKNamjEn9kyMkt+iF4Rvksw==","signatures":[{"sig":"MEYCIQDLy2UrWMqphTS4p9njj6+jTm2ASn+6DCGw6nt4bKPnAAIhAOynuaOwdd2/VMeaW0zt5kEOh+cJjK4SP1E56GOnazB0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":245433},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"7bb9133ab29591a475b40625ac8815855bbc605b","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.6.2","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"25.1.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.6_1762228730027_0.9587374205902726","host":"s3://npm-registry-packages-npm-production"}},"0.2.7":{"name":"showify","version":"0.2.7","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"author":{"url":"Snowflyt","name":"Ge Gao","email":"gaoge011022@gmail.com"},"license":"MPL-2.0","_id":"showify@0.2.7","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"dist":{"shasum":"f201100866c6ace9166b0ffd116087f95c29e5b9","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.7.tgz","fileCount":7,"integrity":"sha512-azmzfwOKnYeLrJCn7pgwrgZfz9NvG2cF4/RFQw1qv3I8kNxzvNDnZ2znhQM70krFw+qAm4IijaTrVER1KC/R+g==","signatures":[{"sig":"MEUCIQDDNw0SaqU/a41gOk0vYOH+ITWLFedywwwql4h5wyIxHAIgIv8PEZariNrUHK/t7kyIatVAmjw9jrsfg33rUu59Ko4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":246116},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","gitHead":"6aa166a99502ec4ec1ccd44b47b5406ca95992fd","_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"overrides":{"typescript-eslint":{"typescript":"$typescript"}},"repository":{"url":"git+https://github.com/Snowflyt/showify.git","type":"git"},"_npmVersion":"11.6.2","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/showify_0.2.7_1774684505863_0.025447166439381164","host":"s3://npm-registry-packages-npm-production"}},"0.2.8":{"name":"showify","version":"0.2.8","description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"homepage":"https://github.com/Snowflyt/showify","bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"repository":{"type":"git","url":"git+https://github.com/Snowflyt/showify.git"},"license":"MPL-2.0","author":{"name":"Ge Gao","email":"gaoge011022@gmail.com","url":"Snowflyt"},"sideEffects":false,"type":"module","main":"./index.js","module":"./index.js","types":"./index.d.ts","gitHead":"9a455119e0735ec2fc2a2de8ea14bb925fd52c38","_id":"showify@0.2.8","_nodeVersion":"25.8.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-CDFzD6ORbdkPOF8at/mv57ZQb2wa9iaC48R97uF6k1yJE7sfbsvEmuIb94FZ5x4UlfGSqmVgii+RcUJh3bsXKw==","shasum":"905f218e78d5611e27e191fba77cba89ae551f3a","tarball":"https://registry.npmjs.org/showify/-/showify-0.2.8.tgz","fileCount":7,"unpackedSize":247842,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID9xl1A5PPkfoOiBom86LftrV8EmYx8VL92Ue2MCS2Q/AiEAs7ujPFc82v191VS+VgKm3rRnOmEnClhhKMdfXCn9PO4="}]},"_npmUser":{"name":"snowflyt","email":"gaoge011022@163.com"},"directories":{},"maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/showify_0.2.8_1775313504450_0.946679756345036"},"_hasShrinkwrap":false}},"time":{"created":"2025-02-20T15:31:26.587Z","modified":"2026-04-04T14:38:24.747Z","0.1.0":"2025-02-20T15:31:26.769Z","0.1.1":"2025-02-20T16:05:55.839Z","0.1.2":"2025-02-23T10:26:36.606Z","0.1.3":"2025-03-26T16:19:28.787Z","0.1.4":"2025-03-28T20:53:28.678Z","0.1.5":"2025-03-30T05:14:33.029Z","0.2.0":"2025-05-15T15:31:27.912Z","0.2.1":"2025-05-15T17:11:46.643Z","0.2.2":"2025-09-22T18:27:35.498Z","0.2.3":"2025-10-20T05:08:56.388Z","0.2.4":"2025-10-31T05:35:12.169Z","0.2.5":"2025-11-02T04:44:11.630Z","0.2.6":"2025-11-04T03:58:50.230Z","0.2.7":"2026-03-28T07:55:06.031Z","0.2.8":"2026-04-04T14:38:24.625Z"},"bugs":{"url":"https://github.com/Snowflyt/showify/issues"},"author":{"name":"Ge Gao","email":"gaoge011022@gmail.com","url":"Snowflyt"},"license":"MPL-2.0","homepage":"https://github.com/Snowflyt/showify","keywords":["string","stringify","text","format","formatting","human-readable","pretty","pretty-print","log","logging","color","colour","colors","terminal","console","tty","shell","command-line"],"repository":{"type":"git","url":"git+https://github.com/Snowflyt/showify.git"},"description":"Arguably the most comprehensive library for stringifying any JavaScript value into a human-readable format, handling nearly every scenario you might encounter.","maintainers":[{"name":"snowflyt","email":"gaoge011022@163.com"}],"readme":"<h1 align=\"center\">showify</h1>\n\n<p align=\"center\">\n  Arguably the <strong><i>most comprehensive</i></strong> cross-platform library for <strong>stringifying</strong> <i>any</i> JavaScript value into a human-readable format, handling nearly every scenario you might encounter.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/showify\">\n    <img src=\"https://img.shields.io/npm/dm/showify.svg\" alt=\"downloads\" height=\"18\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/showify\">\n    <img src=\"https://img.shields.io/npm/v/showify.svg\" alt=\"npm version\" height=\"18\">\n  </a>\n  <a href=\"https://bundlephobia.com/package/showify\">\n    <img src=\"https://img.shields.io/bundlephobia/minzip/showify.svg\" alt=\"minzipped size\" height=\"18\">\n  </a>\n  <a href=\"https://coveralls.io/github/Snowflyt/showify?branch=main\">\n    <img src=\"https://coveralls.io/repos/github/Snowflyt/showify/badge.svg?branch=main\" alt=\"coverage status\" height=\"18\">\n  </a>\n  <a href=\"https://github.com/Snowflyt/showify\">\n    <img src=\"https://img.shields.io/npm/l/showify.svg\" alt=\"MPL 2.0 license\" height=\"18\">\n  </a>\n</p>\n\n![screenshot](./screenshot.png)\n\n## Features\n\n- **Stringify** _any_ JavaScript value in a format similar to `util.inspect` in Node.js. Special cases like Map, Set, array empty slots, wrapper objects for primitives, ArrayBuffer, DataView, WeakMap, WeakSet, and more are handled properly.\n- Support for maximum recursion **depth** in nested objects.\n- **Circular references** displayed with a **reference pointer** (e.g., `<ref *1> { foo: { bar: [Circular *1] } }`) instead of just `[Circular]`.\n- Auto **indentation** and **line breaking** for long outputs, just like `console.log`/`util.inspect` in Node.js and Deno.\n- **ANSI color** support.\n- Highly customizable options for indentation, quote style, hidden properties, colors, and more.\n- **Custom serializers** for your own types, with a user-friendly API that works on a tree-like structure instead of raw strings, handling maximum recursion depth, indentation, and circular references automatically — without any extra effort.\n\n## Quickstart\n\nSimply import the `show` function and use it to stringify _any_ JavaScript value:\n\n```javascript\nimport { show } from \"showify\";\n\nconst value = {\n  foo: \"bar\",\n  \"Hello\\nworld\": [-0, 2n, NaN],\n  [Symbol(\"qux\")]: { quux: \"corge\" },\n  map: new Map([\n    [\"foo\", \"bar\"],\n    [{ bar: 42 }, \"qux\"],\n  ]),\n};\nvalue.circular = value;\n\nconsole.log(show(value, { indent: 2, trailingComma: \"auto\", colors: true }));\n// <ref *1> {\n//   foo: \"bar\",\n//   \"Hello\\nworld\": [-0, 2n, NaN],\n//   map: Map(2) { \"foo\" => \"bar\", { bar: 42 } => \"qux\" },\n//   circular: [Circular *1],\n//   Symbol(qux): { quux: \"corge\" },\n// }\n```\n\nThe `show()` function accepts an optional second argument for options. Some common options are listed here:\n\n- **`depth`**: Maximum recursion depth, defaults to `Infinity`.\n- **`indent`**: Number of spaces to indent, defaults to `0`. To enable indentation and auto line breaking, set `indent` to a positive integer, e.g., `2`.\n- **`breakLength`**: Maximum line length before breaking, defaults to `80`. This option is ignored if `indent` is `0`.\n- **`sorted`**: Whether to sort the keys of objects (including `Map`s and `Set`s) in the resulting string, defaults to `false`.\n- **`quoteStyle`**: Preferred quote style for strings, should be `\"single\"`, `\"double\"`, `\"backtick\"`, or an array of them to try in order, defaults to `[\"double\", \"single\", \"backtick\"]`.\n- **`trailComma`**: Whether to add a trailing comma to the last element of an array or object, should be `\"none\"`, `\"always\"` or `\"auto\"` (add trailing comma only when the last item is on a separate line), defaults to `\"none\"`.\n- **`colors`**: Enable ANSI colors, defaults to `false`.\n\n**showify** supports many other options. For a complete list of options, see [the available options section](#available-options) below.\n\nNote that **showify** uses slightly different default options compared to `util.inspect` in Node.js. If you want to achieve the exactly same default output as `util.inspect` in Node.js, see [the related FAQ](#how-can-i-achieve-the-exactly-default-output-as-utilinspect-in-nodejs).\n\n## Installation\n\nTo install **showify** via npm (or any other package manager you prefer):\n\n```shell\nnpm install showify\n```\n\nIf you prefer a lightweight version with a smaller bundle size, you may also consider [@showify/lite](https://github.com/Snowflyt/showify/tree/main/packages/lite), which removes ANSI color support and several other features that are not needed for most use cases.\n\n## Comparison\n\nHere’s a comparison of the features of **showify**, `util.inspect` in Node.js, and other libraries:\n\n- ✅ 1st-class, built-in, and ready to use with no additional configuration or code.\n- 🟡 Supported, but has limitations or is not as complete as **showify**.\n- 🔶 Supported and documented, but not out-of-the-box or requires extra user-code to implement.\n- ❌ Not officially supported or documented.\n\n| Feature                                    | showify                                                                                                                                                    | `util.inspect`    | pretty-format                                                                                                                                                          | object-inspect                                                                                                                                                           | stringify-object                                                                                                                                                             |\n| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Bundle size                                | <a href=\"https://bundlephobia.com/package/showify\"><img src=\"https://img.shields.io/bundlephobia/minzip/showify.svg\" alt=\"minzipped size\" height=\"18\"></a> | ❓                | <a href=\"https://bundlephobia.com/package/pretty-format\"><img src=\"https://img.shields.io/bundlephobia/minzip/pretty-format.svg\" alt=\"minzipped size\" height=\"18\"></a> | <a href=\"https://bundlephobia.com/package/object-inspect\"><img src=\"https://img.shields.io/bundlephobia/minzip/object-inspect.svg\" alt=\"minzipped size\" height=\"18\"></a> | <a href=\"https://bundlephobia.com/package/stringify-object\"><img src=\"https://img.shields.io/bundlephobia/minzip/stringify-object.svg\" alt=\"minzipped size\" height=\"18\"></a> |\n| Indentation                                | ✅                                                                                                                                                         | 🟡 uncustomizable | ✅                                                                                                                                                                     | ✅                                                                                                                                                                       | ✅                                                                                                                                                                           |\n| Auto line breaking                         | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Array elements grouping [1]                | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Circular references                        | ✅                                                                                                                                                         | ✅                | ✅                                                                                                                                                                     | ✅                                                                                                                                                                       | ✅                                                                                                                                                                           |\n| Circular reference pointers                | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Maximum recursion depth                    | ✅                                                                                                                                                         | ✅                | ✅                                                                                                                                                                     | ✅                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| ANSI colors                                | ✅                                                                                                                                                         | ✅                | 🔶                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Sorted keys                                | ✅                                                                                                                                                         | ✅                | ✅                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Auto select proper quote style for strings | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Custom quote style                         | ✅                                                                                                                                                         | ❌                | ❌                                                                                                                                                                     | 🟡 [2]                                                                                                                                                                   | 🟡 [2]                                                                                                                                                                       |\n| Auto line break for long multiline strings | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Trailing comma                             | ✅                                                                                                                                                         | ❌                | 🟡 forced                                                                                                                                                              | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Hidden (non-enumerable) properties         | ✅ [3]                                                                                                                                                     | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Proper getters/setters inspection [3]      | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| `Symbol.toStringTag` support               | ✅                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | 🟡                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Custom serializers                         | ✅                                                                                                                                                         | ✅                | ✅                                                                                                                                                                     | ✅                                                                                                                                                                       | ✅                                                                                                                                                                           |\n| Promise inspection                         | 🟡 [4]                                                                                                                                                     | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| WeakMap/WeakSet inspection                 | 🟡 [5]                                                                                                                                                     | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n| Proxy inspection                           | ❌                                                                                                                                                         | ✅                | ❌                                                                                                                                                                     | ❌                                                                                                                                                                       | ❌                                                                                                                                                                           |\n\n<p>\n  <div><small>[1]: Groups multiple short elements of an array onto the same line for better readability when placing the entire array on a single line would exceed the `breakLength`. This is particularly useful for arrays with many short elements, such as <code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</code>, which can be displayed as <code>[\\n  1,  2, 3, 4,\\n  5,  6, 7, 8,\\n  9, 10\\n]</code> instead of placing each element on a separate line.</small></div>\n  <div><small>[2]: object-inspect and stringify-object only supports single or double quotes, while <strong>showify</strong> supports automatic quote style.</small></div>\n  <div><small>[3]: In addition to <code>showHidden: boolean</code> from Node.js, <strong>showify</strong> also provides an <code>\"exclude-meta\"</code> option, which behaves like <code>true</code> but removes common meta properties like the <code>length</code> property of arrays from the output.</small></div>\n  <div><small>[4]: Whether to treat getters/setters specially. Getters may throw errors, so it’s important to account for such cases.</small></div>\n  <div><small>[5]: <code>Promise</code> objects are displayed as <code>Promise { &lt;state unknown&gt; }</code>, since it’s impossible to determine the state of a <code>Promise</code> without awaiting it.</small></div>\n  <div><small>[6]: <code>WeakMap</code> and <code>WeakSet</code> objects are displayed as <code>${className} { &lt;items unknown&gt; }</code> even when <code>showHidden</code> is <code>\"always\"</code>, since it’s impossible to retrieve the values of a <code>WeakMap</code> or <code>WeakSet</code> without knowing the keys.</small></div>\n</p>\n\nAside from the features listed above, **showify** also supports many more special cases than other libraries, such as wrapper objects for primitives (e.g., `new String(\"foo\")`), async/generator functions, ES6 classes, and more.\n\n## Documentation\n\n### Limitations\n\n- **Module:** Module detection may be misled by `Symbol.toStringTag`. If an object has a non-writable, non-enumerable, and non-configurable `Symbol.toStringTag` property set to `\"Module\"`, it will be considered a module.\n- **Promise:** `Promise` objects are displayed as `Promise { <state unknown> }`, since it’s impossible to determine the state of a `Promise` without awaiting it.\n- **Proxy:** `Proxy` objects are treated as regular objects, since it’ impossible to identify whether an object is a `Proxy` in vanilla JavaScript.\n- **WeakMap/WeakSet:** `WeakMap` and `WeakSet` objects are displayed as `${className} { <items unknown> }` even when `showHidden` is `\"always\"`, since it’s impossible to retrieve the values of a `WeakMap` or `WeakSet` without knowing the keys.\n\n### Known differences from `util.inspect` in Node.js\n\n- **Default options:** **showify** uses slightly different default options compared to `util.inspect` in Node.js. For example, **showify** uses infinite depth, prefers double quotes, and does not break lines by default, while `util.inspect` uses a depth of `2`, prefers single quotes, and breaks lines by default. See [the related FAQ](#how-can-i-achieve-the-exactly-default-output-as-utilinspect-in-nodejs) if you want to achieve the exact same default output as `util.inspect` in Node.js.\n- **Custom serialization:** **showify** supports custom serialization via both the special `Symbol(nodejs.util.inspect.custom)` property (compatible with Node.js) and through the `serializers` option in the `show` function or its own `Symbol(showify.inspect.custom)` property, while `util.inspect` only supports the former.\n- **Break length:** **showify** tries to break lines exactly at `breakLength` characters, while `util.inspect` may break lines at slightly different positions due to a different algorithm for calculating the break position.\n- **Circular reference pointer:** **showify** always displays a reference pointer when the same object is referenced, while `util.inspect` does not always do so if the same object is referenced multiple times.\n- **`Symbol.toStringTag`:** `util.inspect` shows `Symbol(Symbol.toStringTag): \"...\"` for some objects (like generators and generator functions) when `showHidden` is `true`, even if `Symbol.toStringTag` is not an own property of the object. **showify** does not show this in such cases.\n\n### A complete list of rules for stringifying JavaScript values\n\n**Common rules:**\n\n- **Maximum recursion depth:** Values are stringified up to the specified `depth` (defaults to `Infinity`). When stringifying a value, if the current depth exceeds the specified `depth`, **showify** checks if further recursion is necessary. If recursion is not needed, it simply stringifies the value as is. If further recursion is needed, **showify** displays `[${className}]` and stops further recursion. A special case occurs when the value’s `[[Prototype]]` is `null`, in which case the value is displayed as `[Object: null prototype]`.\n- **Break length:** Lines are wrapped at the `breakLength` (defaults to `80`) characters when possible. When stringifying a value, **showify** first attempts to use the inline format. If the inline format doesn’t exceed the `breakLength`, it switches to the multiline format. This process is repeated recursively for each child value. Specially for arrays, when the inline format would exceed the `breakLength`, **showify** tries to group multiple short elements onto the same line to reduce the number of lines, still respecting the limit. For example, an array like `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]` may be displayed as `[\\n  1,  2, 3, 4,\\n  5,  6, 7, 8,\\n  9, 10\\n]` instead of placing each element on a separate line. This grouping is conservative and is not applied if the array is too small to benefit from grouping or if it contains elements that are too long, which would cause uneven spacing.\n- **Circular references:** Objects with circular references are displayed with a reference pointer. For example, `<ref *1> { foo: [ [Circular *1] ], bar: <ref *2> { inner: [Circular *2], obj: [Circular *1] } }`.\n- **`.[Symbol.for(\"nodejs.util.inspect.custom\")]()`**: If `callNodeInspect` is `true`, **showify** calls `[Symbol.for(\"nodejs.util.inspect.custom\")]()` on the value before stringifying it (if available). This option takes precedence over `callToJSON`.\n- **`.[Symbol.for(\"showify.inspect.custom\")]()`**: If `callCustomInspect` is `true`, **showify** calls `[Symbol.for(\"nodejs.inspect.custom\")]()` on the value before stringifying it (if available). This option takes precedence over `callToJSON` and `callNodeInspect`.\n- **`.toJSON()`**: If `callToJSON` is `true`, **showify** calls `toJSON()` on the value before stringifying it (if available).\n- **Extra keys:** Extra keys of any special object (e.g., wrapper objects for primitives, errors, promises, functions, arrays) are displayed. For example, `[Function: foo] { bar: \"baz\" }` or `[1, 2, 3, foo: \"bar\"]`.\n- **Class name:** An object’s `${className}` is defined as the first non‑empty `.constructor.name` found while walking up the prototype chain, or `\"Object\"` if none is found. For cross‑realm and Proxy objects, we only accept a name when the own `constructor` is a function and `value instanceof constructor` is `true`.\n- **`Symbol.toStringTag`:** If an object has a `Symbol.toStringTag` property that is not already shown and its `${className}` does not end with the value of `Symbol.toStringTag`, it is displayed as the following:\n  - For `Date`s and `RegExp`s, it is displayed with brackets around after the class name, e.g., `Date [MyTag] 2025-02-13T11:42:41.196Z` or `MyRegExp [MyTag] /(?:)/ { foo: 'bar' }`.\n  - For `Error`s, it is displayed with brackets around after the error name, e.g., `Error [MyTag]: error message\\n    at ...` or `[TypeError [MyTag]: error message]`.\n  - For ES6 classes, it is displayed with brackets around after the class name, e.g., `[class MyClass [MyTag]]` or `[class MyClass [MyTag] extends MySuperClass]`.\n  - For other objects, the tag is displayed with brackets around after its original prefix (if it does not have a prefix, the prefix is defined as `${className}`), e.g., `Object [MyTag] { foo: \"bar\" }`or`[String: \"foo\"] [MyTag]`.\n\n**Primitive values:**\n\n- **Undefined:** `undefined` is displayed as `undefined`. Gray if `colors` is `true`.\n- **Null:** `null` is displayed as `null`. Bold if `colors` is `true`.\n- **Boolean:** `true` and `false` are displayed as `true` and `false`, respectively. Yellow if `colors` is `true`.\n- **Number:** Numbers are displayed as their literal values, e.g., `42`. Yellow if `colors` is `true`.\n- **BigInt:** BigInts are displayed as their literal values with **n** suffix, e.g., `42n`. Yellow if `colors` is `true`.\n- **String:** Strings are displayed as their literal values with quotes based on the `quoteStyle` option, e.g., `\"foo\"`. Green if `colors` is `true`. When backticks are a candidate, showify avoids using backticks if the string contains the sequence `${` to prevent it from looking like a template literal. In that case, the next available quote style in your preference order is chosen.\n- **Multi-line strings:** Multi-line strings are broken into `\"${s1}\\n\" + \"${s2}\\n\" + ...` if its indentation plus the length of the string exceeds `breakLength`. Each part is colorized separately if `colors` is `true`, and `+`s are not colorized.\n- **Long strings:** If `maxStringLength` is set and the string is longer than `maxStringLength`, it is displayed as `\"${s}\"... ${n} more character${n === 1 ? \"\" : \"s\"}`, e.g., `\"foo bar\"... 3 more characters`. This also applies to multi-line strings, e.g., `\"foo\\n\" + \"bar\"... 1 more character\"`.\n- **Symbol:** Symbols are displayed as their literal values, e.g., `Symbol(foo)`. Green if `colors` is `true`.\n- **Wrapper objects for primitives:** Wrapped primitive values are displayed as `[${Type}: ${value}]`, e.g., `[String: \"foo\"]`. Their colors are the same as their primitive values if `colors` is `true`. If a wrapped primitive’s `${className}` is not equal to its `${Type}`, it is displayed as `[${Type} (${className}): ${value}]`, e.g., `[String (MyString): \"foo\"]`.\n\n**Special objects:**\n\n- **Date:** `Date` objects are displayed as `date.toISOString()`. If `${className}` is not `\"Date\"`, it is displayed as `${className} ${date.toISOString()}`.\n- **RegExp:** `RegExp` objects are displayed as `re.toString()`. If `${className}` is not `\"RegExp\"`, it is displayed as `${className} ${re.toString()}`. When `colors` is `true`, the RegExp is syntax highlighted with a highlighter adapted from [Node.js’s implementation of `util.inspect`](https://github.com/nodejs/node/blob/dec0213c834607e7721ee250d8c46ef9cd112efe/lib/internal/util/inspect.js#L526-L768) that follows the ECMAScript grammar (groups, assertions, escapes, character classes, quantifiers, etc.). You can customize this via `styles.regexp`.\n- **Error:** `Error` objects are displayed as `error.stack` if available and valid, or `[${error.stack}]` if `error.stack` is available but invalid, or `[${className}: ${error.message}]` if message is available, or `[${className}]` otherwise.\n- **Promise:** `Promise` objects are displayed as `Promise { <state unknown> }`.\n- **ArrayBuffer:** `[Uint8Contents]` and `byteLength` are displayed for `ArrayBuffer` objects. For example, `ArrayBuffer { [Uint8Contents]: <2a 00 00 00 00 00 00 00>, [byteLength]: 8 }`. `maxArrayLength` is respected when displaying `[Uint8Contents]`. If the `ArrayBuffer` is [detached](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer#transferring_arraybuffers), it is displayed as `ArrayBuffer { (detached), [byteLength]: 0 }`.\n- **DataView:** `byteLength`, `byteOffset` and `buffer` are displayed for `DataView` objects. For example, `DataView { [byteLength]: 8, [byteOffset]: 0, [buffer]: ArrayBuffer { [Uint8Contents]: <2a 00 00 00 00 00 00 00>, [byteLength]: 8 } }`.\n\n**Classes and functions:**\n\n- **ES6 Class:** If a callable (i.e., `typeof value === \"function\"`) object is an ES6 class, it is displayed as `[class ${className}]` or `[class (anonymous)]` if the class name is not available, or `[class ${className} extends ${superClassName}]` if the class has a superclass and the superclass name is available.\n- **Function:** Functions are shown as `[${Type}: ${name}]` or `[${Type} (anonymous)]` (`Type` is `Function`, `AsyncFunction`, `GeneratorFunction`, or `AsyncGeneratorFunction`); if the resolved `${className}` differs from `Type`, append it—except when it is `\"Object\"`.\n\n**Collections:**\n\n- **Array:** `Array` objects are displayed as `[e1, e2, ...]`. Empty slots are displayed as `<${n} empty item${n === 1 ? \"\" : \"s\"}>`. For subclasses of `Array` or typed arrays, the `${className}` is displayed with its size, e.g., `MyArray(4) [1, <2 empty items>, 2, { foo: \"bar\" }]` or `Uint8Array(3) [1, 2, 3]`.\n- **Typed arrays:** Typed arrays (e.g., `Uint8Array`, `Int16Array`, etc.) are displayed as `${CtorName}(${length}) [v1, v2, ...]`. When `showHidden` is `\"always\"`, the following special properties are also displayed: `[BYTES_PER_ELEMENT]`, `[length]`, `[byteLength]`, `[byteOffset]`, and `[buffer]`.\n- **Long arrays, `Map`s, and `Set`s:** If `maxArrayLength` is set and one of these collections has more elements than `maxArrayLength`, it is truncated and displays the omitted count, e.g., `[1, 2, 3, 4, ... 2 more items]`, `Map(3) { \"a\" => 1, ... 2 more items }`, or `Set(3) { \"a\", ... 2 more items }`.\n- **Map:** `Map` objects are displayed as `Map(${size}) { key1 => value1, key2 => value2, ... }`.\n- **Set:** `Set` objects are displayed as `Set(${size}) { value1, value2, ... }`.\n- **WeakMap/WeakSet:** `WeakMap` and `WeakSet` objects are displayed as `${className} { <items unknown> }`.\n\n**Regular objects:**\n\n- **Module:** `Module` objects are displayed as `[Module]` if its `[[Prototype]]` is not null, or `[Module: null prototype]` otherwise.\n- **Object:** Other objects are displayed as `{ key: value1, \"non identifier key\": value2, Symbol(id): value3, ... }`. `${className}` is displayed if it’s not `\"Object\"` and no prefix is already defined, e.g., `MyClass { key1: value1, key2: value2, ... }`. Objects with a null `[[Prototype]]` are displayed as `[Object: null prototype]`.\n- **Object keys:** String keys are displayed as `key` if they are valid identifiers, or `\"key\"` otherwise. Symbol keys are displayed as `Symbol(key)`. If a key is non-enumerable, it is displayed as `[key]` (NOTE: non-enumerable keys are only displayed if `showHidden` is not `\"none\"`).\n- **Getter/Setter:** Getters and setters are displayed as `[Getter/Setter]`, `[Getter]`, or `[Setter]`. For example, `{ foo: [Getter/Setter], bar: [Getter] }`. If `getters` is not `\"none\"`, getters are further inspected, e.g., `{ foo: [Getter] { bar: \"baz\" } }`. Note that getters might throw an error, and in such cases, the error message is displayed if the thrown value is an object with a `message` property, e.g., `{ foo: [Getter: <Inspection threw (error message)>] }`.\n\n### Available Options\n\n| Option                | Type                                                                      | Default                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| --------------------- | ------------------------------------------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `callToJSON`          | `boolean`                                                                 | `false`                            | Whether to call `toJSON()` on the value before stringifying it (if available).                                                                                                                                                                                                                                                                                                                                                         |\n| `callNodeInspect`     | `boolean`                                                                 | `true`                             | Whether to call `[Symbol.for(\"nodejs.util.inspect.custom\")]()` on the value before stringifying it (if available). This option takes precedence over `callToJSON`.                                                                                                                                                                                                                                                                     |\n| `callCustomInspect`   | `boolean`                                                                 | `true`                             | Whether to call `[Symbol.for(\"showify.inspect.custom\")]()` on the value before stringifying it (if available). This option takes precedence over `callToJSON` and `callNodeInspect`.                                                                                                                                                                                                                                                   |\n| `depth`               | `number`                                                                  | `Infinity`                         | Maximum recursion depth of the object to be inspected, similar to `util.inspect`.                                                                                                                                                                                                                                                                                                                                                      |\n| `indent`              | `number`                                                                  | `0`                                | Number of spaces to indent the output. If `indent` is `0`, the output is not indented.                                                                                                                                                                                                                                                                                                                                                 |\n| `breakLength`         | `number`                                                                  | `80`                               | Maximum line length before breaking. This option is ignored if `indent` is `0`.                                                                                                                                                                                                                                                                                                                                                        |\n| `showHidden`          | <code>\"none\" &#124; \"always\" &#124; \"exclude-meta\" &#124; boolean</code>  | `\"none\"`                           | Whether to show hidden (non-enumerable) properties, should be `\"none\"`, `\"always\"`, or `\"exclude-meta\"`. If set to `\"exclude-meta\"`, it behaves like `\"always\"` but removes common meta properties like the `length` property of arrays. For compatibility with Node.js’s `util.inspect`, `true` is also accepted as `\"always\"`, and `false` is also accepted as `\"none\"`, but it is recommended to use the string values for clarity. |\n| `getters`             | <code>\"none\" &#124; \"get\" &#124; \"set\" &#124; \"all\" &#124; boolean</code> | `\"none\"`                           | Whether to inspect getters. If set to `\"get\"`, only getters without a corresponding setter are inspected. If set to `\"set\"`, only getters with a corresponding setter are inspected. If set to `\"all\"`, all getters are inspected. For compatibility with Node.js’s `util.inspect`, `true` is also accepted as `\"all\"`, and `false` is also accepted as `\"none\"`, but it is recommended to use the string values for clarity.          |\n| `sorted`              | `boolean`                                                                 | `false`                            | Whether to sort the keys of objects (including `Map`s and `Set`s) in the resulting string.                                                                                                                                                                                                                                                                                                                                             |\n| `omittedKeys`         | <code>Set&lt;string &#124; symbol&gt;</code>                              | `new Set()`                        | A set of keys to omit from the output. Note that this option is _not recursive_ and only omits the top-level keys.                                                                                                                                                                                                                                                                                                                     |\n| `quoteStyle`          | <code>\"single\" &#124; \"double\" &#124; \"backtick\"</code>                   | `[\"double\", \"single\", \"backtick\"]` | Preferred quote style for strings. If an array is provided, **showify** tries each quote style in order.                                                                                                                                                                                                                                                                                                                               |\n| `quoteKeys`           | <code>\"auto\" &#124; \"always\"</code>                                       | `\"auto\"`                           | Whether to quote object keys. If set to `\"auto\"`, object keys are quoted only when necessary.                                                                                                                                                                                                                                                                                                                                          |\n| `numericSeparator`    | <code>\"none\" &#124; string &#124; boolean</code>                          | `\"none\"`                           | The thousands separator for numbers (including BigInts), e.g., `\",\"` or `\"_\"`. If set to `\"none\"`, no separator is used. For compatibility with Node.js’s `util.inspect`, `true` is also accepted as `\"_\"`, and `false` is also accepted as `\"none\"`, but it is recommended to use the string values for clarity.                                                                                                                      |\n| `trailingComma`       | <code>\"none\" &#124; \"always\" &#124; \"auto\"</code>                         | `\"none\"`                           | Whether to add a trailing comma to the last element of an array or object. If set to `\"auto\"`, a trailing comma is added only when the last item is on a separate line.                                                                                                                                                                                                                                                                |\n| `arrayBracketSpacing` | `boolean`                                                                 | `false`                            | Whether to add spaces inside the brackets of arrays.                                                                                                                                                                                                                                                                                                                                                                                   |\n| `objectCurlySpacing`  | `boolean`                                                                 | `true`                             | Whether to add spaces inside the curly braces of objects.                                                                                                                                                                                                                                                                                                                                                                              |\n| `referencePointer`    | `boolean`                                                                 | `true`                             | Whether to display circular references with a reference pointer. If set to `false`, circular references are displayed as `[Circular]`.                                                                                                                                                                                                                                                                                                 |\n| `maxArrayLength`      | `number`                                                                  | `Infinity`                         | Maximum number of elements to display for arrays, `Map`s, and `Set`s. If one of these collections has more elements than `maxArrayLength`, the output is truncated and includes the omitted count.                                                                                                                                                                                                                                     |\n| `maxStringLength`     | `number`                                                                  | `Infinity`                         | Maximum length of a string to display. If a string is longer than `maxStringLength`, it is displayed as `\"${s}\"... ${n} more character${n === 1 ? \"\" : \"s}\"`.                                                                                                                                                                                                                                                                          |\n| `colors`              | `boolean`                                                                 | `false`                            | Whether to enable ANSI colors.                                                                                                                                                                                                                                                                                                                                                                                                         |\n| `styles`              | `Object`                                                                  | `{}`                               | Custom styles for different types of values. Valid keys are `string`, `symbol`, `number`, `bigint`, `boolean`, `null`, `undefined`, `date`, `regexp`, and `special`. Valid colors are `bold`, `dim`, `reset`, `black`, `blue`, `cyan`, `gray`, `green`, `magenta`, `red`, `white`, `yellow`, and functions that take a string and return a string (for advanced styling).                                                              |\n| `serializers`         | `Serializer[]`                                                            | `[]`                               | Custom serializers for your own types. See the [custom serializers section](#custom-serializers) for more details.                                                                                                                                                                                                                                                                                                                     |\n\n### Custom Serializers\n\n**showify** supports three ways to customize the serialization of objects:\n\n- Using the special `Symbol(nodejs.util.inspect.custom)` property on objects (compatible with Node.js).\n- Using the `serializers` option in the `show()` function.\n- Using the **showify**’s own `Symbol(showify.inspect.custom)` property on objects (not compatible with Node.js).\n\n**showify** aims to be fully compatible with Node.js’s `Symbol(nodejs.util.inspect.custom)` property, so examples from the [Node.js documentation](https://nodejs.org/api/util.html#custom-inspection-functions-on-objects) should work with **showify** as well. Here’s an example adapted from the Node.js documentation that works seamlessly with **showify**:\n\n```typescript\nimport { type InspectOptions, type InspectOptionsStylized, show } from \"showify\";\n\nclass Box {\n  constructor(value) {\n    this.value = value;\n  }\n\n  [Symbol.for(\"nodejs.util.inspect.custom\")](\n    depth: number,\n    options: InspectOptionsStylized,\n    inspect: (value: unknown, options?: InspectOptions) => any,\n  ) {\n    if (depth < 0) {\n      return options.stylize(\"[Box]\", \"special\");\n    }\n\n    const newOptions = Object.assign({}, options, {\n      depth: options.depth === null ? null : options.depth - 1,\n    });\n\n    // Five space padding because that’s the size of \"Box< \".\n    const padding = \" \".repeat(5);\n    const inner = inspect(this.value, newOptions).replace(/\\n/g, `\\n${padding}`);\n    return `${options.stylize(\"Box\", \"special\")}< ${inner} >`;\n  }\n}\n\nconst box = new Box(true);\n\nconsole.log(show(box, { colors: true, indent: 2, depth: 2 }));\n// \"Box< true >\"\n```\n\nWhile this approach works, we generally recommend using custom serializers through the `serializers` option in the `show()` function, as it is more flexible and allows for better control over the serialization process. In **showify**, a serializer must implement the following interface:\n\n```typescript\ninterface Serializer {\n  if: (value: object, options: SerializerOptions) => boolean;\n  then: (\n    value: object,\n    options: SerializerOptions,\n    expand: (value: unknown, options?: Partial<SerializerOptions>) => Node,\n  ) => Node;\n}\n```\n\nYou may wonder what `Node` is. A `Node` is a tree-like structure that represents the value to be stringified:\n\n```typescript\ntype Node =\n  | { type: \"circular\"; ref: object }\n  | { type: \"text\"; value: string; ref?: object }\n  | { type: \"variant\"; inline: Node; wrap: Node; ref?: object }\n  | { type: \"sequence\"; values: Node[]; ref?: object }\n  | { type: \"between\"; values: Node[]; open?: Node; close?: Node; ref?: object };\n```\n\nInternally, **showify** interacts with Nodes rather than directly with strings:\n\n```text\n╔═══════╗   ╔═════════════════════╗   ╔════════════════════════╗\n║ value ║ → ║ Build tree of nodes ║ → ║ Render nodes to string ║\n╚═══════╝   ╚═════════════════════╝   ╚════════════════════════╝\n```\n\n`serializers` come into play during the second step, where the tree of nodes is built. The `if` function of a serializer is called with the value to be serialized. If it returns `true`, the `then` function is invoked to build the tree of nodes. The `expand` function is a helper that recursively serializes child values.\n\nYou can use the exported `serializer` helper function and the `Node` object to create your own serializers:\n\n```javascript\nimport { Node as SerializerNode, serializer, show } from \"showify\";\n\nconst { circular, text, variant, sequence, pair, between } = SerializerNode;\n\nclass Point {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n}\n\nconst pointSer = serializer({\n  if: (value) => value instanceof Point,\n  then: (value) => text(`Point(${value.x}, ${value.y})`),\n});\n\nclass Box {\n  constructor(data) {\n    this.data = data;\n  }\n}\n\nconst boxSer = serializer({\n  if: (value) => value instanceof Box,\n  then: (value, options, expand) =>\n    sequence([text(\"Box(\"), expand(value.data), text(\")\")]),\n});\n\nconst obj = {\n  point: new Point(1, 2),\n  box1: new Box({ foo: \"bar\" }),\n  box2: new Box(new Point(3, 4)),\n};\n\nconsole.log(show(obj, { indent: 2, serializers: [pointSer, boxSer] }));\n// {\n//   point: Point(1, 2),\n//   box1: Box({ foo: \"bar\" }),\n//   box2: Box(Point(3, 4))\n// }\n```\n\nAlternatively, you can define a `[Symbol.for(\"showify.inspect.custom\")]()` method on the object itself, which works similarly to the `Symbol(nodejs.util.inspect.custom)` property in Node.js. This method is called with the same arguments as the `then` function of a serializer, and should also return a `Node`.\n\n```typescript\nimport type { SerializerOptions, SerializerOptionsStylized, Node as SerializerNode } from \"showify\";\n\nclass Point {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n\n  [Symbol.for(\"showify.inspect.custom\")](\n    options: SerializerOptions,\n    expand: (value: unknown, options?: Partial<SerializerOptions>) => SerializerNode,\n  ) {\n    // We avoid using helper functions like `text` here to eliminate runtime dependency on showify\n    return { type: \"text\", value: `Point(${this.x}, ${this.y})` };\n  }\n}\n\nconsole.log(show([new Point(1, 2), new Point(3, 4)]));\n// [Point(1, 2), Point(3, 4)]\n```\n\nThis can be useful if you want to create a library compatible with **showify** without the need to include it as a dependency. However, it is also more intrusive and less flexible than using the `serializers` option, so we generally recommend using the `serializers` option instead.\n\nThe above examples show how to use custom serializers to display `Point` and `Box` objects in a custom format. The `pointSer` serializer formats `Point` objects as `Point(x, y)`, and the `boxSer` serializer formats `Box` objects as `Box(...)`.\n\nWe’ve seen how to use `text` and `sequence` to build simple nodes. There are other nodes we haven’t used yet. Here’s a brief introduction to all these nodes:\n\n- **`circular`**: Represents a circular reference. Normally, you don’t need to create this node manually in a serializer. All nodes returned by a custom serializer automatically get a `ref` property, which helps detect circular references.\n- **`text`**: Represents a text node. The `value` property holds the text to be displayed.\n- **`variant`**: Represents a “variant” node. Some objects format differently depending on whether they are inline or multiline. For example, when `trailingComma` is `\"auto\"`, a trailing comma is added only when the last item is on a separate line. This can be represented with `variant(inlineNode, multilineNode)`.\n- **`sequence`**: Represents a sequence of nodes. The `values` property is an array of nodes to be displayed in order. Unlike `between`, `sequence` does not break lines between nodes. `pair(left, right)` is an alias of `sequence([left, right])`.\n- **`between`**: Represents a sequence of nodes. The `values` property is an array of nodes to be displayed in order. The `open` and `close` properties are optional nodes to be displayed before and after the `values` nodes. Don’t be confused by the name, `between` can be used like `sequence` without `open` and `close`. The key difference is that `between` breaks lines between nodes according to the `indent` and `breakLength` options.\n\nSo far, you might wonder how `sequence` and `between` differ. Let’s use a `Pair` class as an example to demonstrate the difference:\n\n```javascript\nclass Pair {\n  constructor(left, right) {\n    this.left = left;\n    this.right = right;\n  }\n}\n\nconst badPairSer = serializer({\n  if: (value) => value instanceof Pair,\n  then: (value, options, expand) =>\n    sequence([\n      text(\"(\"),\n      expand(value.left),\n      text(\", \"),\n      expand(value.right),\n      text(\")\"),\n    ]),\n});\n\nconst goodPairSer = serializer({\n  if: (value) => value instanceof Pair,\n  then: (value, options, expand) =>\n    between([\n      pair(expand(value.left), text(\", \")),\n      expand(value.right)\n    ], text(\"(\"), text(\")\")),\n});\n```\n\nAt first glance, `badPairSer` and `goodPairSer` seem identical, and they produce the same output for short values:\n\n```javascript\nconst p = new Pair(\"left\", \"right\");\n\nconsole.log(show(p, { indent: 2, serializers: [badPairSer] }));\n// (\"left\", \"right\")\nconsole.log(show(p, { indent: 2, serializers: [goodPairSer] }));\n// (\"left\", \"right\")\n```\n\nHowever, they behave differently when the `Pair` object is displayed in multiline format:\n\n```javascript\nconst s1 = \"This is a very long string that will break the line\";\nconst s2 = \"This is another very long string that will break the line\";\n\nconst p = new Pair(s1, s2);\n\nconsole.log(show(p, { indent: 2, serializers: [badPairSer] }));\n// (\"This is a very long string that will break the line\", \"This is another very long string that will break the line\")\nconsole.log(show(p, { indent: 2, serializers: [goodPairSer] }));\n// (\n//   \"This is a very long string that will break the line\",\n//   \"This is another very long string that will break the line\"\n// )\n```\n\nAlthough the inline format exceeds the `breakLength` limit, `badPairSer` does not break lines between its children, so the output stays on a single line. On the other hand, `goodPairSer` uses `between`, which breaks lines between its children, resulting in a multiline output.\n\nHere’s a more interesting example where child nodes themselves can be multiline:\n\n```javascript\nconst obj1 = { foo: \"bar\", bar: \"baz\", baz: \"quxx\" };\nconst obj2 = { qux: \"baz\", baz: \"bar\", bar: \"foo\" };\n\nconst p = new Pair(obj1, obj2);\n\nconsole.log(show(p, { indent: 2, serializers: [badPairSer] }));\n// ({\n//   foo: \"bar\",\n//   bar: \"baz\",\n//   baz: \"quux\"\n// }, {\n//   qux: \"baz\",\n//   baz: \"bar\",\n//   bar: \"foo\"\n// })\nconsole.log(show(p, { indent: 2, serializers: [goodPairSer] }));\n// (\n//   { foo: \"bar\", bar: \"baz\", baz: \"quux\" },\n//   { qux: \"baz\", baz: \"bar\", bar: \"foo\" }\n// )\n```\n\nWhile the outputs might be different from what you expect, the underlying principle remains the same. The `badPairSer` serializer uses `sequence`, which does not break lines between _direct_ children. Therefore, it tries to break lines within the children themselves when possible. In contrast, `goodPairSer` uses `between`, which handles line breaks between children, so it doesn’t require further instruction for child elements to break lines.\n\nThe `goodPairSer` is still not “good” enough — the separator is still `\", \"` (with a space after) when multiline, which is not what we want. We can use `variant` to solve this problem:\n\n```javascript\nconst goodPairSer = serializer({\n  if: (value) => value instanceof Pair,\n  then: (value, options, expand) =>\n    variant(\n      // The inline format\n      sequence([\n        text(\"(\"),\n        expand(value.left),\n        text(\", \"), // A comma with a space after\n        expand(value.right),\n        text(\")\"),\n      ]),\n      // The multiline format\n      between([\n        pair(expand(value.left), text(\",\")), // No space after the comma\n        expand(value.right)\n      ], text(\"(\"), text(\")\")),\n    ),\n});\n```\n\nThe `variant` node enforces inline formatting for the first argument and multiline formatting for the second argument. Using `sequence` for the inline format is just a personal preference; you can use `between` instead, as they behave similarly in inline format.\n\nThe `options` argument in `then` function and the second optional argument in `expand` are almost identical to the options passed to `show`, which we'll refer to as `SerializerOptions` below. The `SerializerOptions` is a subset of the options passed to `show`, with the following differences:\n\n- `indent`, `breakLength`, and `referencePointer` are not available in `SerializerOptions`, as they only affect rendering the nodes to strings and do not interact with the process of building the node tree.\n- `level` is available in `SerializerOptions`, indicating the current depth of the object being inspected.\n- `ancestors` is available in `SerializerOptions`, which is an array of the ancestors of the current value. This is useful for detecting circular references.\n- An object named `c` is available in `SerializerOptions`, containing functions to colorize strings using ANSI colors. These functions are similar to [chalk](https://github.com/chalk/chalk), such as `c.bold`, `c.cyan`, and so on, as well as `c.number`, `c.special`, etc., which are aliases for corresponding styles in the `styles` option. Note that when `colors` is `false`, all color functions are no-op functions that return the input string unchanged.\n\n**showify** automatically handles `level` increment in `expand`, and internally triggers a signal to stop recursion when `level` exceeds `depth`, so you don't need to worry about it. Circular references are also automatically detected — the current value is added to the `ancestors` array, and the `ref` property of each node returned is set to its value to detect circular references. As shown earlier, since the tree of nodes is built in two stages, indentation and line breaking are handled by `between`, so you don't need to worry about those either.\n\nHere’s an example showing how to use the `options` argument in `then` and `expand`:\n\n```javascript\nconst ser = serializer({\n  if: (value, { omittedKeys }) =>\n    \"_tag\" in value &&\n    typeof value._tag === \"string\" &&\n    // Detect if `_tag` is already omitted to avoid infinite recursion\n    !omittedKeys.has(\"_tag\"),\n  then: (val, { ancestors, c, level }, expand) => {\n    const tag = val._tag;\n    return sequence([\n      text(c.blue(tag)),\n      text(\"(\"),\n      expand(val, {\n        // Reset `level` and force expansion the object with a depth of 1\n        level: 0,\n        depth: 1,\n        // Omit the `_tag` key when expanding the object\n        omittedKeys: new Set([\"_tag\"]),\n        // Avoid auto-adding current value to `ancestors` to avoid circulars\n        ancestors: [...ancestors],\n      }),\n      text(\")\"),\n    ]);\n  },\n});\n\nconst obj = { _tag: \"Some\", value: 42, nested: { foo: { bar: \"baz\" } } };\n\nconsole.log(show(obj, { indent: 2, serializers: [ser], colors: true }));\n// Some({ value: 42, nested: { foo: [Object] } })\n```\n\n## Performance\n\n**showify** is designed to be both efficient and performant. While the exact performance depends on the complexity of the inspected objects and the chosen options, **showify** generally performs very well across most use cases.\n\nThe detailed benchmark results are listed below:\n\n```plaintext\n> inspect small objects\nname                      hz     min     max    mean     p75     p99    p995    p999     rme  samples\nutil.inspect      331,765.00  0.0023  0.7345  0.0030  0.0027  0.0060  0.0067  0.0222  ±0.70%   165883\nshowify            19,771.68  0.0363  4.5130  0.0506  0.0485  0.1278  0.1770  0.3943  ±2.07%     9886\npretty-format     263,180.95  0.0031  0.5132  0.0038  0.0036  0.0070  0.0077  0.0231  ±0.53%   131591\nobject-inspect      1,999.72  0.4259  1.2383  0.5001  0.5089  0.8780  0.9557  1.0895  ±0.89%     1000\nstringify-object    1,391.39  0.6386  1.3762  0.7187  0.7370  1.0406  1.1360  1.3762  ±0.87%      696\n\n> inspect large objects\nname                   hz      min      max     mean      p75      p99     p995     p999     rme  samples\nutil.inspect       499.32   1.7958   3.1423   2.0027   2.0424   2.9653   3.1330   3.1423  ±1.40%      250\nshowify           55.7037  15.3508  22.0917  17.9521  18.6678  22.0917  22.0917  22.0917  ±4.08%       28\npretty-format      365.28   2.3214   5.6467   2.7376   2.7650   5.2624   5.6467   5.6467  ±3.10%      183\nobject-inspect     2.3993   399.74   452.77   416.79   426.61   452.77   452.77   452.77  ±2.87%       10\nstringify-object   1.2630   683.92   987.43   791.79   818.72   987.43   987.43   987.43  ±9.99%       10\n\n> inspect huge objects\nname                   hz      min      max     mean      p75      p99     p995     p999      rme  samples\nutil.inspect      47.8965  16.7504  27.8419  20.8783  23.0972  27.8419  27.8419  27.8419   ±6.13%       24\nshowify           12.1","readmeFilename":"README.md"}