-
Notifications
You must be signed in to change notification settings - Fork 1
/
LocalStorage.elm
143 lines (109 loc) · 3.67 KB
/
LocalStorage.elm
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
module LocalStorage
(get, set, remove, getJson, Error(..)) where
{-|
This library offers rudimentary access to the browser's localStorage, which is
limited to string keys and values. It uses Elm Tasks for storage IO.
# Retrieving
@docs get, getJson
# Storing
@docs set
# Removing
@docs remove
# Error type
@docs Error
-}
import Native.LocalStorage
import String
import Task exposing (Task, andThen, succeed, fail)
import Json.Decode as Json
import Maybe exposing (Maybe(..))
{-|
kek
-}
type Error
= NoStorage
| UnexpectedPayload String
{-|
Retrieve the string value for a given key. Yields Maybe.Nothing if the key
does not exist in storage. Task will fail with NoStorage if localStorage is
not available in the browser:
result : Signal.Mailbox String
result = Signal.mailbox "loading..."
main : Signal Element
main = Signal.map show result.signal
port getStorage : Task LocalStorage.Error ()
port getStorage =
let handle str =
case str of
Just s -> Signal.send result.address s
Nothing -> Signal.send result.address "not found in storage =("
in
(LocalStorage.get "some-key")
`onError` (\_ -> succeed (Just "no localStorage in browser =((("))
`andThen` handle
-}
get : String -> Task Error (Maybe String)
get =
Native.LocalStorage.get
{-|
Retrieves the value for a given key and parses it using the provided JSON
decoder. Yields Maybe.Nothing if the key does not exist in storage. Task will
fail with NoStorage if localStorage is not available in the browser, or
UnexpectedPayload if there was a parsing error:
result : Signal.Mailbox String
result = Signal.mailbox "loading..."
main : Signal Element
main = Signal.map show result.signal
port getStorage : Task LocalStorage.Error ()
port getStorage =
let handleError err =
case err of
LocalStorage.NoStorage ->
succeed (Just "no localStorage in browser =(((")
LocalStorage.UnexpectedPayload _ ->
succeed (Just "JSON parse err! wha happehn?")
handle str =
case str of
Just s -> Signal.send result.address s
Nothing -> Signal.send result.address "not found in storage =("
in
(LocalStorage.getJson Json.string "some-json-key")
`onError` handleError
`andThen` handle
-}
getJson : Json.Decoder value -> String -> Task Error (Maybe value)
getJson decoder key =
let decode maybe =
case maybe of
Just str -> fromJson decoder str
Nothing -> succeed Nothing
in
(get key) `andThen` decode
-- Decodes json and handles parse errors
fromJson : Json.Decoder value -> String -> Task Error (Maybe value)
fromJson decoder str =
case Json.decodeString decoder str of
Ok v -> succeed (Just v)
Err msg -> fail (UnexpectedPayload msg)
{-|
Sets the string value for a given key and passes through the string value as
the task result for chaining. Task will fail with NoStorage if localStorage is
not available in the browser:
port setStorage : Signal (Task LocalStorage.Error String)
port setStorage =
Signal.map (LocalStorage.set storageKey) someStringSignal
-}
set : String -> String -> Task Error String
set =
Native.LocalStorage.set
{-|
Removes the value for a given key and passes through the string key as the
task result for chaining. Task will fail with NoStorage if localStorage is
not available in the browser:
port removeStorage : Signal (Task LocalStorage.Error String)
port removeStorage =
Signal.map (LocalStorage.remove storageKey) someStringSignal
-}
remove : String -> Task Error String
remove key =
Native.LocalStorage.remove