1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! The core `DurableObject` trait.
use Future;
use ;
use DurableContext;
use DurableObjectError;
use ;
use crateRouter;
/// A Durable Object with hibernation-first WebSocket support.
///
/// # Design
///
/// - **One value per instance**: the platform constructs a Durable Object instance once and
/// delivers every event to it until it is evicted, and the struct follows the same lifetime.
/// It is built on the instance's first event — from storage when it [persists](Self::PERSIST),
/// from `Default` otherwise — and every later event on that instance sees the same value, so a
/// field set by one event is there for the next.
///
/// - **`&self` everywhere**: events on one instance interleave at every `await` — the platform
/// serializes them only around storage operations — so a handler holds the object shared, never
/// exclusively. State an event changes lives behind interior mutability, and [`fetch`](Self::fetch)
/// hands handlers what they need as `State<…>` clones of the object's own handles.
///
/// - **Struct IS the state**, when it persists: a type with the default
/// [`PERSIST`](Self::PERSIST) must be `Serialize + DeserializeOwned + Default`, is read from
/// storage when the instance first receives an event, and is written back after every
/// successful event whose serialization changed.
///
/// - **Two methods**: `fetch` for HTTP (returns a [`Router`]),
/// `websocket` for all hibernation WS events.
///
/// # Example
///
/// ```ignore
/// use std::sync::atomic::{AtomicU64, Ordering};
///
/// use serde::{Serialize, Deserialize};
/// use skyzen::durable::*;
/// use skyzen::routing::{CreateRouteNode, Route, Router};
///
/// #[derive(Serialize, Deserialize, Default)]
/// struct Counter {
/// count: AtomicU64,
/// }
///
/// impl DurableObject for Counter {
/// fn fetch(&self) -> Router {
/// self.count.fetch_add(1, Ordering::Relaxed);
/// Route::new((
/// "/increment".at(increment),
/// ))
/// .build()
/// }
/// }
///
/// async fn increment() -> skyzen::Result<String> {
/// Ok("incremented".to_string())
/// }
/// ```