A utilitarian web framework with refreshing state management.
mail.hackclub.com uses this! take a look at theseus package.json...
3rr0rc0d3z3r0
Whoops! Looks like they don't have a project yet. Maybe ask them to start one?
dave9123
Check their projects out: Recall Me, InstaQuote, Lenie
Neon
Check their projects out: Annoy Lou, Slack zeon, Ntfy w/ som, Summer of making Share votes, @grok is this true, ruby scrapes a book site, SoM userscript, Shipwrecked random phone number, Washing machine updates
nora
Check their projects out: Theseus, Summer of Making
hellonearth311
Check their projects out: PlasticTax, Recycle.AI, SDL2 Tower Defense, Brainwave, WinStatz, Statz, APODPaper, Echoes of the Void, Copper Rails, IPSeeYou
Rowan
Whoops! Looks like they don't have a project yet. Maybe ask them to start one?
Once you ship this you can't edit the description of the project, but you'll be able to add more devlogs and re-ship it as you add new features!
Nevermind, I'm redesigning the frontpage again. It's pretty much a wall of text right now so I'm adding smaller headers + more examples/visuals.
Hopefully last devlog before shipping: dreamland.js.org and the GitHub now point to dreamland v2! I've spent 105h on this project across Journey v1, Journey v2, and Summer of Making. It's now my top hackatime project too.
Added a browser support disclaimer (dreamland supports major browsers that support :where()
) and set up ESLint (it doesn't want to warn about new JS features like Array.prototype.at
for some reason though).
Moved component state hydration earlier in the hydration process for non-data components, fixed mobile docs CSS by adding a menu button
Tested out and added docs for pure js (no bundler - this needs an importmap), and fixed hybrid ssr.
Speedran creating a web IDE playground that uses Monaco + rollup to edit and bundle JSX to run in an iframe. Took a lot longer last time I did it in Journey v1, mostly because I was debugging the typescript worker. Now I know what to do first try.
Fixed hydrating state so that my fancy rich image for Crab Rave in the SoM Grand Expedition wouldn't shift around on hydration. Also optimized it for size by removing the object wrapper and string type in SsrValue
.
Attepted to get 100s on lighthouse for the docs site, but turns out lighthouse really doesn't like the color choice (it passes according to the rest of devtools).
Temporary deployment of the site is available at https://dl.r58playz.dev/ !
Finished the intro docs! Also added a manual order to the metadata of the docs pages so it isn't sorted alphabetically anymore.
Finished the CSS for the docs site, now just the content of the docs is left. It'll probably need a playground as well, which ideally would be split into a different bundle so that rollup/monaco aren't loaded when opening the frontpage or docs.
Added syntax highlighting to the site. This required yet another custom plugin because for some reason @mdx-js/mdx
doesn't support using class
as a JSX prop instead of className
.
Used the MDX integration to flesh out the frontpage. The frontpage's content is now in MDX while the sidebar is in JSX. I still need to tweak the content and add syntax highlighting but this looks pretty good!
Implemented SSRing and hydrating MDX for the docs site!
As a result, I did a TON of SSR fixes, and implemented pruning SSR data for elements and components not in the SSR dom tree.
The pruning helps remove SSR data for other routes, since all routes are constructed during router creation BTW. We may want to change this later but for now it’s like this since the original dreamland 1 router did this. It also makes sense for the current state management style I think
Integrated SSG support with dreamland/router
. This is turning into a pretty good template project, time to build my personal website from scratch with it!
Fixed the rest of the SSR bugs. Also rewrote state serialization to have lookup tables for keys/values, drastically reducing the SSR state size. Then I added comment/text node tracking which increased the SSR state size by like 33%, but it fixed m3-dreamland.
1 month later...
Locked in and fixed SSR's bitrot! I now have it mostly-working with m3-dreamland. The only bug is something to do with dynamic text nodes not being hydrated correctly.
Added hybrid SSR finally! It's basically a replacement of Turbo Controllers with dreamland components. You get all the benefits of dreamland state management/reactivity while still being able to use rails/etc.
Added a backdoor to the JSX factory to allow for JSX data components and changed the dreamland router syntax to use those for route definitions.
Cleaned up a hackfix velzie made after I procrastinated on an actual fix. Also fixed use(a, b, c)
and cleaned up code that had to handle Pointer<T> | T
, saving a ton of bytes. (totally not procrastinating on hybrid ssr)
Implemented style object syntax (style={{ backgroundColor: "red" }}
) and cleaned up the SSR bundle.
Started learning rails for dreamland 2 hybrid SSR (effectively sponsored by nora btw go check nora-changelog's threads). So far I'm thinking of a phlex component subclass that automagically serializes any whitelisted state and attaches a unique ID, then the dreamland component can target selectors to attach events or clientside components to.
Also cleaned up the store code to save like 360 bytes and push dreamland/core under 8000b.
Hydration is now fully working! I refactored the JSX factory to remove the dlarr code and saved 205 bytes in the process, mounted comments from the SSR tree to fix the new dynamic pointer code, and removed dl-ssr-css-id to bring down the overhead from 50+% to ~20%.
Basic SSR is now working! It now uses the JSX factory element construction order to match up SSR'd elements immediately when hydrating instead of waiting until the whole tree is constructed. The SSR'd tree is now very bloated with duplicated info however, but that can be fixed later. Also the dlarr code is broken but I think I'll completely replace that soon.
Worked on component state serialization for SSR. Now component state is sent to the client as a dlcss ID to JSON map in a script tag alongside the rewritten CSS. I can then parse the JSON and apply the state to the components being hydrated. Next step is to actually implement the clientside SSR lib for hydration.
Started the serverside SSR implementation! The render function returns a domhandler element for the component and an array of elements that need to be put in the document head which the user can append to a dom of the whole page and serialize to HTML.
I'm currently testing the code in the CSS test project I made in Journey v2, so it isn't actually running in node yet but I'm not using dom types so it should work fine.
Told copilot to write a hydrate function for SSR to laugh at it and it wrote 45% useless code, 45% copied code, and 10% partially useful code. Check it out at https://github.com/MercuryWorkshop/dreamlandjs/pull/14.
Anyway, I started SSR support by moving all DOM references into a separate file that exports them so that SSR plugins can override it. I think I have a plan for SSR now:
- Server overrides DOM to jsdom or similar for export to string, calls the server side init function
- Once on client, hydration overrides DOM to a fake version to match up elements with the server side tree and sets state (idk how I'll transfer over state I haven't decided that yet)
I need to figure out how to make deterministic CSS class names for the CSS-in-JS system first probably though
Tried to find a good bundle size visualizer library and eventually settled on rollup-plugin-visualizer
in sourcemap mode. Also refactored the rollup config a bit to make it cleaner.
Did a ton of code golfing to reduce the (uncompressed) size down to below dreamland 1. dreamland 1 still has a better compressed size, which I think is because of the CSS selector parser using regex which is bad for compression.
brotli: 3480B dl2 after, 3598B dl2 before, 3306B dl1
gzip: 3826B dl2 after, 3951B dl2 before, 3656B dl1
btw, preact is all the way at 11195B. imagine using react
Attempted class components again, but it turns out there's no way to dynamically add typed properties to a class so the typescript looks very forced and bad. Reverted it and will move on to SSR now
Refactored the state system to make it cleaner and less buggy. Also cleaned up the array child case in the JSX factory to use more builtin array operations.
I was going to post this devlog earlier, but I locked myself out of my projects (page 500ing) with invalid comment data.
Apparently .class::before:where(...)
is invalid CSS, so I added a case for that in the CSS rewriter. Also messed with the component type some more, so that you can pass in pointers to any prop no matter what.
Try it out at https://dl.r58playz.dev/playground !