• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nicholaswmin / automap / 9855082686

09 Jul 2024 10:08AM UTC coverage: 92.515% (+0.03%) from 92.486%
9855082686

Pull #11

github

web-flow
Merge a3d5d9db2 into e6bd4a332
Pull Request #11: Benchmark

459 of 463 branches covered (99.14%)

Branch coverage included in aggregate %.

0 of 2 new or added lines in 1 file covered. (0.0%)

2013 of 2209 relevant lines covered (91.13%)

18.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

12.5
/src/repository.js
1
import { flatten, expand } from './map.js'
1✔
2

1✔
3
class Repository {
1✔
4
  constructor(Class, redis) {
1✔
5
    this.Class = Class
×
6
    this.redis = redis
×
NEW
7

×
8
    // Usage: `const res = await this.redis.hmgetall(2, 'hash1', 'hash2')`
×
9
    this.redis.defineCommand('hmgetall', {
×
10
      lua: `local r = {} for _, v in pairs(KEYS) do r[#r+1] = redis.call('HGETALL', v) end return r`
×
11
    })
×
12

×
13
    this.loaders = {
×
14
      string: {
×
15
        get: key => {
×
16
          return this.redis.get(key)
×
17
            .then(data => data ? JSON.parse(data) : null)
×
18
        },
×
19

×
20
        set: (key, value) => {
×
21
          return this.redis.set(key, value)
×
22
        }
×
23
      },
×
24

×
25
      hash: {
×
26
        getMany: async (keys = []) => {
×
27
          // ???? wtf
×
28
          return this.redis.hmgetall(keys.length, ...keys)
×
29
            .then(hashes => hashes.map(hash =>
×
30
              hash.filter(field => field.startsWith('{'))
×
31
                .map(JSON.parse)
×
32
                  .sort((a, b) => a.i - b.i)
×
33
                    .map(item => item.json)))
×
34
        },
×
35

×
36
        getField: (key, field) => {
×
37
          return this.redis.hget(key, field)
×
38
            .then(data => data ? JSON.parse(data) : null)
×
39
        },
×
40

×
41
        get: key => {
×
42
          return this.redis.hgetall(key)
×
43
            .then(hash => Object.keys(hash)
×
44
            .map(key => JSON.parse(hash[key]))
×
45
            .sort((a, b) => a.i - b.i)
×
46
            .map(item => item.json))
×
47
        },
×
48

×
49
        set: (key, value) => {
×
50
          return this.redis.hset(key, value)
×
51
        }
×
52
      },
×
53

×
54
      list: {
×
55
        getMany: (keys = []) => {
×
56
          const pipeline = keys.reduce((promise, key) => {
×
57
            return promise.lrange(key, 0, -1)
×
58
              .then(res => res.map(JSON.parse))
×
59
          }, this.redis.pipeline())
×
60

×
61
          return pipeline.exec()
×
62
        },
×
63

×
64
        get: key => {
×
65
          return this.redis.lrange(key, 0, -1).then(res => res.map(JSON.parse))
×
66
        },
×
67

×
68
        set: (key, value) => {
×
69
          return this.redis.rpush(item.key, item.value)
×
70
        }
×
71
      }
×
72
    }
×
73
  }
×
74

1✔
75
  save(root) {
1✔
76
    const flat = flatten(root)
×
77
    const transaction = flat.lists.reduce((promise, item) => {
×
78
      return item.type === 'list' ?
×
79
        promise.rpush(item.key, item.value) :
×
80
        promise.hset(item.key, item.value)
×
81
    }, this.redis.multi().set(flat.root.key, flat.root.value))
×
82

×
83
    return transaction.exec()
×
84
  }
×
85

1✔
86
  async fetch({ id }) {
1✔
87
    const key = this.Class.name.toLowerCase() + ':' + id
×
88
    const root = await this.loaders.string.get(key)
×
89

×
90
    if (!root)
×
NEW
91
      return null
×
92

×
93
    const expandedData = await expand(root, async subs => {
×
94
      const hashSubs = subs.filter(sub => sub.traits.type === 'hash')
×
95
      const listSubs = subs.filter(sub => sub.traits.type === 'list')
×
96

×
97
      const hashSubsWithItems = await this.loaders['hash']
×
98
        .getMany(hashSubs.map(sub => sub.path))
×
99
        .then(items => hashSubs.map((sub, i) => ({ ...sub, items: items[i] })))
×
100

×
101
      const listSubsWithItems = await this.loaders['list']
×
102
        .getMany(listSubs.map(sub => sub.path))
×
103
        .then(items => listSubs.map((sub, i) => ({ ...sub, items: items[i] })))
×
104

×
105
      return [...hashSubsWithItems, ...listSubsWithItems]
×
106
    })
×
107

×
108
    return new this.Class(expandedData)
×
109
  }
×
110

1✔
111
  async fetchHashField({ id, parentId }) {
1✔
112
    const root = await this.loaders.hash.getField(parentId, id)
×
113

×
114
    if (!root)
×
115
      Repository.createChildResourceNotFoundError(parentId, id)
×
116

×
117
    const data = await expand(root, this.loaders)
×
118

×
119
    return new this.Class(data.json)
×
120
  }
×
121

1✔
122
  static createChildResourceNotFoundError(parentId, id) {
1✔
123
    throw new Error(`Cannot find child resource: ${id} of parent: ${parentId}`)
×
124
  }
×
125
}
1✔
126

1✔
127
export { Repository }
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc