/
Index.purs
81 lines (62 loc) · 1.89 KB
/
Index.purs
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
module Epicbot.Index
( DocIndex
, Index
, findById
, fromCards
, new
, random
, search
) where
import Prelude
import Data.Array as Array
import Data.Function.Uncurried (Fn2, runFn2)
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Uncurried (EffectFn2, runEffectFn2)
import Epicbot.Card (Card)
import Epicbot.Card as Card
import Epicbot.Random.Array (takeRandom)
type Index =
{ cards :: Map String Card
, index :: DocIndex
}
type Doc =
{ id :: String
, name :: String
}
type Result =
{ ref :: String
, score :: Number
}
foreign import data DocIndex :: Type
foreign import _addDoc :: EffectFn2 Doc DocIndex DocIndex
foreign import _newDocIndex :: DocIndex
foreign import _searchDoc :: Fn2 String DocIndex (Array Result)
new :: Index
new = { index: _newDocIndex, cards: Map.empty }
fromCards :: Array Card -> Aff Index
fromCards = Array.foldRecM (flip addCard) new
random :: Int -> Index -> Aff (Array Card)
random n { cards } =
takeRandom n <<< Array.filter (not Card.dualSided) <<< Array.fromFoldable <<< Map.values $ cards
search :: String -> Index -> Array Card
search query { index, cards } = Array.mapMaybe resultToCard <<< searchDoc query $ index
where
resultToCard :: Result -> Maybe Card
resultToCard result = Map.lookup result.ref cards
findById :: String -> Index -> Maybe Card
findById id { cards } = Map.lookup id cards
addCard :: Card -> Index -> Aff Index
addCard card { index, cards } = do
index' <- addDoc (cardToDoc card) index
let cards' = Map.insert card.id card cards
pure { index: index', cards: cards' }
addDoc :: Doc -> DocIndex -> Aff DocIndex
addDoc doc index = liftEffect $ runEffectFn2 _addDoc doc index
searchDoc :: String -> DocIndex -> Array Result
searchDoc = runFn2 _searchDoc
cardToDoc :: Card -> Doc
cardToDoc { id, name } = { id, name }