|
| 1 | +/* |
| 2 | + * Nimbella CONFIDENTIAL |
| 3 | + * --------------------- |
| 4 | + * |
| 5 | + * 2018 - present Nimbella Corp |
| 6 | + * All Rights Reserved. |
| 7 | + * |
| 8 | + * NOTICE: |
| 9 | + * |
| 10 | + * All information contained herein is, and remains the property of |
| 11 | + * Nimbella Corp and its suppliers, if any. The intellectual and technical |
| 12 | + * concepts contained herein are proprietary to Nimbella Corp and its |
| 13 | + * suppliers and may be covered by U.S. and Foreign Patents, patents |
| 14 | + * in process, and are protected by trade secret or copyright law. |
| 15 | + * |
| 16 | + * Dissemination of this information or reproduction of this material |
| 17 | + * is strictly forbidden unless prior written permission is obtained |
| 18 | + * from Nimbella Corp. |
| 19 | + */ |
| 20 | + |
| 21 | +let kv = {} |
| 22 | + |
| 23 | +function clearTimeout(k) { |
| 24 | + const x = kv[k] |
| 25 | + if (x && x.timer) { |
| 26 | + clearTimeout(x.timer) |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +// https://redis.io/commands/flushall |
| 31 | +const flushall = () => { |
| 32 | + kv = {} |
| 33 | + return Promise.resolve('OK') |
| 34 | +} |
| 35 | + |
| 36 | +// https://redis.io/commands/keys |
| 37 | +const keys = (p) => { |
| 38 | + if (p) { |
| 39 | + if (p.substring(p.length - 1) === '*') p = p.slice(0, -1); |
| 40 | + return Object.keys(kv).filter(key => key.startsWith(p)) |
| 41 | + } |
| 42 | + else { return Object.keys(kv); } |
| 43 | +} |
| 44 | + |
| 45 | +// https://redis.io/commands/get |
| 46 | +const get = (k) => { |
| 47 | + if (k in kv) { |
| 48 | + return kv[k].value || kv[k] |
| 49 | + } else return null |
| 50 | +} |
| 51 | + |
| 52 | +// https://redis.io/commands/set |
| 53 | +const set = (k, value) => { |
| 54 | + clearTimeout(k) |
| 55 | + kv[k] = { value } |
| 56 | + return 'OK' |
| 57 | +} |
| 58 | + |
| 59 | +// https://redis.io/commands/incr |
| 60 | +const incr = (k) => { |
| 61 | + let c = get(k) |
| 62 | + if (c == null) { |
| 63 | + set(k, 1) |
| 64 | + return 1 |
| 65 | + } else { |
| 66 | + c = c + 1 |
| 67 | + set(k, c) |
| 68 | + return c |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +// https://redis.io/commands/setex |
| 73 | +const setex = (k, ttl, value) => { |
| 74 | + const res = set(k, value) |
| 75 | + expire(k, ttl) |
| 76 | + return res |
| 77 | +} |
| 78 | + |
| 79 | +// https://redis.io/commands/del |
| 80 | +const del = (k) => { |
| 81 | + if (k in kv) { |
| 82 | + clearTimeout(k) |
| 83 | + delete kv.k |
| 84 | + return 1 |
| 85 | + } else return 0 |
| 86 | +} |
| 87 | + |
| 88 | +// https://redis.io/commands/expire |
| 89 | +const expire = (k, t) => { |
| 90 | + if (k in kv) { |
| 91 | + clearTimeout(k) |
| 92 | + kv[k].timer = setTimeout(() => del(k), t * 1000) |
| 93 | + return 1 |
| 94 | + } else return 0 |
| 95 | +} |
| 96 | + |
| 97 | +// https://redis.io/commands/sadd |
| 98 | +const sadd = (k, v) => { |
| 99 | + if (kv[k] === undefined) { |
| 100 | + kv[k] = new Set() |
| 101 | + } |
| 102 | + |
| 103 | + const s = kv[k] |
| 104 | + const n = s.size |
| 105 | + s.add(v) |
| 106 | + return s.size - n |
| 107 | +} |
| 108 | + |
| 109 | +// https://redis.io/commands/srem |
| 110 | +const srem = (k, v) => { |
| 111 | + const s = kv[k] |
| 112 | + if (s !== undefined) { |
| 113 | + const n = s.size |
| 114 | + s.remove(v) |
| 115 | + return s.size - n |
| 116 | + } else return 0 |
| 117 | +} |
| 118 | + |
| 119 | +// https://redis.io/commands/smembers |
| 120 | +const smembers = (k) => { |
| 121 | + const s = kv[k] |
| 122 | + if (s) return Array.from(s.keys()) |
| 123 | + else return [] |
| 124 | +} |
| 125 | + |
| 126 | +// https://redis.io/commands/rpush |
| 127 | +const rpush = (k, v) => { |
| 128 | + if (kv[k] === undefined) { |
| 129 | + kv[k] = [] |
| 130 | + } |
| 131 | + |
| 132 | + const l = kv[k] |
| 133 | + l.push(v) |
| 134 | + return l.length |
| 135 | +} |
| 136 | + |
| 137 | +// https://redis.io/commands/lpush |
| 138 | +const lpush = (k, v) => { |
| 139 | + if (kv[k] === undefined) { |
| 140 | + kv[k] = [] |
| 141 | + } |
| 142 | + |
| 143 | + const l = kv[k] |
| 144 | + l.unshift(v) |
| 145 | + return l.length |
| 146 | +} |
| 147 | + |
| 148 | +// https://redis.io/commands/lrange |
| 149 | +const lrange = (k, i, j) => { |
| 150 | + const l = kv[k] |
| 151 | + if (l !== undefined) { |
| 152 | + // TODO: this is not quite the same as redis |
| 153 | + return l.slice(i, j) |
| 154 | + } else return [] |
| 155 | +} |
| 156 | + |
| 157 | +// https://redis.io/commands/llen |
| 158 | +const llen = (k) => { |
| 159 | + const l = kv[k] |
| 160 | + if (l === undefined) { |
| 161 | + return 0 |
| 162 | + } else if (Array.isArray(l)) { |
| 163 | + return l.length |
| 164 | + } else { |
| 165 | + throw new Error('not an array') |
| 166 | + } |
| 167 | +} |
| 168 | + |
| 169 | +module.exports = { |
| 170 | + redis: () => ({ |
| 171 | + flushall, |
| 172 | + keys, |
| 173 | + get, |
| 174 | + set, |
| 175 | + incr, |
| 176 | + setex, |
| 177 | + del, |
| 178 | + expire, |
| 179 | + sadd, |
| 180 | + srem, |
| 181 | + smembers, |
| 182 | + rpush, |
| 183 | + lpush, |
| 184 | + lrange, |
| 185 | + llen, |
| 186 | + flushallAsync: flushall, |
| 187 | + keysAsync: (k) => Promise.resolve(keys(k)), |
| 188 | + getAsync: (k) => Promise.resolve(get(k)), |
| 189 | + setAsync: (k, v) => Promise.resolve(set(k, v)), |
| 190 | + incrAsync: (k) => Promise.resolve(incr(k)), |
| 191 | + setexAsync: (k, t, v) => Promise.resolve(setex(k, t, v)), |
| 192 | + delAsync: (k) => Promise.resolve(del(k)), |
| 193 | + expireAsync: (k, t) => Promise.resolve(expire(k, t)), |
| 194 | + smembersAsync: (s) => Promise.resolve(smembers(s)), |
| 195 | + rpushAsync: (k, v) => Promise.resolve(rpush(k, v)), |
| 196 | + lpushAsync: (k, v) => Promise.resolve(lpush(k, v)), |
| 197 | + lrangeAsync: (k, i, j) => Promise.resolve(lrange(k, i, j)), |
| 198 | + llenAsync: (k) => { |
| 199 | + try { |
| 200 | + const result = llen(k) |
| 201 | + return Promise.resolve(result) |
| 202 | + } catch (e) { |
| 203 | + return Promise.reject(e.message) |
| 204 | + } |
| 205 | + } |
| 206 | + }), |
| 207 | + storage: () => ({ |
| 208 | + id: `bucket`, |
| 209 | + setMetadata: () => Promise.resolve({}), |
| 210 | + file: (filename) => ({ |
| 211 | + getSignedUrl: (options) => Promise.resolve([`signed-${filename}-${options.action}`]) |
| 212 | + }) |
| 213 | + }) |
| 214 | +} |
0 commit comments