🚀 TwoFold v0.11
Whoa, I’m still on a high from releasing not one, but two new versions of TwoFold in the last three weeks! It’s been a wild ride, and I’m excited to share it with you.
Let’s dive into the chaos.
The biggest news is the arrival of addons - yes, I finally got around to implementing what I used to think it’s ‘plugins’ (I’ve been thinking about this since 2019, but it wasn’t the right time… or I just didn’t know where to stitch 'em).
The ignore functionality is now part of the ‘ignore addon’, and the consume tag functionality has moved to the ‘consume addon’. We also have a brand new experimental caching addon that’s perfect for HTTP request functions. Super excited about the flexibility this brings - we’re not just talking about caching JSON responses to avoid rate-limiting; we’re talking about full-fledged middlewares that can do some serious heavy lifting (check out the custom eval from the ‘protect’ feature for a mind-bender).
The documentation for addons is a bit lacking at the moment, but I will slowly add to it. Until then, feel free to check the source of the already implemented addons to understand how to use them.
Of course, with great power comes great breaking changes… The ‘ignore’ tag is now called ‘freeze’ to keep things consistent with the ‘freeze=true’ option (and it’s shorter, too). We’ve also got a new ‘protect’ tag that ensures a tag won’t be consumed by its parent + a ‘protect=true’ option, and a ‘freezeChildren=true’ option to run a tag without running its node children.
Another major update is the upgrade of set
, del
, json
, toml
, and import
tags from inside evaluate()
to regular tags. This is a huge deal - it means people can now implement their own versions of these tags and other data languages (JSON5, YAML, AML, ENO, REN, you name it).
I was able to make this happen by introducing a new type of tag: BFS (breadth-first order) tags. You see, the old tags were executed in a depth-first order (run all the children, then the parents, like functions in a regular programming language), but data tags need to be executed first, so I had to get creative. Now we’ve got BFS tags, and it’s a game-changer.
On the breaking changes front, I finally killed off JSON props in backticks. RIP. They’re now replaced by the more flexible React JSX curly braces {..}
props. I know I’ve broken JSON props a few times before, but this time it’s stable, final, and better than ever.
We’ve also got more exciting new features: the {..}
React JSX spread syntax and a new {..}
prop type, inspired by JSX curly braces. You can now expand and merge groups like g={...group1, ...group2, ...group3}
, and even explode groups as props inside regular tags or ‘set’ tags. And more, both {..}
prop type and backtick string props now allow newlines inside - a small but welcome change.
Other notable updates include the import
tag (EXPERIMENTAL because there are tricky edge cases when imports are importing imports that are importing more imports, so bear with me), the toml
tag, the del
tag, and the vars
tag to view selected variables.
Another new tag is weather
, also experimental, to fetch weather from WeatherAPI.com, OpenWeatherMap.org, or Open-Meteo.com. This tag requires the new caching addon, to make sure you don’t call the weather API too much.
Oh, and I created tons of new tests to make sure all this stuff works correctly.
You can check the changelog in the docs: https://github.com/ShinyTrinkets/twofold.ts/blob/main/docs/CHANGELOG.md
So, what’s next? Well, I’ve got plenty of ideas.
I need to polish the ‘import’ functionality, test the caching addon and, well, test more stuff in general. I’ve also got some TODO/IDEA/LINK tags to implement, I need to tweak the AI tag to be smarter about finding the local inference provider port. And, you know, maybe play with long context memory management for long AI chat sessions… unless I get distracted by something shinier, that is.