topcoat_runtime/router.rs
1#[cfg(feature = "router")]
2use topcoat_router::RouterBuilder;
3
4#[cfg(feature = "router")]
5use crate::{MaxRunsPerConnection, PrefetchMode, RuntimeLayer};
6
7/// Marks a router's app context as configured for the browser runtime.
8#[derive(Debug, Clone, Copy)]
9pub struct RuntimeSetup;
10
11/// Sets up the browser runtime on a [`RouterBuilder`].
12#[cfg(feature = "router")]
13pub trait RouterBuilderRuntimeExt {
14 /// Enables page reruns by registering a [`RuntimeLayer`].
15 ///
16 /// Call this once when building a router that serves interactive pages.
17 /// Register your application's pathless layers first so the runtime
18 /// layer can rewrite page reruns to `GET` before those layers run.
19 /// See [`RuntimeLayer`] for the request format and rewrite behavior.
20 ///
21 /// Register procedures and shards separately through discovery or
22 /// explicit registration.
23 #[must_use]
24 fn runtime(self) -> Self;
25
26 /// Sets when links in this router load their pages ahead of time.
27 ///
28 /// This sets the app context value read by
29 /// [`prefetch_mode`](crate::prefetch_mode). You can override it with a
30 /// `PrefetchMode` in the request context or with a link's `prefetch`
31 /// argument.
32 ///
33 /// ```rust
34 /// use topcoat_router::Router;
35 /// use topcoat_runtime::{PrefetchMode, RouterBuilderRuntimeExt};
36 ///
37 /// let router = Router::builder()
38 /// .runtime()
39 /// .prefetch(PrefetchMode::Viewport)
40 /// .build();
41 /// ```
42 ///
43 /// # Panics
44 ///
45 /// Panics if the app context already contains a `PrefetchMode`.
46 #[must_use]
47 #[track_caller]
48 fn prefetch(self, mode: PrefetchMode) -> Self;
49
50 /// Sets how many connected renders one runtime connection may have at
51 /// once. The default is 64.
52 ///
53 /// The browser keeps one connected render for each live page or shard
54 /// that is not inside another one. Once a connection reaches the limit,
55 /// the server answers further render requests with
56 /// `429 Too Many Requests` until a render finishes or is stopped.
57 ///
58 /// ```rust
59 /// use topcoat_router::Router;
60 /// use topcoat_runtime::RouterBuilderRuntimeExt;
61 ///
62 /// let router = Router::builder()
63 /// .runtime()
64 /// .max_runs_per_connection(128)
65 /// .build();
66 /// ```
67 ///
68 /// # Panics
69 ///
70 /// Panics if the limit was already set.
71 #[must_use]
72 #[track_caller]
73 fn max_runs_per_connection(self, max: usize) -> Self;
74}
75
76#[cfg(feature = "router")]
77impl RouterBuilderRuntimeExt for RouterBuilder {
78 fn runtime(self) -> Self {
79 self.layer(RuntimeLayer).app_context(RuntimeSetup)
80 }
81
82 #[track_caller]
83 fn prefetch(self, mode: PrefetchMode) -> Self {
84 self.app_context(mode)
85 }
86
87 #[track_caller]
88 fn max_runs_per_connection(self, max: usize) -> Self {
89 self.app_context(MaxRunsPerConnection(max))
90 }
91}