Skip to main content

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}