The 'previous question's resources until refresh' mystery: leptos's auto-generated server fn routes embed a hash that changes across builds. Every deploy therefore breaks every already-open tab - its wasm keeps calling /api/get_question<oldhash>, the new server answers 400 'Could not find a server function at the route', and client-side navigation quietly leaves the previous question's data on screen. Refresh loads the new wasm with matching hashes, which is why it always fixed it. Confirmed live: a pre-deploy client 400ed on get_question2970801986613442004 while the freshly served wasm calls get_question13103328088426240960, same source on both builds. Explicit endpoint names decouple the URL from the build. This deploy is the last breaking one; after it, old clients keep working. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
5b3ffa62e8
commit
c9c5caf3ff
+2
-2
@@ -101,7 +101,7 @@ pub struct TransitionItem {
|
||||
/// (the shared per-alternative Confirm button). Items are independent
|
||||
/// - per-item CAS, no cross-item transaction - so one failure doesn't
|
||||
/// roll back the others; failures are collected and reported together.
|
||||
#[server]
|
||||
#[server(endpoint = "transition_answers")]
|
||||
pub async fn transition_answers(
|
||||
question_id: String,
|
||||
alternative: String,
|
||||
@@ -289,7 +289,7 @@ async fn apply_transition(
|
||||
/// itself. Deliberately returns the same generic error for "no such
|
||||
/// item" and "email doesn't match", so an unsubscribe link can't be
|
||||
/// used to probe which hashes or emails exist.
|
||||
#[server]
|
||||
#[server(endpoint = "self_transition_answer")]
|
||||
pub async fn self_transition_answer(
|
||||
question_id: String,
|
||||
alternative: String,
|
||||
|
||||
+3
-3
@@ -1484,7 +1484,7 @@ fn NotFound() -> impl IntoView {
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
#[server(endpoint = "get_question")]
|
||||
pub async fn get_question(path: String) -> Result<Option<Question>, ServerFnError> {
|
||||
use crate::server::AppState;
|
||||
let state = expect_context::<AppState>();
|
||||
@@ -1495,7 +1495,7 @@ pub async fn get_question(path: String) -> Result<Option<Question>, ServerFnErro
|
||||
/// the site nav's data. Context-dependent: an owner session sees the
|
||||
/// gated pages too, and `followup` pages only appear once the visitor
|
||||
/// carries an answer chain.
|
||||
#[server]
|
||||
#[server(endpoint = "list_qualifying_questions")]
|
||||
pub async fn list_qualifying_questions(
|
||||
has_chain: bool,
|
||||
) -> Result<Vec<(String, String)>, ServerFnError> {
|
||||
@@ -1528,7 +1528,7 @@ pub struct SubmitResult {
|
||||
pub chain_hash: String,
|
||||
}
|
||||
|
||||
#[server]
|
||||
#[server(endpoint = "submit_answer")]
|
||||
pub async fn submit_answer(
|
||||
question_id: String,
|
||||
alternative: String,
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ pub struct User {
|
||||
pub const SESSION_USER_KEY: &str = "user";
|
||||
|
||||
/// Returns the currently signed-in user, if any.
|
||||
#[server]
|
||||
#[server(endpoint = "current_user")]
|
||||
pub async fn current_user() -> Result<Option<User>, ServerFnError> {
|
||||
let session: tower_sessions::Session = leptos_axum::extract().await?;
|
||||
let user = session
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ use leptos::prelude::*;
|
||||
/// fetch (`GiteaStarred`/`GiteaOrgRepos`/`Url`), the mechanism behind
|
||||
/// "a resource parameterized by other form fields"; a `Kv` resource
|
||||
/// ignores them entirely, same as today.
|
||||
#[server]
|
||||
#[server(endpoint = "get_resource")]
|
||||
pub async fn get_resource(
|
||||
question_id: String,
|
||||
alternative: String,
|
||||
@@ -49,7 +49,7 @@ pub async fn get_resource(
|
||||
/// of whether it's displayed read-only or offered as choices to pick
|
||||
/// from, so this deliberately doesn't duplicate the source-dispatch or
|
||||
/// jq-shaping logic - see `fetch_resource_value`.
|
||||
#[server]
|
||||
#[server(endpoint = "get_requirement_options")]
|
||||
pub async fn get_requirement_options(
|
||||
question_id: String,
|
||||
alternative: String,
|
||||
@@ -80,7 +80,7 @@ pub async fn get_requirement_options(
|
||||
/// `get_requirement_options`: fetches the resource a bound field
|
||||
/// loads its value from, parameterized by the watched sibling's value
|
||||
/// (already inside `params`, keyed by the bind's param name).
|
||||
#[server]
|
||||
#[server(endpoint = "get_requirement_binding")]
|
||||
pub async fn get_requirement_binding(
|
||||
question_id: String,
|
||||
alternative: String,
|
||||
|
||||
Reference in New Issue
Block a user