{"_id":"halua","_rev":"48-958616b04d522e3f100e546b6fc87856","name":"halua","dist-tags":{"latest":"5.0.0"},"versions":{"0.0.5":{"name":"halua","version":"0.0.5","keywords":["logger","logging"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@0.0.5","maintainers":[{"name":"tokkiumai","email":"tokkiumai@gmail.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"d8528f0d4f675aefff4bc628905b29b86fcd7694","tarball":"https://registry.npmjs.org/halua/-/halua-0.0.5.tgz","fileCount":7,"integrity":"sha512-48PMNo8vcGimQzQvaP0juqEuiBDU674Oz/NG3kybdMh4ar3dofpDZ7Tjrr2uWyIJ1NxSrhcXa1NWeMpxvC8MPA==","signatures":[{"sig":"MEYCIQC4DZey5sVEMvuE9NZMQzEzzRqrxo+ZcG1gvKBlQv1F9wIhAJJztuklNF6RBkaVQqST1zeWnOxTqfkLrLEjO0nrK1+j","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16312},"main":"lib/index.js","types":"lib/index.d.ts","module":"lib/index.mjs","gitHead":"545c7da428f260c966ed00ea39021d7e35eac498","scripts":{"test":"jest --config --passWithNoTests jest.config.ts","build":"tsup","prepare":"yarn build","postversion":"git push && git push --tags"},"_npmUser":{"name":"tokkiumai","actor":{"name":"tokkiumai","type":"user","email":"tokkiumai@gmail.com"},"email":"tokkiumai@gmail.com"},"repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"logger for JS","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.0.2","tsup":"^8.5.0","ts-jest":"^29.4.0","ts-node":"^10.9.2","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/halua_0.0.5_1750781421076_0.9332557151610963","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"halua","version":"1.0.0","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@1.0.0","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"8ab9c1ae8a2ef1ba5d556e9ac48a642b02094cbc","tarball":"https://registry.npmjs.org/halua/-/halua-1.0.0.tgz","fileCount":7,"integrity":"sha512-9TBO/GDw41nPd7O8gJEvNbN6J82YsrBndd4pnSIAo31aCghHkfKLAqzO0s+ztqK6ju1QJLCAi8ov+R4uQBu0Wg==","signatures":[{"sig":"MEYCIQC2yTKWQOchWcyek8S3TLsd6g/d5+slVyk9XEdmDhUq8QIhAOxHyicoP9OJ+WschXK/Mdhxw8w8P27LaGtPe6bbsXmY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54803},"main":"lib/index.js","type":"module","_from":"file:halua-1.0.0.tgz","types":"lib/index.d.ts","module":"lib/index.mjs","scripts":{"test":"vitest","bench":"node benchmarks/main_bench.js","build":"tsup","postversion":"git push && git push --tags"},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"_resolved":"/private/var/folders/dr/zy5hc7_n3p5ds1hk9tt_l84w0000gn/T/a45e130454d611c58e70e1c920baa3c0/halua-1.0.0.tgz","_integrity":"sha512-9TBO/GDw41nPd7O8gJEvNbN6J82YsrBndd4pnSIAo31aCghHkfKLAqzO0s+ztqK6ju1QJLCAi8ov+R4uQBu0Wg==","repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Package that takes control of logging, metrics and other stuff","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^3.2.4","ts-node":"^10.9.2","prettier":"^3.6.1","tinybench":"^5.0.0","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/halua_1.0.0_1760089939662_0.8517213843952591","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"halua","version":"1.1.0","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@1.1.0","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"e586def39ea96dea8bf4e3e41c267d85a1004e30","tarball":"https://registry.npmjs.org/halua/-/halua-1.1.0.tgz","fileCount":7,"integrity":"sha512-GBQZ4v2foG95lkT6awncT4rYwy1gryhmx6pzS6vyEg1XPuCiLGE/3grcA3iQgoIcivPckqA6SQpaETgaO5bhog==","signatures":[{"sig":"MEQCIADmXnHjgicFIPuSMbVqAqGHwkUFCQ3sEbbuczJTyraVAiBQj//iEvf1D4Ld1mHEYXJuo4Lye+z1faQNR2MFSFqWLg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55439},"main":"lib/index.js","type":"module","_from":"file:halua-1.1.0.tgz","types":"lib/index.d.ts","module":"lib/index.mjs","scripts":{"test":"vitest","bench":"node benchmarks/main_bench.js","build":"tsup","postversion":"git push && git push --tags"},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"_resolved":"/private/var/folders/dr/zy5hc7_n3p5ds1hk9tt_l84w0000gn/T/d078193c1234d57796af2bc08b7426e8/halua-1.1.0.tgz","_integrity":"sha512-GBQZ4v2foG95lkT6awncT4rYwy1gryhmx6pzS6vyEg1XPuCiLGE/3grcA3iQgoIcivPckqA6SQpaETgaO5bhog==","repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Package that takes control of logging, metrics and other stuff","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^3.2.4","ts-node":"^10.9.2","prettier":"^3.6.1","tinybench":"^5.0.0","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/halua_1.1.0_1760632670442_0.33185780917803087","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"halua","version":"2.0.0","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@2.0.0","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"57ac414153e612cae241ff10f964227920fcd64a","tarball":"https://registry.npmjs.org/halua/-/halua-2.0.0.tgz","fileCount":7,"integrity":"sha512-P9Ej72OnN6JULOkRWWCv/1HmJBn4ZSZ3cjt5XKKNqVh6vycgAYTTduzhmIsMBTeLrRmwzP3lIN/CIz5fV8Wh1A==","signatures":[{"sig":"MEQCID8kwHjEeF2vLn/DM4oa4ytGkqzfnBioNzGcBIVTOED3AiBa0fHaJy9WianEoOIYU70YfR9wZ9XYBEtrwnAb/y20iw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51821},"main":"lib/index.js","type":"module","_from":"file:halua-2.0.0.tgz","types":"lib/index.d.ts","module":"lib/index.mjs","scripts":{"test":"vitest","bench":"node benchmarks/main_bench.js","build":"tsup","postversion":"git push && git push --tags"},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"_resolved":"/private/var/folders/dr/zy5hc7_n3p5ds1hk9tt_l84w0000gn/T/e82254c865283734272fe9f4cb05be1e/halua-2.0.0.tgz","_integrity":"sha512-P9Ej72OnN6JULOkRWWCv/1HmJBn4ZSZ3cjt5XKKNqVh6vycgAYTTduzhmIsMBTeLrRmwzP3lIN/CIz5fV8Wh1A==","repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Package that takes control of logging, metrics and other stuff","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^3.2.4","ts-node":"^10.9.2","prettier":"^3.6.1","tinybench":"^5.0.0","typescript":"^5.8.3","@types/node":"^24.9.1"},"_npmOperationalInternal":{"tmp":"tmp/halua_2.0.0_1769540391009_0.6687148502057496","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"halua","version":"2.0.1","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@2.0.1","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"0a42e65b3564db92b21f8fc0574317deb207cfaf","tarball":"https://registry.npmjs.org/halua/-/halua-2.0.1.tgz","fileCount":7,"integrity":"sha512-NLsnRmeQtYW0xFFIfK/DkMwkQxmjm9LmRRynu+douxAv4AtnjWxzKS0w0x6hsRfSv/RhloFZY12YfKZpDYEA7g==","signatures":[{"sig":"MEUCIFMCcOzMeg1WbNQNuzHRheg5eC+NHtrDToyiwgKD1RQFAiEAvhyI9hFieUkNX4Hynqww8OYWjuPnFCLnvJHCFRu6HoE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51843},"main":"lib/index.js","type":"module","_from":"file:halua-2.0.1.tgz","types":"lib/index.d.ts","module":"lib/index.mjs","scripts":{"test":"vitest","bench":"node benchmarks/main_bench.js","build":"tsup","postversion":"git push && git push --tags"},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"_resolved":"/private/var/folders/dr/zy5hc7_n3p5ds1hk9tt_l84w0000gn/T/46e7b3256d668a2ca868ca453751d5c6/halua-2.0.1.tgz","_integrity":"sha512-NLsnRmeQtYW0xFFIfK/DkMwkQxmjm9LmRRynu+douxAv4AtnjWxzKS0w0x6hsRfSv/RhloFZY12YfKZpDYEA7g==","repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Package that takes control of logging, metrics and other stuff","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^3.2.4","ts-node":"^10.9.2","prettier":"^3.6.1","tinybench":"^5.0.0","typescript":"^5.8.3","@types/node":"^24.9.1"},"_npmOperationalInternal":{"tmp":"tmp/halua_2.0.1_1770194258792_0.04525006947391064","host":"s3://npm-registry-packages-npm-production"}},"2.0.2":{"name":"halua","version":"2.0.2","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@2.0.2","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"fe66feba7cb1c24e56920cd87fdb42060b51f00e","tarball":"https://registry.npmjs.org/halua/-/halua-2.0.2.tgz","fileCount":7,"integrity":"sha512-wrg6A0pqUw6gvOBh2YCR5DJkGM3A6FCn4eI+oPBXjwOy6PWcO17sR7QrsKrx3LL3NXBztHElK23VS5FBVpAWYA==","signatures":[{"sig":"MEUCIHP5oHxZQ+GsLIIsYRG5ytiHk0ozXNaR2DCNeHQBntGbAiEAjRFduS4nCagAmekvCLQahyFcDVRBbJT2bn2L7LLr6n4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52038},"main":"lib/index.js","type":"module","types":"lib/index.d.ts","module":"lib/index.cjs","gitHead":"7ca1154f0a80904f2ca086594141869e216e7ca5","scripts":{"test":"vitest","bench":"node benchmarks/main_bench.js","build":"tsup","prepare":"pnpm run test run && pnpm run build","postversion":"git push && git push --tags"},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Package that takes control of logging, metrics and other stuff","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^3.2.4","ts-node":"^10.9.2","prettier":"^3.6.1","tinybench":"^5.0.0","typescript":"^5.8.3","@types/node":"^24.9.1"},"_npmOperationalInternal":{"tmp":"tmp/halua_2.0.2_1771568643215_0.39807030305004965","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"halua","version":"3.0.0","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@3.0.0","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"bab5dd8dd0b7b3e51957532728b3313084b9d1fd","tarball":"https://registry.npmjs.org/halua/-/halua-3.0.0.tgz","fileCount":7,"integrity":"sha512-V8IQbY864O+Uim60Gb99Sfud3KinZmZWBxMGM1rFcUvRjglOB62HJaH10sUPDfuTCCM1vfvUEn8tJjui2g89rQ==","signatures":[{"sig":"MEQCIFHp+LJ+/hCf2o3O2T1pURU8N3WlF5dDpxc0lz/ARTNTAiB4h2c9pKQ1QCmCAAasajE2v7XzegEhqJoH5coAgNnzSw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52078},"main":"lib/index.js","type":"module","types":"lib/index.d.ts","module":"lib/index.cjs","gitHead":"0b221d9b1a961fe1436d299e6ecbe7ff181fa65e","scripts":{"test":"vitest","bench":"node benchmarks/main_bench.js","build":"tsup","prepare":"pnpm run test run && pnpm run build","postversion":"git push && git push --tags"},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Package that takes control of logging, metrics and other stuff","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^3.2.4","ts-node":"^10.9.2","prettier":"^3.6.1","tinybench":"^5.0.0","typescript":"^5.8.3","@types/node":"^24.9.1"},"_npmOperationalInternal":{"tmp":"tmp/halua_3.0.0_1776366353742_0.6423357552191373","host":"s3://npm-registry-packages-npm-production"}},"4.0.2":{"name":"halua","version":"4.0.2","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@4.0.2","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"3cb4bdcf93fd3887a7858b250e561e57191866ef","tarball":"https://registry.npmjs.org/halua/-/halua-4.0.2.tgz","fileCount":7,"integrity":"sha512-jINS0Z2xO8PydCOayrBa8JFkWOHE1SJx30zawUWD7KkJHfL86mJexvygLt7PMoMf2ogK//5po8Dmj+DMz4xzTQ==","signatures":[{"sig":"MEUCIQD5R1jHvKzqiCHaCpDADts6u1YauxbZB78lFZz2WvgO1wIgPNxRCoL48gsmcEJFLdj+Efc9yoSh1/ov6KsLI2NtVqQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":93305},"main":"lib/index.cjs","type":"module","types":"lib/index.d.ts","module":"lib/index.js","exports":{".":{"import":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"require":{"types":"./lib/index.d.ts","default":"./lib/index.cjs"}}},"gitHead":"629076e8e183b4289820630714c9c283b2112bf8","scripts":{"dev":"vitest","lint":"pnpm run format:check","test":"vitest","bench":"node benchmarks/main-bench.js","build":"vite build","format":"prettier --write \"**/*.{ts,js,json,md,yml,yaml}\"","prepare":"pnpm run lint && pnpm run test run && pnpm run build","postversion":"git push && git push --tags","format:check":"prettier --check \"**/*.{ts,js,json,md,yml,yaml}\""},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Tiny zero-dependency logger with pluggable dispatchers, child contexts, minor levels (e.g. INFO+5) and safe formatting","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"6.4.2","vitest":"4.1.7","ts-node":"10.9.2","prettier":"3.8.3","tinybench":"6.0.2","typescript":"6.0.3","@types/node":"25.9.1","vite-plugin-dts":"5.0.1","@microsoft/api-extractor":"7.58.7"},"_npmOperationalInternal":{"tmp":"tmp/halua_4.0.2_1779530923859_0.9908854146957884","host":"s3://npm-registry-packages-npm-production"}},"4.1.0":{"name":"halua","version":"4.1.0","keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","_id":"halua@4.1.0","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"homepage":"https://github.com/inshinrei/halua#readme","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"dist":{"shasum":"8f131a1cef69c9e824837bb80d790acc18c2db18","tarball":"https://registry.npmjs.org/halua/-/halua-4.1.0.tgz","fileCount":7,"integrity":"sha512-ufZO1kAz/Ga7w9ymLuUAH3Sbr2mg4CCz0N9J7fXSzZ/jW7ZnXd8EiAGMAFXzVkzrnlBqu8aZct7+RY1nVRgzHg==","signatures":[{"sig":"MEQCIH3OZpvoSnlcwfdcXObC/ML4je+m+0uVX1U+rSSg8paGAiAeXv0tb7pez1hugevOCc57ataxOLppwa43TtIrVMsVLA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":96088},"main":"lib/index.cjs","type":"module","types":"lib/index.d.ts","module":"lib/index.js","exports":{".":{"import":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"require":{"types":"./lib/index.d.ts","default":"./lib/index.cjs"}}},"gitHead":"9485059bd2ed29a42da10807b40ae302f98bb8a6","scripts":{"dev":"vitest","lint":"pnpm run format:check","test":"vitest","bench":"node benchmarks/main-bench.js","build":"vite build","format":"prettier --write \"**/*.{ts,js,json,md,yml,yaml}\"","prepare":"pnpm run lint && pnpm run test run && pnpm run build","postversion":"git push && git push --tags","format:check":"prettier --check \"**/*.{ts,js,json,md,yml,yaml}\""},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"repository":{"url":"git+https://github.com/inshinrei/halua.git","type":"git"},"_npmVersion":"10.8.1","description":"Tiny zero-dependency logger with pluggable dispatchers, child contexts, minor levels (e.g. INFO+5) and safe formatting","directories":{},"_nodeVersion":"22.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"6.4.2","vitest":"4.1.7","ts-node":"10.9.2","prettier":"3.8.3","tinybench":"6.0.2","typescript":"6.0.3","@types/node":"25.9.1","vite-plugin-dts":"5.0.1","@microsoft/api-extractor":"7.58.7"},"_npmOperationalInternal":{"tmp":"tmp/halua_4.1.0_1780085589572_0.8374403450358472","host":"s3://npm-registry-packages-npm-production"}},"5.0.0":{"name":"halua","version":"5.0.0","description":"Tiny zero-dependency logger with pluggable dispatchers, child contexts, minor levels (e.g. INFO+5) and safe formatting","type":"module","main":"lib/index.cjs","module":"lib/index.js","types":"lib/index.d.ts","exports":{".":{"import":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"require":{"types":"./lib/index.d.ts","default":"./lib/index.cjs"}}},"repository":{"type":"git","url":"git+https://github.com/inshinrei/halua.git"},"keywords":["logger","logging","node","console","web","json logs"],"author":{"name":"inshinrei"},"license":"MIT","bugs":{"url":"https://github.com/inshinrei/halua/issues"},"homepage":"https://github.com/inshinrei/halua#readme","devDependencies":{"@microsoft/api-extractor":"7.58.7","@types/node":"25.9.1","prettier":"3.8.3","tinybench":"6.0.2","ts-node":"10.9.2","typescript":"6.0.3","vite":"6.4.2","vite-plugin-dts":"5.0.1","vitest":"4.1.7"},"publishConfig":{"access":"public"},"scripts":{"test":"vitest","dev":"vitest","bench":"node benchmarks/main-bench.js","build":"vite build","format:check":"prettier --check \"**/*.{ts,js,json,md,yml,yaml}\"","format":"prettier --write \"**/*.{ts,js,json,md,yml,yaml}\"","lint":"pnpm run format:check","postversion":"git push && git push --tags"},"_id":"halua@5.0.0","_integrity":"sha512-mdwS4Fmm7uC3d+dddCr2ay0qW5x6inh+VmGxRNeZDa2E/SSCJ+YfaFxH7c6AirCgMSGYJNeC2HdBuzzMg6D7hA==","_resolved":"/private/var/folders/dr/zy5hc7_n3p5ds1hk9tt_l84w0000gn/T/a54994ee7bd6d401e4b56a09adc71d5d/halua-5.0.0.tgz","_from":"file:halua-5.0.0.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-mdwS4Fmm7uC3d+dddCr2ay0qW5x6inh+VmGxRNeZDa2E/SSCJ+YfaFxH7c6AirCgMSGYJNeC2HdBuzzMg6D7hA==","shasum":"21b9d0f19adefd55aeaec066a1a769d3dd56deb1","tarball":"https://registry.npmjs.org/halua/-/halua-5.0.0.tgz","fileCount":8,"unpackedSize":117919,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHqVEaYkEpTcZpMrIcuLVaKYwaR16vDdRjrKiKb530RXAiBf42gmd08fx8tNU478XeRNYNHnUXkFJpcIwvufC1P7JA=="}]},"_npmUser":{"name":"inshinrei","email":"tokkiumai@icloud.com"},"directories":{},"maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/halua_5.0.0_1786972413850_0.10615404138602003"},"_hasShrinkwrap":false}},"time":{"created":"2025-06-24T15:13:33.310Z","modified":"2026-08-17T13:13:34.478Z","0.0.1":"2025-06-24T15:13:33.601Z","0.0.2":"2025-06-24T15:31:12.556Z","0.0.3":"2025-06-24T15:43:42.074Z","0.0.4":"2025-06-24T16:08:13.325Z","0.0.5":"2025-06-24T16:10:21.262Z","26.0.1":"2025-07-01T19:39:52.689Z","26.0.2":"2025-07-03T13:11:16.135Z","26.1.0":"2025-07-10T19:51:19.776Z","26.1.1":"2025-07-10T19:53:38.702Z","26.1.2":"2025-07-11T06:40:00.404Z","26.1.4":"2025-07-16T18:57:51.533Z","26.1.5":"2025-07-16T20:41:25.608Z","26.1.6":"2025-07-17T05:55:30.836Z","26.1.7":"2025-07-17T06:03:57.397Z","25.0.0":"2025-07-20T21:09:45.981Z","25.1.0":"2025-08-15T18:27:10.369Z","25.1.1":"2025-08-19T09:05:08.080Z","1.0.0":"2025-10-10T09:52:19.850Z","1.1.0":"2025-10-16T16:37:50.671Z","2.0.0":"2026-01-27T18:59:51.155Z","2.0.1":"2026-02-04T08:37:38.939Z","2.0.2":"2026-02-20T06:24:03.382Z","3.0.0":"2026-04-16T19:05:53.870Z","4.0.0":"2026-05-23T09:26:28.652Z","4.0.1":"2026-05-23T09:55:17.750Z","4.0.2":"2026-05-23T10:08:44.010Z","4.1.0":"2026-05-29T20:13:09.732Z","5.0.0":"2026-08-17T13:13:34.106Z"},"bugs":{"url":"https://github.com/inshinrei/halua/issues"},"author":{"name":"inshinrei"},"license":"MIT","homepage":"https://github.com/inshinrei/halua#readme","keywords":["logger","logging","node","console","web","json logs"],"repository":{"type":"git","url":"git+https://github.com/inshinrei/halua.git"},"description":"Tiny zero-dependency logger with pluggable dispatchers, child contexts, minor levels (e.g. INFO+5) and safe formatting","maintainers":[{"name":"inshinrei","email":"tokkiumai@icloud.com"}],"readme":"# Halua\n\n**A powerful, extensible logging library for Node.js, browsers, and edge runtimes.**\n\nHalua gives you full control over log output through pluggable dispatchers (text, JSON, console), hierarchical child\nloggers, fine-grained level filtering (including minor levels like `INFO+3`), and zero-config defaults that just work.\n\n[![npm version](https://img.shields.io/npm/v/halua.svg)](https://www.npmjs.com/package/halua)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Features\n\n- Zero-config default logger (writes to `console` using appropriate methods)\n- Four built-in dispatchers: `NewTextDispatcher`, `NewJSONDispatcher`, `NewConsoleDispatcher`, `NewConsoleColoredDispatcher`\n- Compose any number of dispatchers per logger instance\n- Child loggers that automatically append context (`logger.child(\"user\", 42)`)\n- `createHalua()` fluent builder with typed `.use(feature)` (accumulates)\n- Default logger includes `.flow(name, ctx?)` and `.span(label, fn?)` for log-driven development\n- Opt-in `capture()` for asserting the log story in tests\n- Powerful level system: `TRACE` < `DEBUG` < `INFO` < `NOTICE` < `WARN` < `ERROR` < `FATAL` + minor levels (`INFO+5`)\n- Per-dispatcher level overrides and exact-match mode\n- Zero-cost disabled levels: calling a level with no active dispatchers (e.g. `debug` in prod) is a true no-op with zero overhead\n- Beautiful structured formatting for objects, arrays, Maps, Sets, Errors, etc.\n- Safe by design — dispatcher errors never crash your application\n- `.stamp(label, id?)` + `.stampEnd(id)` (or returned ender) for `performance.now`-based timing with automatic pretty\n  `took X.XXms` logging; the ender and `.stampEnd` return elapsed ms as a number\n- Tiny, fast, tree-shakeable ESM + CJS + TypeScript\n\n## Installation\n\n```bash\nnpm install halua\n# or\npnpm add halua\n```\n\n## Upgrading\n\n4.1.0 → 5.0.0: most apps need no code changes. See [`docs/migrations/4.1.0-to-5.0.0.md`](docs/migrations/4.1.0-to-5.0.0.md)\n(also shipped at `lib/migrations/4.1.0-to-5.0.0.md` in the npm package).\n\n## Quick Start\n\n```ts\nimport { halua } from \"halua\"\n\nhalua.info(\"Application started\")\nhalua.warn(\"Disk space low\", { available: \"12%\" })\nhalua.error(\"timeout\") // strings accepted too (unknownToError normalizes to Error)\n```\n\n**Default output (console):**\n\n```\n22/05/2026 21:55:50 INFO Application started\n22/05/2026 21:55:50 WARN Disk space low { available: '12%' }\n22/05/2026 21:55:50 ERROR Error: timeout\n    at ...\n```\n\n## Dedicated Loggers & Dispatchers\n\nUse the built-in dispatcher factories to create purpose-specific loggers:\n\n```ts\nimport { halua, NewTextDispatcher, NewJSONDispatcher, Level } from \"halua\"\n\n// Text logger (human readable)\nlet textLogger = halua.create(NewTextDispatcher((line) => sendToLogServer(line)))\n\n// JSON logger (for structured ingestion)\nlet jsonLogger = halua.create(NewJSONDispatcher((json) => writeToArchive(json)))\n\n// Console logger (explicit)\nlet consoleLogger = halua.create(NewConsoleDispatcher(console))\n\n// Colored console (ANSI in Node, %c CSS in browsers; colors: trace/debug=purple, info=blue, notice=orange, warn/error/fatal=red)\nlet colorLogger = halua.create(NewConsoleColoredDispatcher(console))\n\ntextLogger.info(\"user action\", { id: 123, type: \"click\" })\n// -> 22/05/2026 21:55:50 INFO user action { id: 123, type: \"click\" }\n\njsonLogger.info(\"structured\", { success: true })\n// -> {\"timestamp\":\"2026-05-22T18:55:50.430Z\",\"level\":\"INFO\",\"args\":[\"structured\",{\"success\": true}]}\n```\n\nYou can pass an array to use **multiple dispatchers at once**:\n\n```ts\nlet prodLogger = halua.create([NewTextDispatcher(sendToFile), NewJSONDispatcher(sendToElastic)], { level: Level.Info })\n```\n\n## Child Loggers (Context)\n\n```ts\nlet requestLogger = halua.child(\"requestId\", \"abc-123\", \"user\", 42)\n\nrequestLogger.info(\"processing started\")\n// -> ... INFO processing started requestId abc-123 user 42\n\nlet stepLogger = requestLogger.child(\"step\", \"validate\")\nstepLogger.warn(\"slow validation\")\n// -> ... WARN slow validation requestId abc-123 user 42 step validate\n```\n\nCall `.create({ withArgs: [] })` to clear context on a child.\n\n### Flow marks & spans\n\nThe reserved mark key is `flow`. `halua.flow(name, ctx?)` is `child(\"flow\", name, …flattened ctx)`. `.span` logs\n`start` / `done` with `{ span, elapsedMs }` on a `span <label>` child; on throw it logs `.error` or `never-happen` and\nrethrows. It does not emit the stamp `took X.XXms` line (use `.stamp` when you only want timing).\n\n```ts\nlet log = halua.flow(\"checkout\", { requestId: \"abc-123\" })\nlog.info(\"start\", { orderId: 88 })\nlet result = await log.span(\"charge\", async () => charge(order))\nlog.info(\"done\", { paymentId: result.id })\n// grep: flow checkout\n```\n\n## Building a logger\n\n`.create(dispatchers?, options?)` is still the shortcut and inherits features from the parent (the default `halua`\nalready has `spanFlow`). Use `createHalua()` when you need to compose features from scratch — including opt-in\n`capture()`, or a logger _without_ `.flow` / `.span`.\n\n```ts\nimport { createHalua, spanFlow, capture, NewTextDispatcher, Level } from \"halua\"\n\nlet logger = createHalua()\n    .dispatchers(NewTextDispatcher((line) => sendToLogServer(line)))\n    .use(spanFlow())\n    .use(capture())\n    .level(Level.Debug)\n    .build()\n```\n\n## Asserting the log story\n\n```ts\nlet logger = createHalua()\n    .dispatchers(NewTextDispatcher(() => {}))\n    .use(spanFlow())\n    .use(capture())\n    .build()\n\nlogger.flow(\"checkout\").info(\"start\")\nexpect(logger.collect().some((r) => r.args[0] === \"start\")).toBe(true)\n```\n\n`collect()` returns a copy of raw dispatch records (`{ timestamp, level, args, errorMeta? }`). `clear()` empties the\nshared buffer (parent and children share one).\n\n## Level Control\n\n```ts\nimport { Level } from \"halua\"\n\n// Instance level (affects all dispatchers that don't override)\nlet logger = halua.create({ level: Level.Warn })\n\nlogger.debug(\"hidden\")\nlogger.info(\"hidden\")\nlogger.warn(\"visible\")\nlogger.error(\"visible\")\n```\n\n### Per-Dispatcher Levels\n\n```ts\nlet logger = halua.create([\n    NewTextDispatcher(sendToFile, { level: Level.Info }),\n    NewJSONDispatcher(sendToMetrics, { level: Level.Error }),\n])\n```\n\n### Minor / Custom Levels\n\nUse the `LEVEL+N` syntax for fine-grained control (e.g. sampling, feature flags):\n\n```ts\nlet logger = halua.create(NewTextDispatcher(out), { level: `${Level.Info}+2` })\n\nlogger.logTo(\"INFO+1\", \"sampled out\")\nlogger.logTo(\"INFO+2\", \"important info\") // logged\nlogger.logTo(\"INFO+3\", \"very important\") // logged\nlogger.logTo(\"WARN\", \"always higher major level\") // logged\n```\n\nYou can also pass string levels directly: `{ level: \"ERROR+7\" }` or `logTo(\"DEBUG+10\", ...)`.\n\n## Sensitive Data Redaction\n\nPass `redactDataRegExp` (a `RegExp`) to `halua.create(options)` for the logger instance (applies to all its dispatchers) or to individual `New*Dispatcher(..., { redactDataRegExp })` (overrides the logger default).\n\n- In strings (and strings inside arrays): all matches of the regexp are replaced by `\"^_^\"`\n- In objects and Maps: if a _key_ matches the regexp, its value (any type) is replaced entirely by `\"^_^\"`\n- Works for both text and structured (JSON) output, and for `errorMeta`\n- Use the exported `DefaultRedactRegExp` for common PII (passwords, tokens, api keys, emails, SSNs, JWTs, credit cards, etc.) or provide your own.\n\n```ts\nimport { halua, NewJSONDispatcher, DefaultRedactRegExp } from \"halua\"\n\n// logger-level default (affects dispatchers without their own setting)\nlet prodLogger = halua.create(\n    [\n        NewJSONDispatcher(sendToStore),\n        NewTextDispatcher(sendToFile, { level: Level.Warn }), // this one can override if needed\n    ],\n    { redactDataRegExp: DefaultRedactRegExp },\n)\n\nprodLogger.info(\"login\", { user: \"alice\", password: \"hunter2\", apiKey: \"sk_xxx\" })\n// args become: [\"login\", { user: \"alice\", password: \"^_^\", apiKey: \"^_^\" }]\n\nprodLogger.info(\"token eyJhbGciOi...abc.123\", \"email: foo@bar.com\")\n// the string arg will have secrets replaced by ^_^\n```\n\nThe `redact` helper is also exported for custom dispatchers or preprocessing.\n\n## Dispatcher Options\n\nAll `New*Dispatcher` factories accept a second `options` argument:\n\n| Option             | Type                     | Default     | Description                                                                              |\n| ------------------ | ------------------------ | ----------- | ---------------------------------------------------------------------------------------- |\n| `level`            | `LogLevel`               | `undefined` | Minimum level this dispatcher accepts                                                    |\n| `exact`            | `LogLevel \\| LogLevel[]` | `null`      | Only log these exact levels (ignores normal hierarchy)                                   |\n| `printTimestamp`   | `boolean`                | `true`      | Include timestamp in output                                                              |\n| `printLevel`       | `boolean`                | `true`      | Include level name in output                                                             |\n| `spacing`          | `boolean`                | `true`      | Pretty-print objects/arrays with tabs & newlines (Text & JSON only)                      |\n| `redactDataRegExp` | `RegExp`                 | `undefined` | Redact sensitive data in strings/arrays and by key in objects/maps (see feature section) |\n\n`NewConsoleDispatcher` and `NewConsoleColoredDispatcher` do not support `spacing` (they pass values directly to console methods).\n\n## API Reference\n\n### Main Export\n\n```ts\nimport {\n    halua,\n    createHalua,\n    spanFlow,\n    capture,\n    Level,\n    NewTextDispatcher,\n    NewJSONDispatcher,\n    NewConsoleDispatcher,\n    NewConsoleColoredDispatcher,\n} from \"halua\"\n```\n\n- `halua` — default logger instance (preconfigured with `NewConsoleDispatcher` + `spanFlow()`)\n- `createHalua()` — fluent builder (`dispatchers`, `level`, `redact`, `withArgs`, `use`, `build`)\n- `spanFlow()` — feature: `.flow(name, ctx?)` and `.span(label, fn?)`\n- `capture()` — opt-in feature: `.collect()` / `.clear()`\n- `Level` — enum: `Trace | Debug | Info | Notice | Warn | Error | Fatal`\n- `NewTextDispatcher(send: (line: string, errorMeta?: Record<string, any>) => void, options?)` → factory\n- `NewJSONDispatcher(send: (json: string, errorMeta?: Record<string, any>) => void, options?)` → factory\n- `NewConsoleDispatcher(console: {debug,info,warn,error}, options?)` → factory\n- `NewConsoleColoredDispatcher(console: {debug,info,warn,error}, options?)` → factory (colors levels: TRACE/DEBUG=purple, INFO=blue, NOTICE=orange, WARN/ERROR/FATAL=red; uses ANSI in Node, %c in browsers)\n\n### Advanced Exports (for custom dispatcher authors)\n\n```ts\nimport {\n    DispatcherBase,\n    format,\n    getType,\n    toJSONValue,\n    Dispatcher,\n    HaluaLogger,\n    HaluaBuilder,\n    Feature,\n    SpanFlowApi,\n    CaptureApi,\n    CapturedRecord,\n    ConsoleLike,\n} from \"halua\"\n```\n\n- `DispatcherBase` — extendable base class implementing `dispatch(meta, args)` + timestamp/level prefixing; override via\n  `formatArg`\n- `format(spec: {type, value, ...})` — the text pretty-printer (handles circulars, Errors, Maps, etc.)\n- `getType(value)` — returns `ArgumentType` discriminant for any JS value\n- `toJSONValue(value)` — converts any value to a JSON-legal tree (Errors → {name,message,stack[]}, etc.)\n- `redact(value, regexp?)` — recursively redacts strings by content match and object/map values by key match (used internally by the redact feature)\n- `DefaultRedactRegExp` — built-in regexp matching common sensitive keys and value patterns (password, token, email, ssn, jwt, cc, etc.)\n- `Dispatcher` — interface for raw custom dispatchers (`dispatch(meta, args): void`)\n- `HaluaLogger` — the logger instance interface (`HaluaLogger<ErrorMeta, Caps>`)\n- `HaluaBuilder` — fluent builder returned by `createHalua()`\n- `Feature` — `{ apply(host), contributeDispatchers?() }` used by `.use()`\n- `SpanFlowApi` / `CaptureApi` / `CapturedRecord` — feature method and record types\n- `ConsoleLike` — minimal `{ debug, info, warn, error }` shape accepted by `NewConsoleDispatcher` / `NewConsoleColoredDispatcher`\n\n### Logger Instance Methods\n\n| Method                                                        | Description                                                                                                                                                                                                                                                                   |\n| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `.create(dispatcher?, options?)`                              | Create a new independent logger (inherits dispatchers/options when partial)                                                                                                                                                                                                   |\n| `.child(...args)`                                             | Create child logger that appends context to every message                                                                                                                                                                                                                     |\n| `.flow(name, ctx?)`                                           | `spanFlow()` (on by default): child marked `flow <name>` plus flattened `ctx` pairs. Does not emit a line                                                                                                                                                                     |\n| `.span(label, fn?)`                                           | `spanFlow()` (on by default): `start`/`done` `{ span, elapsedMs }` on a `span <label>` child; callback form rethrows after `.error` / `never-happen`. Ender form `() => number`                                                                                               |\n| `.collect()` / `.clear()`                                     | `capture()` only: copy or empty the shared raw-record buffer                                                                                                                                                                                                                  |\n| `.setDispatchers(dispatcher \\| dispatchers[])`                | Replace all dispatchers                                                                                                                                                                                                                                                       |\n| `.appendDispatchers(...)`                                     | Add more dispatchers to existing set                                                                                                                                                                                                                                          |\n| `.logTo(level, ...args)`                                      | Log at a custom / minor level                                                                                                                                                                                                                                                 |\n| `.trace / .debug / .info / .warn / .notice / .fatal(...args)` | Standard levels (varargs)                                                                                                                                                                                                                                                     |\n| `.error(error, meta?)`                                        | Log at ERROR level; first arg (unknown) is normalized to Error; optional `meta?: ErrorMeta` (generic on the logger instance) — when supplied, the normalized Error instance is auto-attached under `error` key and the augmented object becomes the second arg to dispatchers |\n| `.assert(condition, error, meta?)`                            | Log at ERROR only on falsy condition; same error + optional `meta?: ErrorMeta` semantics as `.error` (auto-attaches normalized Error under `error` when meta supplied)                                                                                                        |\n| `.stamp(label, id?)`                                          | Start high-res perf timer (`performance.now`); returns ender `() => number` (raw elapsed ms); optional id for `.stampEnd`                                                                                                                                                     |\n| `.stampEnd(id)`                                               | End named stamp started with same id on this logger; logs pretty `label took X.XXms`; returns elapsed ms or `undefined` if unknown                                                                                                                                            |\n\nEvery method returns a new `HaluaLogger` when using `.create` / `.child`, so they are fully chainable.\n\n`setDispatchers` and `appendDispatchers` mutate the dispatcher list on the **live instance only**. They do not update the blueprint used by later `.create(...)` or `.child(...)` calls on that same logger (those continue to inherit the dispatchers that were supplied when the logger was originally built). If you need a fresh logger with the new set, call `halua.create(newDispatchers)` (or the mutated logger's `.create(newDispatchers)`).\n\n## Error Handling\n\nHalua never throws from logging calls. If a dispatcher fails, the error is reported via `console.error` (best-effort)\nand logging continues for other dispatchers.\n\n### Using `errorMeta` with error trackers (Sentry, Rollbar, etc.)\n\nThe special `.error(unknown, meta?)` and `.assert(condition, unknown, meta?)` methods accept an optional second `meta`\nobject. When you use a custom `send` callback with `NewTextDispatcher` (or `NewJSONDispatcher`), this `meta` is\ndelivered as the **second argument** to your send function.\n\nHalua automatically appends the _normalized Error instance_ (the same one passed to the primary log args) under the\n`error` key of the meta object. This makes it trivial to forward the live `Error` (including `.cause`, custom props,\nand accurate stack) to error trackers instead of a string or plain-object snapshot.\n\nThis is ideal for attaching correlation IDs, issue keys, user context, or routing hints to your error reporting service\nwithout polluting the normal log arguments.\n\n```ts\nimport * as Sentry from \"@sentry/node\"\nimport { halua, NewTextDispatcher } from \"halua\"\n\n// Human-readable logs via TextDispatcher, while still forwarding\n// rich errorMeta (issueKey, etc.) to your error tracker.\nlet errorSink = NewTextDispatcher((line, errorMeta) => {\n    if (errorMeta?.issueKey) {\n        const err = errorMeta.error\n        // Destructure to omit the Error from `extra` (Sentry serializes it nicely on its own)\n        const { error: _err, ...context } = errorMeta\n        if (err instanceof Error) {\n            Sentry.captureException(err, {\n                level: \"error\",\n                tags: {\n                    issueKey: errorMeta.issueKey,\n                    component: errorMeta.component,\n                },\n                extra: context,\n            })\n        } else {\n            Sentry.captureMessage(line, { extra: context })\n        }\n    } else {\n        // Fallback: still surface the error even without extra context\n        Sentry.captureMessage(line, \"error\")\n    }\n})\n\nlet logger = halua.create(errorSink, { level: \"WARN\" })\n\n// Normal log — no meta attached (Note that .error will serialize passed string to Error)\nlogger.error(\"something odd happened\")\n\n// Critical path with traceable issue key — when you supply the second meta arg to .error or .assert,\n// Halua auto-appends the normalized Error under `errorMeta.error` (in addition to your fields).\n// The formatted line stays clean; your send fn receives the live Error + context for captureException.\nlogger.error(new Error(\"Payment declined\"), {\n    issueKey: \"PAY-48291\",\n    userId: 8472,\n    component: \"checkout\",\n    requestId: \"req_abc123\",\n})\n```\n\nThe user-supplied portion of `meta` is never mixed into the formatted `args` (exception: ConsoleDispatcher) — it (plus the auto-attached `error`) is always available as a clean second parameter to your send function.\nWhen meta is absent, the second argument is `undefined`.\n\n## Advanced / Custom Dispatchers\n\nFor simple file (or any sink) logging the easiest approach is to use a built-in factory with your own send function:\n\n```ts\nimport { halua, NewTextDispatcher } from \"halua\"\nimport fs from \"node:fs\"\n\nlet logPath = \"app.log\"\n\nlet fileLogger = halua.create(\n    NewTextDispatcher((line) => {\n        fs.appendFileSync(logPath, line + \"\\n\")\n    }),\n)\n```\n\nIf you need full control (custom dispatch, different prefixing, rotation, binary framing, remote calls, etc.) extend `DispatcherBase` and use the exported `format` + `getType` (or `toJSONValue`) exactly as the built-ins do:\n\n```ts\nimport { halua, DispatcherBase, format, getType, toJSONValue } from \"halua\"\nimport fs from \"node:fs\"\n\nconst NewFileDispatcher = (filePath: string) => {\n    return () =>\n        new (class FileDispatcher extends DispatcherBase {\n            constructor() {\n                super((line) => {\n                    fs.appendFileSync(filePath, line + \"\\n\")\n                })\n                this.formatArg = (v) => format({ type: getType(v), value: v }, true)\n            }\n        })()\n}\n\nlet fileLogger = halua.create(NewFileDispatcher(\"app.log\"), { level: \"INFO\" })\nfileLogger.warn(\"something happened\", { user: 42 })\n```\n\nThe `Dispatcher` interface (`dispatch(meta, args)`) + `DispatcherBase` + `format`/`getType`/`toJSONValue` are the public\nextension surface. See `src/main/dispatchers/text-dispatcher.ts`, `json-dispatcher.ts` for reference implementations.\n\n**Semver note for custom dispatchers**: `Dispatcher`, `dispatch`, `DispatcherBase`, and the formatter trio are stable\nwithin a major version. Changes that would break existing custom `Dispatcher` implementations are released only as\nmajors and recorded in `docs/dr.md`.\n\nFor most use cases the three built-in dispatchers are sufficient.\n\n## TypeScript\n\nFull TypeScript support included. All types are exported.\n\n## License\n\nMIT © [inshinrei](https://github.com/inshinrei)\n\n---\n\n**See also:** [Tour of Halua](https://github.com/inshinrei/halua/blob/main/docs/tour-of-halua.md) for a narrative deep dive and decision records in `docs/dr.md`.\n","readmeFilename":"README.md"}