I guess the UX of the generate feature could be better (or at least I need to add some help/explanation info there). You don't have to navigate to the link and use the interface that shows up there, it's more like for fine-tuning the program, but it's optional. You can just download the Liftosaur app, and import the generated link there, and then do exactly as you said - recording the lifts that you initially described in the Planner.
IMHO there's a lot of similarities in how we write software programs and weightlifting programs. In weightlifting, we also use specific syntax to describe our workouts - like sets by reps (3x8), how close we are to failure (Rate of Perceived Exertion - RPE), percentages of Reps Max, etc.
I thought it'd make sense to formalize the syntax for weightlifting programs, and then we could build a code editor, an IDE for weightlifting programs. It would autocomplete the exercises and the syntax, show errors and highlight syntax.
And also, it'd show important properties of a program in real time. Like, what's the weekly volume per muscle group, how many days per week you hit specific muscle groups, what's the proportion of strength vs hypertrophy sets, push vs pull sets, upper vs lower sets. It'd show the graph of weekly undulation in volume and instensity per exercise when you plan multi-week programs, so you can manage your fatigue over time. And it'll show approximately how long the workout would take, so you can balance the time you spend in gym.
So, "Liftosaur: Workout Planner" is kinda an IDE for the weightlifting programs. You write workouts in plain text, using special syntax. Because it's just text, you can tweak it very quickly and easily - select, copy-paste, change, which makes it easy and fast to write the programs. It supports:
- RPE (e.g. @8 - meaning it's 8 RPE - about 2 reps til failure)
- Percentages of 1RM - 1 rep max (e.g. 65%)
- If you omit weight, it'll try to come up with proper weight for you based on percentage of 1 rep max, using RPE tables. E.g. if you write `Bench Press / 3x8 @8`, it knows that generally people can do 8 reps at @8 RPE with 70% of 1RM.
- Custom rest times per exercise
E.g. example of the programs would be:
```
// 4 sets of 6 reps with 65% of 1 rep max, last set is As Many Reps As Possible
Squat / 3x6 65%, 6+ 65%
// 3 sets of 12 reps at 6 RPE
Romanian Deadlift, barbell / 3x12 @6
// 2 sets of 12-15 reps, rest timer 90s
Bent Over Row / 2x12-15 90s
```
You can also specify progressive overload, like:
```
// Linear Progression: increase by 5lb each successful workout
Squat / 3x6 65%, 6+ 65% / progress: lp(5lb)
```
And finally, you can convert the program you built into a Liftosaur app program (it's a weightlifting progress tracker), then import it there, and run it in an app while you're in gym. It'll take into account progressive overload too, and will change the weights, reps and sets oveer time how you defined.
But I'm frankly not super familiar with FDroid and alternative stores, and have no idea how hard or easy to distribute it there. The main benefit is that'd be available for devices without Google services, right? Or something else?
Thanks for the feedback! Yeah, that's a valid point. You can probably right now look at built-in programs for examples, or check the docs on the site: https://www.liftosaur.com/docs/docs.html. Hopefully that helps!
If it works, this is awesome. I've used it before to add my PWA (liftosaur.com) to the Android store, and it's way easier to get users from there, than to explain them how to install PWA. Will try it out for iOS definitely.
Just built "yatro" last weekend - TypeScript's actually typesafe router. I wanted a framework-agnostic router, that would actually be typesafe - it'd match the request with specified routes where path and querystring parameters' types are descdribed, and provided properly typed extracted parameters. Couldn't find anything like that in npm.
Pros of Cloudflare Workers - they're way simpler. Their docs are nice, it's straightforward to set up a dev environment for them, it's easy to set up a key-value store for them (Cloudflare KV), secrets management is simple. Pricing is nice - it's flat $5 a month, and you get access to almost all of it. It works fast and distributed across the whole world, admin console is nicely integrated with the Cloudflare CDN dashboard.
But they're too limiting. Cloudflare Worker should be a pure JS script (that looks like a service worker script in a browser). You cannot use any Node libraries. In my app I need to generate images on the fly, so I couldn't figure out how to do that in a Cloudflare worker, so I ended up creating lambdas for those, and proxying the calls from Cloudflare worker to those lambdas.
KV (their key-value store) is way too simple. No secondary indexes, no sorting, no querying (you can only sorta query list of keys, but then you have to fetch a record by each key individually). My app hit the limits of KV very quickly.
Also, there's no monitoring or any good way to do backups for KV. So, it's almost unusable in a real-world production system, except as maybe a cache layer.
Monitoring was a big pain for Cloudflare Workers. Like, even accessing production logs is weird - you have to "tail" them from your CLI. Even Cloudwatch is 100x better here.
Development environment is okay, I guess, but the local server crashes constantly. Also, it kinda forces you to use Webpack and bundle the sources. It also doesn't have anything like layers in AWS lambdas, and they have a limit of 1MB for a bundle, which I almost hit (I had like a 900kb JS file), so that part got me worried too.
Basically all of that made me worry I will hit a wall soon with Cloudflare Workers, so I moved to AWS. It's not piece of cake too, but at least I get a way to run proper Node scripts, a decent document database, continuous backups and pretty good monitoring out of the box.
I recently migrated from Cloudflare Workers to AWS Lambda + Dynamo for my relatively large pet project.
It was surprisingly hard - the local development of lambdas is still very raw, documentation is scarce, and there are various small issues appearing here and there. I should probably write a blogpost about how to setup decent developer environment for AWS CDK and Lambdas, because there's not much on the Internet about it.
I set up the whole AWS infrastructure via AWS CDK. I have one TypeScript file, that creates a stack with lambdas, dynamodb tables, API gateways, S3 buckets, wires up the secrets manager, etc - all of that in 2 environments - dev and prod.
AWS CLI also can generate a Cloudformation YAML file from the CDK file (via `cdk synth`), which could be fed into SAM. So, I generate a `template.yaml` Cloudformation file this way, then run SAM like `sam local start-api`, and it runs exactly the same lambda locally, as in AWS, using that Cloudformation YAML file. SAM also supports live reload, so if you change any source files, it will automatically get those changes.
So, okay-ish developer experience for lambdas is possible. There're caveats though:
* I couldn't figure out how to use "nameless" Dynamodb tables (i.e. when CDK assigns the name to them automatically), because if I omit a table name in CDK template, then the local lambda and lambda in AWS assume different names for some reason.
* Locally, the binary outputs don't work. It ignores `isBase64Encoded` by some reason, and lambda just returns Base64 output, instead of binary.
* And the main problem - local lambdas are SLOW. It seems like it restarts some container or something under the hood on each API call, which adds 2-3 seconds to each API call. So, the calls that should be like 30ms, are actually 2 seconds now. This is super frustrating.
I switched my pet project (about 15000 lines of code) from Webpack to esbuild, and reduced the build time from 30 seconds to 2 seconds.
The trickiest part was to make Tailwind CSS work. I used to do that via postcss plugin, but just running that plugin even without Webpack takes 15 seconds. Finally, with some modifications in my CSS I made it work, and purged the unused styles just by using PurgeCSS API manually.
The setup got a bit hairier than with Webpack, but it builds damn fast now.
I made a free PWA phone app for tracking weightlifting progress - Liftosaur. Yup, like thousands of other weightlifting tracker apps, but mine has one unique feature - you can write code right in the app!
It has a powerful exercise editor, where you can define the logic for progressions and deloads using built-in scripting language Liftoscript. Like, you can express that after 3 successful Squat sets you want to increase the weight by 5lb, or decrease weight if you didn’t hit 12 reps total, or anything like that.
It also has all those features all other weightlifting trackers have - rest timers, plate calculator, history editing, cloud storage, progress graphs, etc, etc.
You don’t have to be weightlifting expert to use it though. It contains a bunch of prebuilt programs (built by using the same built-in scripting language Liftoscript) from https://thefitness.wiki - IMHO the best starting guide for those who wants to get into weightlifting. So, you could start with “Basic Beginner” routine, and after 3 months of running it switch to GZCLP or 5/3/1 For Beginners. All you need is to read about the program in the wiki, and then just do whatever app tells you to do, it will handle progressions and deloads properly for you.
There're a lot of apps that are either focused on one weightlifting routine (like 5x5 StrongLifts or Five3One) - they do nice job leading you through the routine, but if you want to try another one, you basically need another app. And if you want to create a custom routine, you're out of luck. There're also generic ones, like Strong or Jefit, but it's hard to make them follow some specific routine, increasing and decreasing weights automatically, changing exercises when necessary, etc.
I thought - how hard would it be to create a platform, that'd support many routines, and you'd choose any, and have a consistent UI across them you got used to?
Another thing I wanted to see - how hard it is to create a PWA app that is nice to use, and what features are still lacking there (compared to native experience).
The app is already in a usable shape, I use it 3 times a week, though it only has one working routine now. It's written in Preact/Redux/TypeScript.
It's a surprisingly pleasant experience to have a personal project like that, and slowly build it in your own pace, working on features you care, that would actually help you in your workouts. I found myself sometimes working on it til late night, being in that "flow", like in the beginning of my career, having so much fun, and returning back the joy of coding!
Remember, you need to get another immutable map, which is a modified version of the original, preferably memory-efficient, which means we want to reuse the unchanged keys/values of the original map.
1, 3 - you can crop and zoom the photos by clicking on them right on the page. You can also swap the photos by dragging them, and change layouts by clicking to the "Change Layout" button.