Skip to content

Commit

Permalink
feat: created capsules system and rewrote just about everything (#224)
Browse files Browse the repository at this point in the history
* 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
arctic-hen7 authored Dec 30, 2022
1 parent bd06110 commit a4c59f2
Show file tree
Hide file tree
Showing 289 changed files with 12,155 additions and 9,692 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = [
"examples/core/*",
"examples/demos/*",
"examples/comprehensive/*",
"examples/website/*",
# "examples/website/*",
"website",
]
resolver = "2"
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ pub fn main<G: Html>() -> PerseusApp<G> {
PerseusApp::new()
.template(
Template::new("index")
.template(|cx| {
.view(|cx| {
view! { cx,
p { "Hello World!" }
}
})
)
.build()
)
}
```

Expand Down
17 changes: 11 additions & 6 deletions bonnie.toml
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,24 @@ test.cmd = [
"cargo test", # This will ignore Wasm tests
# Run tests for each example
"bonnie test example-all-integrations core basic --headless",
"bonnie test example-all-integrations core unreactive --headless",
"bonnie test example-all-integrations core i18n --headless",
"bonnie test example-all-integrations core plugins --headless",
"bonnie test example-all-integrations core state_generation --headless",
"bonnie test example-all-integrations core custom_server --headless",
"bonnie test example-all-integrations core error_views --headless",
"bonnie test example-all-integrations core freezing_and_thawing --headless",
"bonnie test example-all-integrations core global_state --headless",
"bonnie test example-all-integrations core helper_build_state --headless",
"bonnie test example-all-integrations core i18n --headless",
"bonnie test example-all-integrations core idb_freezing --headless",
"bonnie test example-all-integrations core index_view --headless",
"bonnie test example-all-integrations core js_interop --headless",
"bonnie test example-all-integrations core plugins --headless",
# TODO core/preload
"bonnie test example-all-integrations core router_state --headless",
"bonnie test example-all-integrations core rx_state --headless",
"bonnie test example-all-integrations core index_view --headless",
"bonnie test example-all-integrations core set_headers --headless",
"bonnie test example-all-integrations core state_generation --headless",
"bonnie test example-all-integrations core static_content --headless",
"bonnie test example-all-integrations core custom_server --headless"
"bonnie test example-all-integrations core suspense --headless",
"bonnie test example-all-integrations core unreactive --headless",
]
test.desc = "runs all tests headlessly (assumes geckodriver running in background)"
test.subcommands.core.cmd = "cargo test"
Expand Down
4 changes: 0 additions & 4 deletions docs/next/en-US/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

- [Introduction](/docs/intro)
- [What is Perseus?](/docs/what-is-perseus)
- [Getting Started](/docs/getting-started/intro)
- [Installation](/docs/getting-started/installation)
- [Your First App](/docs/getting-started/first-app)
- [Core Principles](/docs/core-principles)
- [Your Second App](/docs/tutorials/second-app)

# Reference

Expand Down
75 changes: 0 additions & 75 deletions docs/next/en-US/getting-started/first-app.md

This file was deleted.

32 changes: 0 additions & 32 deletions docs/next/en-US/getting-started/installation.md

This file was deleted.

3 changes: 0 additions & 3 deletions docs/next/en-US/getting-started/intro.md

This file was deleted.

2 changes: 2 additions & 0 deletions docs/next/en-US/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

[Home][repo][Crate Page][crate][API Documentation][docs][Contributing][contrib]

**WARNING:** These docs are under heavy construction right now, in preparation for the release of Perseus v0.4.0, which will be, by far, the most powerful version of Perseus yet! A lot has changed though, so we *highly* recommend sticking to the v0.3.4+ docs if you're using v0.3.x, or the v0.4.x docs if you're still on one of the beta versions up to beta 11. The `next` docs (these ones) are highly incomplete, probably full of errors and typos, and have not yet been thoroughly checked. You have been warned!

Welcome to the Perseus documentation! Here, you'll find guides on how to use Perseus, as well as documentation for specific features and plenty of examples! Note that every code snippet in these docs comes from something in the [examples](https://github.com/arctic-hen7/perseus/tree/main/examples), where you can get context from real-world code.

If you like Perseus, please consider giving us a star [on GitHub](https://github.com/arctic-hen7/perseus)!
Expand Down
Loading

0 comments on commit a4c59f2

Please sign in to comment.