-
Notifications
You must be signed in to change notification settings - Fork 0
/
Falcor.elm
168 lines (145 loc) · 4.58 KB
/
Falcor.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
module Falcor where
import Json.Encode
import Task exposing (Task)
import Effects exposing (Never)
-- import Debug exposing (log)
import String
import Json.Decode as Json exposing ((:=))
import Native.Falcor
type alias Model =
{ cache: Maybe Json.Value
, url: Maybe String
, headers: Maybe (List (String, String))
, model: Maybe Json.Value
}
type Error = CommonError
type Path
= PathList (List Path)
| PathString String
| PathStrings (List String)
| Range Int Int
convertPaths : List Path -> List Json.Encode.Value
convertPaths paths =
List.map
(\path ->
case path of
PathList lst ->
Json.Encode.list <| convertPaths lst
PathString str ->
Json.Encode.string str
PathStrings arr ->
Json.Encode.list <| List.map Json.Encode.string arr
Range from to ->
Json.Encode.object [ ("from", Json.Encode.string <| toString <| from), ("to", Json.Encode.string <| toString <| to) ]
) paths
cache: Json.Value -> Model -> Model
cache c model = { model | cache = Just c}
init: Model
init = Model Nothing Nothing Nothing Nothing
url: String -> Model -> Model
url arg model = { model | url = Just arg}
headers : List (String, String) -> Model -> Model
headers headers' model = { model | headers = Just headers' }
setup : Model -> Model
setup = Native.Falcor.createModel
get : Model -> List Path -> Task err Json.Value
get model paths = Native.Falcor.get model (convertPaths paths |> Json.Encode.list)
setValue : Model -> List String -> String -> Task err ()
setValue model path value = Native.Falcor.setValue model (listToJs path) value
call : Model -> List String -> List String -> Task err ()
call model path value = Native.Falcor.call model (listToJs path) (listToJs value)
hashToList : List (String, a) -> List a
hashToList lst =
List.sortBy
(fst >> String.toInt >> Result.withDefault -1)
lst
|> List.map snd
listToJs : List String -> Json.Value
listToJs = List.map Json.Encode.string >> Json.Encode.list
{-
load : (List String) -> Json.Decoder a -> Task Error a
load falcorQuery decoder =
Falcor.get falcorModel falcorQuery |> Task.map (Json.decodeValue decoder)
-}
prependPath : List String -> List Path -> List Path -> List Path
prependPath prefix paths suffix =
let
basePath = List.map PathString prefix
in
List.map
(\path ->
PathList <| basePath ++ suffix ++ (
case path of
PathList arr -> arr
_ -> [ path ]
)
) paths
prefixPath : List Path -> List Path -> List Path
prefixPath prefix lst =
List.map
(\p ->
PathList <| prefix ++
-- [ p ]
( case p of
PathList plist -> plist
_ -> [p]
)
)
lst
listDecoder : Json.Decoder a -> Json.Decoder (List a)
listDecoder decoder =
Json.oneOf
[ Json.keyValuePairs decoder |> Json.map hashToList
, Json.succeed []
]
load : Model -> List String -> List Path -> Json.Decoder a -> Task Never (Result String a)
load falcorModel prefix paths decoder =
get
falcorModel
(prependPath prefix paths [])
|> Task.toResult
|> Task.map
(\resultJsonVal ->
Result.andThen
resultJsonVal
(\v -> Json.decodeValue (Json.at prefix decoder) v)
)
loadCollection : Model -> List String -> List Path -> Json.Decoder a -> Int -> Int -> Task Never (List a)
loadCollection falcorModel prefix paths decoder from to =
get
falcorModel
(prependPath prefix paths [ Range from to ])
|> Task.toMaybe
|> Task.map
(\maybeJsonVal ->
Maybe.andThen
maybeJsonVal
(\v ->
Result.toMaybe <|
Json.decodeValue
(Json.at prefix (listDecoder decoder))
v
) |> Maybe.withDefault []
)
loadCollection2 : Model -> List String -> List Path -> Json.Decoder a -> Json.Decoder b -> Int -> Int -> Task Never (List (a, b))
loadCollection2 falcorModel prefix paths decoder1 decoder2 from to =
get
falcorModel
(prependPath prefix paths [ Range from to ])
|> Task.toResult
|> Task.map
(\resultJsonVal ->
Result.andThen
resultJsonVal
(\v ->
let
dec decoder =
Json.decodeValue
(Json.at prefix (Json.keyValuePairs decoder |> Json.map hashToList))
v
in
Result.map2 (,) (dec decoder1) (dec decoder2)
|> Result.map (\(lst1, lst2) -> List.map2 (,) lst1 lst2)
)
|> Result.toMaybe |> Maybe.withDefault []
)