Skip to content

Commit 2eb697b

Browse files
author
Max Hill
committed
feat: including session adapters
1 parent 1c8968a commit 2eb697b

File tree

7 files changed

+178
-182
lines changed

7 files changed

+178
-182
lines changed

README.md

+20-26
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ wisp_kv_sessions is a key-value session management library for [Wisp](https://gl
1111
An minimal example usage is available in `./example/app.gleam`.
1212

1313
```gleam
14-
import gleam/dynamic
1514
import gleam/erlang/process
16-
import gleam/json
1715
import gleam/option
1816
import gleam/result
1917
import gleam/string_builder
@@ -26,16 +24,16 @@ import wisp_kv_sessions/session
2624
import wisp_kv_sessions/session_config
2725
2826
pub fn main() {
29-
// Setup session_store
30-
use actor_adapter <- result.map(actor_adapter.try_create_session_store())
31-
use cache_store <- result.map(actor_adapter.try_create_session_store())
27+
// Setup session_adapter
28+
use store <- result.map(actor_adapter.new())
29+
use cache_store <- result.map(actor_adapter.new())
3230
3331
// Create session config
3432
let session_config =
3533
session_config.Config(
3634
default_expiry: session.ExpireIn(60 * 60),
3735
cookie_name: "SESSION_COOKIE",
38-
store: actor_adapter,
36+
store:,
3937
cache: option.Some(cache_store),
4038
)
4139
@@ -52,22 +50,26 @@ pub fn main() {
5250
}
5351
5452
pub fn handle_request(req: wisp.Request, session_config) -> wisp.Response {
55-
use req <- wisp_kv_sessions.middleware(session_config, req)
53+
// Run the middleware and construct current_session
54+
use req <- wisp_kv_sessions.middleware(req, session_config)
55+
let current_session = wisp_kv_sessions.CurrentSession(req, session_config)
5656
5757
case wisp.path_segments(req) {
58-
[] -> get_value_page(req, session_config)
59-
["set"] -> set_value_page(req, session_config)
58+
[] -> get_value_page(req, current_session)
59+
["set"] -> set_value_page(req, current_session)
6060
_ -> wisp.not_found()
6161
}
6262
}
6363
6464
fn get_value_page(
65-
req: wisp.Request,
66-
session_config: session_config.Config,
65+
_req: wisp.Request,
66+
session: wisp_kv_sessions.CurrentSession,
6767
) -> wisp.Response {
6868
// Read value to the session
6969
let assert Ok(key) =
70-
wisp_kv_sessions.get(session_config, req, "test_key", dynamic.string)
70+
session
71+
|> wisp_kv_sessions.key("test_key")
72+
|> wisp_kv_sessions.get()
7173
7274
case key {
7375
option.Some(k) -> {
@@ -82,24 +84,16 @@ fn get_value_page(
8284
}
8385
}
8486
85-
// Not nessesary for this simple type
86-
fn encode_string(str: String) {
87-
json.string(str) |> json.to_string
88-
}
89-
9087
fn set_value_page(
91-
req: wisp.Request,
92-
session_config: session_config.Config,
88+
_req: wisp.Request,
89+
session: wisp_kv_sessions.CurrentSession,
9390
) -> wisp.Response {
9491
// Set value to the session
9592
let _ =
96-
wisp_kv_sessions.set(
97-
session_config,
98-
req,
99-
"test_key",
100-
"something",
101-
encode_string,
102-
)
93+
session
94+
|> wisp_kv_sessions.key("test_key")
95+
|> wisp_kv_sessions.set("something")
96+
10397
wisp.redirect("/")
10498
}
10599
```

example/src/app.gleam

+16-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import gleam/dynamic
21
import gleam/erlang/process
3-
import gleam/json
42
import gleam/option
53
import gleam/result
64
import gleam/string_builder
@@ -39,22 +37,26 @@ pub fn main() {
3937
}
4038

4139
pub fn handle_request(req: wisp.Request, session_config) -> wisp.Response {
42-
use req <- wisp_kv_sessions.middleware(session_config, req)
40+
// Run the middleware and construct current_session
41+
use req <- wisp_kv_sessions.middleware(req, session_config)
42+
let current_session = wisp_kv_sessions.CurrentSession(req, session_config)
4343

4444
case wisp.path_segments(req) {
45-
[] -> get_value_page(req, session_config)
46-
["set"] -> set_value_page(req, session_config)
45+
[] -> get_value_page(req, current_session)
46+
["set"] -> set_value_page(req, current_session)
4747
_ -> wisp.not_found()
4848
}
4949
}
5050

5151
fn get_value_page(
52-
req: wisp.Request,
53-
session_config: session_config.Config,
52+
_req: wisp.Request,
53+
session: wisp_kv_sessions.CurrentSession,
5454
) -> wisp.Response {
5555
// Read value to the session
5656
let assert Ok(key) =
57-
wisp_kv_sessions.get(session_config, req, "test_key", dynamic.string)
57+
session
58+
|> wisp_kv_sessions.key("test_key")
59+
|> wisp_kv_sessions.get()
5860

5961
case key {
6062
option.Some(k) -> {
@@ -69,23 +71,15 @@ fn get_value_page(
6971
}
7072
}
7173

72-
// Not nessesary for this simple type
73-
fn encode_string(str: String) {
74-
json.string(str) |> json.to_string
75-
}
76-
7774
fn set_value_page(
78-
req: wisp.Request,
79-
session_config: session_config.Config,
75+
_req: wisp.Request,
76+
session: wisp_kv_sessions.CurrentSession,
8077
) -> wisp.Response {
8178
// Set value to the session
8279
let _ =
83-
wisp_kv_sessions.set(
84-
session_config,
85-
req,
86-
"test_key",
87-
"something",
88-
encode_string,
89-
)
80+
session
81+
|> wisp_kv_sessions.key("test_key")
82+
|> wisp_kv_sessions.set("something")
83+
9084
wisp.redirect("/")
9185
}

src/wisp_kv_sessions.gleam

+64-39
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,21 @@ import wisp_kv_sessions/internal/utils
1010
import wisp_kv_sessions/session
1111
import wisp_kv_sessions/session_config
1212

13+
pub type CurrentSession {
14+
CurrentSession(req: wisp.Request, config: session_config.Config)
15+
}
16+
1317
/// Try to get the session from the store.
1418
/// If it does not exist create a new one.
1519
///
16-
pub fn get_session(config: session_config.Config, req: wisp.Request) {
17-
use session_id <- result.try(utils.get_session_id(config.cookie_name, req))
20+
pub fn get_session(current_session: CurrentSession) {
21+
use session_id <- result.try(utils.get_session_id(
22+
current_session.config.cookie_name,
23+
current_session.req,
24+
))
1825
use maybe_session <- result.try(get_session_with_cache(
1926
session_id,
20-
config,
27+
current_session.config,
2128
True,
2229
))
2330

@@ -34,10 +41,10 @@ pub fn get_session(config: session_config.Config, req: wisp.Request) {
3441
let session =
3542
session.builder()
3643
|> session.with_id(session_id)
37-
|> session.with_expiry(config.default_expiry)
44+
|> session.with_expiry(current_session.config.default_expiry)
3845
|> session.build
3946

40-
save_session(config, session)
47+
save_session(current_session.config, session)
4148
}
4249
}
4350
}
@@ -72,26 +79,53 @@ fn save_session(config: session_config.Config, session: session.Session) {
7279
/// ```gleam
7380
/// sessions.delete(store, req)
7481
/// ```
75-
pub fn delete_session(config: session_config.Config, req: wisp.Request) {
82+
pub fn delete_session(current_session: CurrentSession) {
83+
let CurrentSession(config: config, req: req) = current_session
7684
use session_id <- result.try(utils.get_session_id(config.cookie_name, req))
7785
config.cache
7886
|> option.map(fn(cache) { cache.delete_session(session_id) })
7987
config.store.delete_session(session_id)
8088
}
8189

90+
pub type SessionKey(data) {
91+
SessionKey(
92+
current_session: CurrentSession,
93+
key: String,
94+
decode: Decoder(data),
95+
encode: fn(data) -> String,
96+
)
97+
}
98+
99+
pub fn key(current_session: CurrentSession, key: String) {
100+
SessionKey(
101+
current_session:,
102+
key:,
103+
decode: dynamic.string,
104+
encode: fn(str: String) { json.string(str) |> json.to_string },
105+
)
106+
}
107+
108+
pub fn with_codec(
109+
session_key: SessionKey(a),
110+
decoder decode: Decoder(data),
111+
encoder encode: fn(data) -> String,
112+
) -> SessionKey(data) {
113+
SessionKey(
114+
current_session: session_key.current_session,
115+
key: session_key.key,
116+
decode:,
117+
encode:,
118+
)
119+
}
120+
82121
/// Get data from session by key
83122
///
84-
pub fn get(
85-
config: session_config.Config,
86-
req: wisp.Request,
87-
key: session.Key,
88-
decoder: Decoder(data),
89-
) {
90-
use session <- result.try(get_session(config, req))
91-
case dict.get(session.data, key) |> option.from_result {
123+
pub fn get(entry: SessionKey(data)) {
124+
use session <- result.try(get_session(entry.current_session))
125+
case dict.get(session.data, entry.key) |> option.from_result {
92126
option.None -> Ok(option.None)
93127
option.Some(data) -> {
94-
json.decode(from: data, using: decoder)
128+
json.decode(from: data, using: entry.decode)
95129
|> result.replace_error(session.DecodeError)
96130
|> result.map(fn(d) { option.Some(d) })
97131
}
@@ -100,31 +134,22 @@ pub fn get(
100134

101135
/// Set data in session by key
102136
///
103-
pub fn set(
104-
config: session_config.Config,
105-
req: wisp.Request,
106-
key: session.Key,
107-
data: data,
108-
encoder: fn(data) -> String,
109-
) {
110-
use session <- result.try(get_session(config, req))
111-
let json_data = encoder(data)
112-
let new_session =
137+
pub fn set(entry: SessionKey(data), data: data) {
138+
use session <- result.try(get_session(entry.current_session))
139+
140+
let session =
113141
session.builder_from(session)
114-
|> session.with_entry(key, json_data)
142+
|> session.with_entry(entry.key, entry.encode(data))
115143
|> session.build
116-
use _ <- result.map(save_session(config, new_session))
144+
use _ <- result.map(save_session(entry.current_session.config, session))
117145
data
118146
}
119147

120148
/// Delete key from session
121149
///
122-
pub fn delete(
123-
config: session_config.Config,
124-
req: wisp.Request,
125-
key: session.Key,
126-
) {
127-
use session <- result.try(get_session(config, req))
150+
pub fn delete(current_session: CurrentSession, key: session.Key) {
151+
let CurrentSession(config: config, req: _req) = current_session
152+
use session <- result.try(get_session(current_session))
128153
save_session(
129154
config,
130155
session.Session(..session, data: dict.delete(session.data, key)),
@@ -134,16 +159,16 @@ pub fn delete(
134159
/// Replace the session with a new one
135160
/// Usage:
136161
/// ```gleam
137-
/// wisp.ok() |> replace_session(session_config, req)
162+
/// wisp.ok() |> replace_session(new_session)
138163
/// ```
139164
///
140165
pub fn replace_session(
141-
config: session_config.Config,
166+
current_session: CurrentSession,
142167
res: wisp.Response,
143-
req: wisp.Request,
144168
new_session: session.Session,
145169
) {
146-
use _ <- result.try(delete_session(config, req))
170+
let CurrentSession(config: config, req: req) = current_session
171+
use _ <- result.try(delete_session(current_session))
147172
use _ <- result.map(save_session(config, new_session))
148173
utils.set_session_cookie(config.cookie_name, res, req, new_session)
149174
}
@@ -154,11 +179,11 @@ pub fn replace_session(
154179
/// always is a session_id to store data towards
155180
/// Usage:
156181
/// ```gleam
157-
/// use <- sessions.middleware(config, req)
182+
/// use <- sessions.middleware(current_session)
158183
/// ```
159184
pub fn middleware(
160-
config: session_config.Config,
161185
req: wisp.Request,
186+
config: session_config.Config,
162187
handle_request: fn(wisp.Request) -> wisp.Response,
163188
) {
164189
case utils.get_session_id(config.cookie_name, req) {

0 commit comments

Comments
 (0)