-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathreducer_context.h
More file actions
126 lines (105 loc) · 3.7 KB
/
Copy pathreducer_context.h
File metadata and controls
126 lines (105 loc) · 3.7 KB
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
124
125
126
#ifndef REDUCER_CONTEXT_H
#define REDUCER_CONTEXT_H
#include <spacetimedb/bsatn/types.h> // For Identity, ConnectionId
#include <spacetimedb/bsatn/timestamp.h> // For Timestamp
#include <spacetimedb/bsatn/uuid.h> // For Uuid
#include <spacetimedb/random.h> // For StdbRng
#include <spacetimedb/auth_ctx.h> // For AuthCtx
#include <optional>
#include <array>
#include <memory>
// Include database for DatabaseContext
#include <spacetimedb/database.h>
namespace SpacetimeDB {
// Enhanced ReducerContext with database access - matches Rust pattern
struct ReducerContext {
private:
Identity sender_;
public:
// Core fields - sender is exposed via sender() like Rust, other fields remain directly accessible
std::optional<ConnectionId> connection_id;
Timestamp timestamp;
// Database context with name-based access
DatabaseContext db;
private:
// Authentication context with lazy JWT loading (private like in Rust)
AuthCtx sender_auth_;
// Lazily initialized RNG (similar to Rust's OnceCell pattern)
// Using shared_ptr to make ReducerContext copyable
mutable std::shared_ptr<StdbRng> rng_instance;
// Monotonic counter for UUID v7 generation (31 bits, wraps around)
mutable uint32_t counter_uuid_ = 0;
public:
Identity sender() const {
return sender_;
}
// Returns the authorization information for the caller of this reducer
const AuthCtx& sender_auth() const {
return sender_auth_;
}
// Get the random number generator for this reducer call
// Lazily initialized and seeded with the timestamp
StdbRng& rng() const {
if (!rng_instance) {
rng_instance = std::make_unique<StdbRng>(timestamp);
}
return *rng_instance;
}
Identity identity() const {
std::array<uint8_t, 32> buffer;
::identity(buffer.data());
return Identity(buffer);
}
/**
* Generate a new random UUID v4.
*
* Creates a random UUID using the reducer's deterministic RNG.
*
* Example:
* @code
* SPACETIMEDB_REDUCER(void, create_session, ReducerContext ctx) {
* Uuid session_id = ctx.new_uuid_v4();
* ctx.db[sessions].insert(Session{session_id});
* }
* @endcode
*
* @return A new UUID v4
*/
Uuid new_uuid_v4() const {
// Get 16 random bytes from the context RNG
std::array<uint8_t, 16> random_bytes;
rng().fill_bytes(random_bytes.data(), 16);
// Generate UUID v4
return Uuid::from_random_bytes_v4(random_bytes);
}
/**
* Generate a new UUID v7.
*
* Creates a time-ordered UUID with the reducer's timestamp, a monotonic counter,
* and random bytes from the reducer's deterministic RNG.
*
* Example:
* @code
* SPACETIMEDB_REDUCER(void, create_user, ReducerContext ctx, std::string name) {
* Uuid user_id = ctx.new_uuid_v7();
* ctx.db[users].insert(User{user_id, name});
* }
* @endcode
*
* @return A new UUID v7
*/
Uuid new_uuid_v7() const {
// Get 4 random bytes from the context RNG
std::array<uint8_t, 4> random_bytes;
rng().fill_bytes(random_bytes.data(), 4);
// Generate UUID v7 with timestamp and counter
return Uuid::from_counter_v7(counter_uuid_, timestamp, random_bytes);
}
// Constructors
ReducerContext() : sender_auth_(AuthCtx::internal()) {}
ReducerContext(Identity s, std::optional<ConnectionId> cid, Timestamp ts)
: sender_(s), connection_id(cid), timestamp(ts),
sender_auth_(AuthCtx::from_connection_id_opt(cid, s)) {}
};
} // namespace SpacetimeDB
#endif // REDUCER_CONTEXT_H