Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: created capsules system and rewrote just about everything (#224)
* feat: created `Capsule` and capsules dummy example That example will evolve substantially over the course of building this feature. * revert: "feat: created `Capsule` and capsules dummy example" This is intended to allow a clean merge from `main`, after which these changes will be re-implemented. This reverts commit 5f592b3. * feat: completely redesigned engine-side perseus This introduces `Turbine`, which replaces all build, export, error page export, tinker, and serving logic. Capsules have been introduced as an integral part of these new processes. This is *extremely* messy right now! (But the core compiles on the engine-side!) * refactor: removed template addition plugin actions * feat: made axum integration work with turbines It and the core now compile (not for the browser-side yet though). This also brings nearly all the server-side logic into the core, which should make authoring future integrations a trivial matter of just extracting the correct data. This currently uses a deliberate memory leak to get a `&'static Turbine` to avoid the use of an `Arc`. So far, I see no issues with this, since it only happens once, but this API may change to an `Arc`. * feat: made `perseus-actix-web` compile This also reduces the Actix Web and Axum integrations to single files, in a universalized format that will be soon documented. Integrations should be as simple as possible. * feat: made all server integrations compile They are now all single-file (except for one extra handler Warp needs), structured, and using the new turbine system. (I'll bet they're a lot faster to, since only Warp needs one `Arc`). * feat(wip): progress on browser-side systems * feat(wip): further progress on browser-side systems * feat: created `Reactor` system Still a work-in-progress, but this will make the browser-side much more maintainable! * refactor: cleaned up some things and improved type bounds * feat: made view functions fallible This makes error handling *much* cleaner, and removes a very large number of panics that hypothetically wouldn't have been executed on the browser-side, but the invariants were not rigorously guaranteed. They now are, and errors are gracefully returned for handling. This involves *substantial* import restructuring, and a greater dependence on `perseus::prelude` for end users. * feat: created new error views mechanism This is nowhere near complete, and full of compilation errors, but we have the basics of a system! * feat: created crash handling mechanism This includes a crash plugin action. * feat: integrated error views with engine-side The engine-side now compiles. * fix: cleaned up browser-side and fixed hsr/live reloading Apart from 3 lifetime errors, the browser-side now compiles. That's down from 159... * fix: re-enabled hsr * feat: added disposers for error views and fixed browser-side For the first time in two weeks, the entire Perseus core, both engine-side and browser-side, actually compile!!! * style: ran `cargo fmt` * fix: fixed up `basic` example * fix: fixed entrypoint return types * feat: re-created subsequent load system in reactor * feat: created system to register initial wdiget states * feat: created system to register widget dependencies The browser-side widget component is also now ready (fetching not yet implemented). * fix: prevented exporting of widgets as initial load pages * feat: created new panic handling system This will allow both arbitrary executions (e.g. crash reports) and the rendering of a proper popup message. * feat: overhauled state generator error handling Custom error types are now fully permissible. I still want to make infallible ones more ergonomic though. * feat: improved ergonomics of state generation error handling Infallible functions can now directly return their value, while those that are fallible can return a `Result`. This allows errors in things like head/header generation, without sacrificing the ergonomics of infallible functions. This same change is *not* feasible with suspense, since the return types must necessarily be known ahead of time. * feat: set up proper widget error handling * fix: target-gated ergonomic error handling system * feat: created full fetching logic for widgets Delayed widgets are not yet implemented, but they can share extremely similar logic. * feat: created delayed widgets These just don't exist on the engine-side for rendering, and they'll be resolved on the browser-side only. * feat: made templates with state work without macros! This involves some serious GAT/HRTB magic, and I don't fully understand *why* this compiles yet, but it does. Tradeoffs are that the state type does have to be manually specified, and a `BoundedScope<'a, 'b>` is needed in the user's function signature, which isn't great, but it's alright, and that can be explained to them with documentation. I want to try to remove the requirement to specify the state type... * fix: made basic example compile again * fix: fixed simple server issues An `Rc` count invariant was not upheld, global state should never have been passed to engine-side error handlers, and there was a typo in the head fetching code in the server. Wasm is still broken. * fix: fixed hydration errors Error views are now barred from hydrating. * fix: added `Content-Type` header handling This is done *in the Perseus core*, meaning server integrations no longer have to worry about this! Note that I have allowed the user to override the content type in initial loads, which may be a good idea in some cases?? * refactor: cleaned up This is just a huge amount of target-gating, and some very minor fixes. * refactor: appeased `clippy` in `packages/perseus` This hadn't been done for quite a long time... * refactor: deleted old code These were the files that have been turned into the `Reactor` and `Turbine` now. * fix: fixed examples (mostly) - Still need a preload method on the reactor - Any pages rendering only one element aren't getting a closing tag for some reason, which is breaking hydration - Exporting is broken * fix: fixed exporting The issue was in the inbuilt server, which runs error page exporting automatically, which wasn't doing a ppost-build population. * style: ran `cargo fmt` * fix: fixed some hydration/minifcation issues Still one problem: any pages rendering only one node lead to a hydration error... * feat: made `Template`/`Capsule` wrappers over smart pointers This removes the very unergonomic `TemplateMap`/`ArcTemplateMap` setup, and makes everything more logical by centering around `Entity<G>`, which can represent either a template or a capsule. This will enable user cloning of `Capsule`s to be used as actual Sycamore components. * feat: added convenience preloading methods on `Reactor` * feat: made global state support full reference passing around This uses `create_ref` under the hood to make the entire global state able to be passed around freely. (This may change soon though to be more ergonomic...) * feat: restructed reference reactive state This changes the use of `&'a RcSignal<T>` to use `create_ref()` on the entire intermediate state, allowing more ergonomic reference passing, such as passing the entire state into a closure to call a user-defined method. Although this is a very substantial conceptual change, the code changes involved are actually fairly small. Additionally, this fixes type inference on `.template_with_state()`. * fix: fixed suspended state with new reference state systems * feat: improved error handling ergonomics and added example This makes error handlers take a full `ClientError`, rather than a reference. * feat: gave header setting functions access to scope/reactor * test: added proper tests for `js_interop` example * feat: created widget properties system Entirely untested as yet! * style: ran `cargo fmt` * feat: created proper system for calling widgets This involves unsafe transmutes, but they are guarded by clear type assertions. * fix: fixed some very minor capsules bugs Just a trailing forward slash on index widgets and I forgot to declare the capsules in the capsules example. * fix: fixed stupidest UB error in human history `&&self != &self`, I am a cabbage. * fix: fixed widget states typing error * fix: fixed several browser-side widget issues * style: ran `cargo fmt` * feat: added `Debug` implementations back to everything These were sidelined quite a while ago, and it's probably a good time to bring them back for v0.4.0. Note that this includes an implementation for `dyn AnyFreeze + 'static`. * fix: fixed up all examples Everything actually compiles now! I also learned from Clippy that there's a *very* helpful lifetime elision that simplifies stateful view function signature significantly from the perspective of mental load! * style: satisifed `clippy` and ran `cargo fmt` * feat: made `PerseusApp` work with static references This introduces several wrapper types and convenience functions to make this all work neatly and safely. * docs: added missing safety declaration * feat: added neat panics for capsules that set head/headers This involved some very minor internal refactoring to allow these assertions to be neatly produced. The same refactors *could* be made on the view function itself, but this would be far less elegant I think. * feat: added `#[auto_scope]` macro for convenience This allows elision of the complex lifetime signatures in view functions that take state. * refactor: cleaned up public interfaces This privatizes a lot of methods inside `TemplateInner`, as the user is now fairly likely to shoot themself in the foot with them. The methods on `Turbine` should be preferred. * feat: added `RxVecNested` and docs for reactive collections More to come... * docs: wrote faw for render backend mismatch error This is Perseus' safeguard against undefined behavior, which can occur if the user tries to do something silly like server-side rendering a capsule-pattern-defined widget in the browser. * test: added tests for `error_views` example * style: ran `cargo fmt` * fix: fixed i18n and locale detection This also makes the preload example use i18n (it all works perfectly!). * fix: assorted fixes Minor fixes for request state and temporary disabling of hydration. Also added some wrapper capsule systems in the capsules example. * fix: fixed several bugs with incremental generation and index paths This also involves making the CLI clear the mutable store, which for some reason it hadn't been previously doing... * fix: fixed build paths index pages * fix: fixed `not_found` checkpoint * ci: made build failures print more detailed error messages * test: removed outdated test checkpoints * fix: fixed `BorrowMut` errors with global state This also affected thawing. There's a 'closure invoked recursively or destroyed' error popping up, which I suspect is to do with live reloading, but it doesn't seem to be causing any actual issues. * fix: fixed `idb_freezing` example * fix: fixes up tests and one last `/` bug * fix: fixed failing doctests * chore: fixed `bonnie.toml` syntax error *Now* everything works! * fix: fixed support for simple widgets Widgets that didn't have state were failing due to an unhandled `NotFound` case. * fix: fixed subsequent loads of widgets * feat: added examples for request state widgets and build rescheduling * fix: fixed initial loads of capsules The subsequent load fix was a little heavy-handed, and broke initial loads. * test: added examples for capsule revalidation * docs: removed completely outdated docs from `next` * feat(website): made index page examples come from `stable` branch This lets us modify them to keep them up to date in PRs. * fix: fixed critical perseus router bug I am astonished this has never been caught: any incremental generation using more than one level (e.g. `__capsule/number/*`) failed due to a roge `else` clause that should never have been there. * fix: made path provided to build state be pure * fix: fixed basic widgets in combination with request state This led to some really weird bugs, just because of a heavy-handed early bailout. * feat: added incremental generation with capsules examples Note that this was the moment I realized incremental generation with widgets can be used with reactivity to reactively command the server to generate widgets in advance. That is unreasomably cool, and would allow something like generating the widgets that back product pages on an e-commerce website through the flipping search bar. The pieces are coming together... * wip * feat: made incremental widgets be rendered at build time This avoids unnecessary reschedules, and brings the capsules system to feature-completion, for now! * fix: fixed actix-web integration This was completely dysfunctional because I apparently didn't knw the difference between a file and a directory. * fix: fixed incremental generation tests * docs: added tiny extra faq BREAKING CHANGE: plugins can no longer add templates (provide the functions to the user for them to manually add) BREAKING CHANGE: `G` parameter removed entirely from plugins BREAKING CHANGE: you must now call `.build()` after creating a template/capsule with `::new(..)` and setting your various functions BREAKING CHANGE: header setting functions now take a `Scope` as their first argument BREAKING CHANGE: removed several outdated `checkpoint`s (see book for details)
- Loading branch information