Hey yโall sorry itโs been a minute. My last retrospective was in September. I had a couple of weeks where I didnโt really have a muse for writing, then I had an all out dash from 10/12 - 10/20 of doing the PDS MOOver: The Next Generation update, where I did write up some about it, but no retrospective. Then last week I mostly rested and didnโt look at any code for a while. Well, now Iโm back. The plan this week is to work on PDS MOOver again.
I'm writing this intro on October 26th and going to roughly layout my goals for the week, it will be fun to see how they change
Move all the migration, plc, backup, etc logic code into a node module so I can publish it for others to create their own ui's for PDS migrations
Change the automated backups from every 24hrs to every 6hrs
general clean up
May only care about certain things. So this is a bit of a guide on which days I talk about what if you wanted to skim to those parts (it was actually just all PDS MOOver this week, but you gotta keep a format)
๐ฎ MOOve to SvelteKit - All week
๐ฆ npm module - All week
Sunday, October 26th, 2025
I played video games all weekend. It was wonderful. I've been pretty hooked on Plan B: Terraform on steam lately. It also helps that lately I've been reading the Mars Trilogy, which without spoiling too much have similar plots ๐
Monday, October 27th, 2025
askama, axum, alpine.js
So. Yeah. I went to add OAuth to the backups page and just kind of looked at the code and said WTF.
A bit of background, the ordinal PDS MOOver was just a index.html and some js attached using vite. The frontend was in alpine.js, which worked great. I like alpine.js, simple and lets you add in a sprinkle of reactivity here and there on your frontend. So with PDS MOOver going to a full backend I thought server side rendering of pages and alpine.js would be the move since it would strengthen the weak spots of the previous setup. Lack of routing, can have different pages easier, etc. Well it does, but the developer experience sucks. I'm just going make a bullet list of what I ran into.
askama is fantastic for what it is, but I can never get syntax highlighting work in anything I try and it just makes me feel like I'm writing PHP in Dreamweaver again (great crate and checks every other box tho)
Before when working with just plain html I had helpers for things like
x-show="someValue"and I could click thesomeValueand see it in my script tag have code completion all that great stuff. Doesn't like theaskama.htmltemplates and broke all the IDE helpers for syntax.Lack of components you can load in with alpine.js really left me with two choices for breaking up long pages. askama partials or a lot of
x-show.ehh....Had to switch to using
build:watchon js changes andcargo watchon axum, combined with a page refresh and about 3 seconds of turn around, it was not ideal to see changes and was a bad workflow
All of those points combined I really wasn't doing "Keep It Simple Software" like I had said in a previous retrospective. With new features being added, bad developer experience It just felt like It was becoming instant legacy code.
SvelteKit
I kind of been having my eye on Svelte lately. Especially thanks to doing the dashboard for selfhosted.social forked from scientific-witchery/pds-dash. Everyone knows the best way to make a decision is to flip a coin, but I went with the second best for this. A pro/con list. (actually it's easier to explain to others on paper than flipping a coin, and probably not best to leave technical decisions to the heart)
Pros
Being a full fledged framework I have better control over components, rendering them, routes. etc. It lets me write code that is easier to read
My tools just work. RustRover, vite, etc. It all worked and I had syntax highlighting again which is huge for me
I was doing some weird
Window.JSClassNameloading before, can write cleaner code there as well nowEverything with the backend is already an XRPC service so no logic change there.
Can allow more people to jump in and do contributions since it is not a cursed dev setup
Cons
It is a rewrite, and that takes time that I could spend else where
Using SvelteKit it will most likely be another docker container in production, meaning I'll probably have to get semi creative with Caddy in front of the XRPC service and the new container running the new UI
I don't actually know svelte
I haven't regret the move to Svelte yet. It's still early in the rewrite of the UI, but there's not a ton of UI code thankfully, just hide this, show that. Taking a bit, but I think in the long run it's going to be the best move since I have some other plans for PDS MOOver
Tuesday, October 28th, 2025
PDS MOOver in Svelte
You could say things are really mooving along. I think I got a working knowledge of sveltekit down. So far I have moved the main MOOver page (normal migrations) over and everything seems to be working pretty well. It was also my first test to see if I can divide up some of the code. I moved the "Sign the papers"(PLC Operation) to it's own component and it has helped a lot with readability of the code.The {#if blah } syntax is also starting to grow on me. Makes it much easier to read.
Top form is collapsed in both and still in the parent component, but this should show it pretty well what I mean. What it was before
What it is now
I also moved the Rotation Key display to a svelte component and got rid of an awful window.handle  I was using to share state between two askama partials since now I can just pass it down to a partial easily. So yay no more weird global variable
PDS MOOver: The library
The current thinking now is to do a release of PDS MOOver 1:1 with the current version, but in SvelteKit, and a release of the node module(package? Library? Thingie ma bob?). Since this is the bulk of the logic I am leaving it in JS for now since I know it works instead of going to TypeScript, but I did go through and add types to it and working on the JSDocs for it as well. Not much to say there other than this is my first attempt at a true node module with the intent to release, so has been interesting to learn how to work with it. The workflow I have is a bit awkward, but it's working.
1. In my svelte project I have it imported as "@pds-moover/moover": "file:../packages/moover" 
2. run a npm run build for vite to build out the library.
3. run a npm run gen:types (tsc -p) to create the type files
4. run a npm install on the svelte project
And I got the changes. It feels a bit awkward, and I think there is probably a better way. But not a ton of changes and it is working so far.
Wednesday, October 29th, 2025
PDS MOOver in Svelte
It's still going. I moved the missing tool over and so far so good.I'm feeling that the code is a bit cleaner and easier to read. Before I had two different forms for the current login and old login, I was able to combine those into one form.
I also got the Turn Off tool ported over, it's the one that helps deactivate your old account if it was left activated for some reason. Which happens a surprising amount.
PDS MOOver: The library
There was a lot more work on this front today. I wrapped up all the JSDoc's so it should be pretty well documented to help others out. I also got the the lexicons uploaded to npm at @pds-moover/lexicons. I'm thinking the current version of @pds-moover/moover is probably going to be the 1.0.0, but I'm holding off till the rewrite of PDS MOOver is completed to make sure there are no bugs.
I also played around a bit with @atpkgs.easrng.net which I think I am also going to upload the modules to. Which they're acutally already there, just you won't know that till this blog is out ๐
Thursday, October 30th, 2025
PDS MOOver: The library
As I was building out the new PDS MOOVer UI I realized things like the did:web, plc directory, and PDS MOOver host were a bit awkward to set. So I made sure to add constructors for that. So no matter the flavor of atproto you're making a PDS migration tool for, PDS MOOver should work for you.
PDS MOOver in Svelte
You'll be surprise to know. It's still going. I think I have all the tools ported over now. I just need to run through testing them all again, which takes a long time. Then onto DevOps, which I am hoping to get to tonight or tomorrow-ish. I will have to get a new container going for the new Svelte assets, probably going just rock a node server incase I ever need the backend. Then Caddy to tie it in with XRPC service all on pdsmoover.com
I do have a good example of how Svelte is making it easier for me to make a better tool. I found a bug on the restore where if the user has a HEX based rotation key (I've actually only ever seen these in use on the pds.env file) it would load it in and not work if it was a secp256k1 key, which is what I've seen all the pds.env rotation keys in. With Multibase you can automatically pick out automatically which one it is, and the library I wrote did use that. But with HEX base you have to specify. 
So thanks to svelte being a bit easier to work with I added in where if the key is detected to be in HEX format to prompt the user for the type. Small little feature, but a great example of showing what Svelte will let me do else where with the UI easier.
Halloween ๐, 2025
It's Halloween! Mostly doing some final testing on the recovery/restore process. I've also reworked the advance options a bit.
I wanted to match a bit more of what the migration does for advance options. The "Recover the did doc & account." will attempt to change the did doc to a temp one with a new verification key to be able to create a new account on the new PDS with the user's did, then signs it over to the recommended one from the PDS along with the user's rotation key. "Restore files from backup" Will restore the repo and blobs from the back up taken on PDS MOOver. Ideally this should make it a bit easier for users to run each individual option and rerun the restore if it is needed, like missed blobs.
What's Halloween without something a bit scary? Well in my testing I was wanting to use the HEX base keys from the pds.env to make sure that works as expected since that is a very possible scenario. Well, I accidentally signed a did doc with a HEX key that was to a PDS with the same rotation key which led me to find out that the PLC is 100% fine with that, but other tooling is not. The first tip off was on pdsls.
And then on boat when I tried to manually fix the document
So that was a bit spooky. But something I am glad to find in testing. I made sure to add client side checking on that.
Saturday, November 1st, 2025
Got a late start on everything today, I mostly worked on devops and did some bug patching here and there. I did have a time trying to get a new docker container to build using npm. Ended up just switching the container build for the new front end to use pnpm, problem solved!
Sunday, November 2nd, 2025
It's here! Release day. I did some final testing today and the actual release. Here's what all changed
New Features:
Moved backups from every 24hrs to every 6hrs
The front end is now in SvelteKit
All the atproto logic is powered by the new @pds-moover/moover node package allowing other developers to create their own PDS MOOver
Options on restore page allowing you to do just the PLC operations or restore from a backup
Added a new VerifyBackups command for the admin tool allowing me to verify backups are there for the whole server
Disable buttons and added loading spinners in a few places when doing an action
Bug fixes
Fixed a bug on restore where when using a HEX format key it would not always pick the proper type. This is now radio button if you enter a hex key
Added a check on restore to check for duplicate rotation keys on the edge case you are restoring an account to a PDS with the same rotation key
Fixed an issue where when recording a repo in the database it would count it multiple times resulting in showing backup size for the server and repos wrong, along with blob counts
Fixed a edge case when recording blobs it could miss blobs for a user if there was already a blob backed up with the same cid
Next I'm planning on building out a dedicated migration page with the new node library for selfhosted.social, work on adding a new gatekept route on PDS Gatekeeper to block creating new accounts unless it is a migrations. Then back to PDS MOOver to rework the backups screen with OAuth login for sign ups and checking your stats.