ts-cache-mongoose 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -1
- package/dist/index.cjs +73 -17
- package/dist/index.d.cts +4 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +73 -17
- package/dist/nest/index.cjs +1 -0
- package/dist/nest/index.mjs +1 -0
- package/package.json +20 -26
- package/biome.json +0 -47
- package/src/cache/Cache.ts +0 -72
- package/src/cache/engine/MemoryCacheEngine.ts +0 -41
- package/src/cache/engine/RedisCacheEngine.ts +0 -52
- package/src/extend/aggregate.ts +0 -51
- package/src/extend/query.ts +0 -81
- package/src/index.ts +0 -68
- package/src/key.ts +0 -10
- package/src/ms.ts +0 -66
- package/src/nest/cache.module.ts +0 -79
- package/src/nest/cache.service.ts +0 -37
- package/src/nest/index.ts +0 -4
- package/src/nest/interfaces.ts +0 -17
- package/src/sort-keys.ts +0 -38
- package/src/types.ts +0 -21
- package/src/version.ts +0 -18
- package/tests/cache-debug.test.ts +0 -73
- package/tests/cache-memory.test.ts +0 -217
- package/tests/cache-options.test.ts +0 -83
- package/tests/cache-redis.test.ts +0 -521
- package/tests/key.test.ts +0 -103
- package/tests/models/Story.ts +0 -29
- package/tests/models/User.ts +0 -39
- package/tests/mongo/.gitignore +0 -3
- package/tests/mongo/server.ts +0 -29
- package/tests/ms.test.ts +0 -113
- package/tests/nest.test.ts +0 -158
- package/tests/sort-keys.test.ts +0 -80
- package/tsconfig.json +0 -33
- package/vite.config.mts +0 -23
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import mongoose from 'mongoose'
|
|
4
|
-
import CacheMongoose from '../src/index'
|
|
5
|
-
import { UserModel } from './models/User'
|
|
6
|
-
import { server } from './mongo/server'
|
|
7
|
-
|
|
8
|
-
describe('cache-debug', async () => {
|
|
9
|
-
const instance = server('cache-debug')
|
|
10
|
-
let cache: CacheMongoose
|
|
11
|
-
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
cache = CacheMongoose.init(mongoose, {
|
|
14
|
-
engine: 'memory',
|
|
15
|
-
debug: true,
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
await instance.create()
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
afterAll(async () => {
|
|
22
|
-
await cache.clear()
|
|
23
|
-
await cache.close()
|
|
24
|
-
await instance.destroy()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
beforeEach(async () => {
|
|
28
|
-
vi.spyOn(global.console, 'log')
|
|
29
|
-
await mongoose.connection.collection('users').deleteMany({})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
afterEach(async () => {
|
|
33
|
-
vi.restoreAllMocks()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
describe('debug scenarios', () => {
|
|
37
|
-
it('should create a use and and query it two time first is cache miss second is hit, also clear by key and global', async () => {
|
|
38
|
-
const user = await UserModel.create({
|
|
39
|
-
name: 'John Doe',
|
|
40
|
-
role: 'admin',
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
const key = 'key'
|
|
44
|
-
const ttl = '1 second'
|
|
45
|
-
const cacheMissRegExp = /\[ts-cache-mongoose\] GET '.*?' - MISS/
|
|
46
|
-
const cacheHitRegExp = /\[ts-cache-mongoose\] GET '.*?' - HIT/
|
|
47
|
-
const cacheSetRegExp = /\[ts-cache-mongoose\] SET '.*?' - ttl: \d+ ms/
|
|
48
|
-
const cacheClearRegExp = /\[ts-cache-mongoose\] CLEAR/
|
|
49
|
-
const cacheDelRegExp = /\[ts-cache-mongoose\] DEL '.*?'/
|
|
50
|
-
|
|
51
|
-
const userCacheMiss = await UserModel.findById(user._id).cache(ttl, key).exec()
|
|
52
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringMatching(cacheMissRegExp))
|
|
53
|
-
expect(userCacheMiss).not.toBeNull()
|
|
54
|
-
expect(userCacheMiss?._id.toString()).toBe(user._id.toString())
|
|
55
|
-
expect(userCacheMiss?.name).toEqual(user.name)
|
|
56
|
-
expect(userCacheMiss?.role).toEqual(user.role)
|
|
57
|
-
|
|
58
|
-
const userCacheHit = await UserModel.findById(user._id).cache(ttl, key).exec()
|
|
59
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringMatching(cacheSetRegExp))
|
|
60
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringMatching(cacheHitRegExp))
|
|
61
|
-
expect(userCacheHit).not.toBeNull()
|
|
62
|
-
expect(userCacheHit?._id.toString()).toBe(user._id.toString())
|
|
63
|
-
expect(userCacheHit?.name).toEqual(user.name)
|
|
64
|
-
expect(userCacheHit?.role).toEqual(user.role)
|
|
65
|
-
|
|
66
|
-
await cache.clear(key)
|
|
67
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringMatching(cacheDelRegExp))
|
|
68
|
-
|
|
69
|
-
await cache.clear()
|
|
70
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringMatching(cacheClearRegExp))
|
|
71
|
-
})
|
|
72
|
-
})
|
|
73
|
-
})
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import mongoose from 'mongoose'
|
|
4
|
-
import CacheMongoose from '../src/index'
|
|
5
|
-
import { UserModel } from './models/User'
|
|
6
|
-
import { server } from './mongo/server'
|
|
7
|
-
|
|
8
|
-
describe('cache-memory', async () => {
|
|
9
|
-
const instance = server('cache-memory')
|
|
10
|
-
let cache: CacheMongoose
|
|
11
|
-
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
cache = CacheMongoose.init(mongoose, {
|
|
14
|
-
engine: 'memory',
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
await instance.create()
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
await cache.clear()
|
|
22
|
-
await cache.close()
|
|
23
|
-
await instance.destroy()
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
beforeEach(async () => {
|
|
27
|
-
await mongoose.connection.collection('users').deleteMany({})
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
describe('memory scenarios', () => {
|
|
31
|
-
it('should use memory cache', async () => {
|
|
32
|
-
const user = await UserModel.create({
|
|
33
|
-
name: 'John Doe',
|
|
34
|
-
role: 'admin',
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
const user1 = await UserModel.findById(user._id).cache().exec()
|
|
38
|
-
await UserModel.findOneAndUpdate({ _id: user._id }, { name: 'John Doe 2' }).exec()
|
|
39
|
-
const user2 = await UserModel.findById(user._id).cache().exec()
|
|
40
|
-
|
|
41
|
-
expect(user1).not.toBeNull()
|
|
42
|
-
expect(user2).not.toBeNull()
|
|
43
|
-
expect(user1?._id.toString()).toBe(user2?._id.toString())
|
|
44
|
-
expect(user1?.name).toEqual(user2?.name)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should not use cache', async () => {
|
|
48
|
-
const user = await UserModel.create({
|
|
49
|
-
name: 'John Doe',
|
|
50
|
-
role: 'admin',
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const cache1 = await UserModel.findById(user._id).cache().exec()
|
|
54
|
-
await UserModel.findByIdAndUpdate(user._id, { name: 'John Doe 2' }).exec()
|
|
55
|
-
await cache.clear()
|
|
56
|
-
const cache2 = await UserModel.findById(user._id).cache().exec()
|
|
57
|
-
|
|
58
|
-
expect(cache1).not.toBeNull()
|
|
59
|
-
expect(cache2).not.toBeNull()
|
|
60
|
-
expect(cache1?._id.toString()).toBe(cache2?._id.toString())
|
|
61
|
-
expect(cache1?.name).not.toEqual(cache2?.name)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should use memory cache with custom key', async () => {
|
|
65
|
-
const user = await UserModel.create({
|
|
66
|
-
name: 'John Doe',
|
|
67
|
-
role: 'admin',
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
const cache1 = await UserModel.findById(user._id).cache('1 minute', 'test-custom-key').exec()
|
|
71
|
-
await UserModel.findOneAndUpdate({ _id: user._id }, { name: 'John Doe 2' }).exec()
|
|
72
|
-
const cache2 = await UserModel.findById(user._id).cache('1 minute', 'test-custom-key').exec()
|
|
73
|
-
|
|
74
|
-
expect(cache1).not.toBeNull()
|
|
75
|
-
expect(cache2).not.toBeNull()
|
|
76
|
-
expect(cache1?._id.toString()).toBe(cache2?._id.toString())
|
|
77
|
-
expect(cache1?.name).toEqual(cache2?.name)
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('should use memory cache and clear custom key', async () => {
|
|
81
|
-
const user = await UserModel.create({
|
|
82
|
-
name: 'John Doe',
|
|
83
|
-
role: 'admin',
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
const cache1 = await UserModel.findById(user._id).cache('1 minute', 'test-custom-key-second').exec()
|
|
87
|
-
await UserModel.updateOne({ _id: user._id }, { name: 'John Doe 2' }).exec()
|
|
88
|
-
await cache.clear('test-custom-key-second')
|
|
89
|
-
const cache2 = await UserModel.findById(user._id).cache('1 minute', 'test-custom-key-second').exec()
|
|
90
|
-
|
|
91
|
-
expect(cache1).not.toBeNull()
|
|
92
|
-
expect(cache2).not.toBeNull()
|
|
93
|
-
expect(cache1?._id.toString()).toBe(cache2?._id.toString())
|
|
94
|
-
expect(cache1?.name).not.toEqual(cache2?.name)
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('should use memory cache and custom key with an empty string', async () => {
|
|
98
|
-
const user = await UserModel.create({
|
|
99
|
-
name: 'John Doe',
|
|
100
|
-
role: 'admin',
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
const cache1 = await UserModel.findById(user._id).cache('1 minute', '').exec()
|
|
104
|
-
await UserModel.updateOne({ _id: user._id }, { name: 'John Doe 2' }).exec()
|
|
105
|
-
const cache2 = await UserModel.findById(user._id).cache('1 minute', '').exec()
|
|
106
|
-
|
|
107
|
-
expect(cache1).not.toBeNull()
|
|
108
|
-
expect(cache2).not.toBeNull()
|
|
109
|
-
expect(cache1?._id.toString()).toBe(cache2?._id.toString())
|
|
110
|
-
expect(cache1?.name).toEqual(cache2?.name)
|
|
111
|
-
|
|
112
|
-
await cache.clear('')
|
|
113
|
-
const cache3 = await UserModel.findById(user._id).cache('1 minute', '').exec()
|
|
114
|
-
expect(cache3).not.toBeNull()
|
|
115
|
-
expect(cache2?._id.toString()).toBe(cache3?._id.toString())
|
|
116
|
-
expect(cache2?.name).not.toEqual(cache3?.name)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
it('should use memory cache and aggregate', async () => {
|
|
120
|
-
await UserModel.create([
|
|
121
|
-
{ name: 'John', role: 'admin' },
|
|
122
|
-
{ name: 'Bob', role: 'admin' },
|
|
123
|
-
{ name: 'Alice', role: 'user' },
|
|
124
|
-
])
|
|
125
|
-
|
|
126
|
-
const cache1 = await UserModel.aggregate([{ $match: { role: 'admin' } }, { $group: { _id: '$role', count: { $sum: 1 } } }])
|
|
127
|
-
.cache()
|
|
128
|
-
.exec()
|
|
129
|
-
|
|
130
|
-
await UserModel.create({ name: 'Mark', role: 'admin' })
|
|
131
|
-
|
|
132
|
-
const cache2 = await UserModel.aggregate([{ $match: { role: 'admin' } }, { $group: { _id: '$role', count: { $sum: 1 } } }])
|
|
133
|
-
.cache()
|
|
134
|
-
.exec()
|
|
135
|
-
|
|
136
|
-
expect(cache1).not.toBeNull()
|
|
137
|
-
expect(cache2).not.toBeNull()
|
|
138
|
-
expect(cache1?.[0].count).toEqual(cache2?.[0].count)
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
describe('memory scenarios with ttl', () => {
|
|
143
|
-
const users = [
|
|
144
|
-
{ name: 'John', age: 30, role: 'admin' },
|
|
145
|
-
{ name: 'Alice', age: 25, role: 'user' },
|
|
146
|
-
{ name: 'Bob', age: 35, role: 'user' },
|
|
147
|
-
]
|
|
148
|
-
|
|
149
|
-
beforeEach(async () => {
|
|
150
|
-
// Delete all users before each test
|
|
151
|
-
await UserModel.deleteMany().exec()
|
|
152
|
-
|
|
153
|
-
// Create new users
|
|
154
|
-
await UserModel.create(users)
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it('findById', async () => {
|
|
158
|
-
const john = await UserModel.create({ name: 'John', age: 30, role: 'admin' })
|
|
159
|
-
const user = await UserModel.findById(john._id).cache('1 minute').exec()
|
|
160
|
-
const cachedUser = await UserModel.findById(john._id).cache('1 minute').exec()
|
|
161
|
-
|
|
162
|
-
expect(user?._id.toString()).toBe(cachedUser?._id.toString())
|
|
163
|
-
expect(user?.name).toEqual(cachedUser?.name)
|
|
164
|
-
expect(user?.createdAt).toEqual(cachedUser?.createdAt)
|
|
165
|
-
expect(user?.updatedAt).toEqual(cachedUser?.updatedAt)
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
it('findOne', async () => {
|
|
169
|
-
const user = await UserModel.findOne({ name: 'John', age: 30, role: 'admin' }).cache('1 minute').exec()
|
|
170
|
-
await UserModel.create({ name: 'Steve', age: 30, role: 'admin' })
|
|
171
|
-
const cachedUser = await UserModel.findOne({
|
|
172
|
-
name: 'John',
|
|
173
|
-
age: 30,
|
|
174
|
-
role: 'admin',
|
|
175
|
-
})
|
|
176
|
-
.cache('1 minute')
|
|
177
|
-
.exec()
|
|
178
|
-
|
|
179
|
-
expect(user?._id.toString()).toBe(cachedUser?._id.toString())
|
|
180
|
-
expect(user?.name).toEqual(cachedUser?.name)
|
|
181
|
-
expect(user?.createdAt).toEqual(cachedUser?.createdAt)
|
|
182
|
-
expect(user?.updatedAt).toEqual(cachedUser?.updatedAt)
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
it('find', async () => {
|
|
186
|
-
const users = await UserModel.find({ age: { $gte: 30 } })
|
|
187
|
-
.cache('1 minute')
|
|
188
|
-
.exec()
|
|
189
|
-
await UserModel.create({ name: 'Steve', age: 30, role: 'admin' })
|
|
190
|
-
const cachedUsers = await UserModel.find({ age: { $gte: 30 } })
|
|
191
|
-
.cache('1 minute')
|
|
192
|
-
.exec()
|
|
193
|
-
|
|
194
|
-
expect(users).toHaveLength(cachedUsers.length)
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
it('count', async () => {
|
|
198
|
-
const count = await UserModel.countDocuments({ age: { $gte: 30 } })
|
|
199
|
-
.cache('1 minute')
|
|
200
|
-
.exec()
|
|
201
|
-
await UserModel.create({ name: 'Steve', age: 30, role: 'admin' })
|
|
202
|
-
const cachedCount = await UserModel.countDocuments({ age: { $gte: 30 } })
|
|
203
|
-
.cache('1 minute')
|
|
204
|
-
.exec()
|
|
205
|
-
|
|
206
|
-
expect(count).toEqual(cachedCount)
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
it('distinct', async () => {
|
|
210
|
-
const emails = await UserModel.distinct('name').cache('1 minute').exec()
|
|
211
|
-
await UserModel.create({ name: 'Steve', age: 30, role: 'admin' })
|
|
212
|
-
const cachedEmails = await UserModel.distinct('name').cache('1 minute').exec()
|
|
213
|
-
|
|
214
|
-
expect(emails).toEqual(cachedEmails)
|
|
215
|
-
})
|
|
216
|
-
})
|
|
217
|
-
})
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import { Cache } from '../src/cache/Cache'
|
|
4
|
-
|
|
5
|
-
import type { CacheOptions } from '../src/types'
|
|
6
|
-
|
|
7
|
-
describe('Cache class tests', () => {
|
|
8
|
-
it('should create a new instance of Cache', () => {
|
|
9
|
-
const cacheOptions: CacheOptions = {
|
|
10
|
-
engine: 'memory',
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const cache = new Cache(cacheOptions)
|
|
14
|
-
expect(cache).toBeInstanceOf(Cache)
|
|
15
|
-
expect(cache).toHaveProperty('get')
|
|
16
|
-
expect(cache).toHaveProperty('set')
|
|
17
|
-
expect(cache).toHaveProperty('del')
|
|
18
|
-
expect(cache).toHaveProperty('clear')
|
|
19
|
-
expect(cache).toHaveProperty('close')
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('should throw an error if the cache engine is not supported', () => {
|
|
23
|
-
const cacheOptions: CacheOptions = {
|
|
24
|
-
// @ts-expect-error Testing invalid engine name
|
|
25
|
-
engine: 'not-supported',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
expect(() => new Cache(cacheOptions)).toThrow(`Invalid engine name: ${cacheOptions.engine}`)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should throw an error if the cache engine is redis and no engine options are provided', () => {
|
|
32
|
-
const cacheOptions: CacheOptions = {
|
|
33
|
-
engine: 'redis',
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
expect(() => new Cache(cacheOptions)).toThrow(`Engine options are required for ${cacheOptions.engine} engine`)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('should create a new instance of Cache with redis engine', async () => {
|
|
40
|
-
const cacheOptions: CacheOptions = {
|
|
41
|
-
engine: 'redis',
|
|
42
|
-
engineOptions: {
|
|
43
|
-
host: 'localhost',
|
|
44
|
-
port: 6379,
|
|
45
|
-
},
|
|
46
|
-
defaultTTL: '10 minutes',
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const cache = new Cache(cacheOptions)
|
|
50
|
-
expect(cache).toBeInstanceOf(Cache)
|
|
51
|
-
expect(cache).toHaveProperty('get')
|
|
52
|
-
expect(cache).toHaveProperty('set')
|
|
53
|
-
expect(cache).toHaveProperty('del')
|
|
54
|
-
expect(cache).toHaveProperty('clear')
|
|
55
|
-
expect(cache).toHaveProperty('close')
|
|
56
|
-
|
|
57
|
-
await cache.set('bob', { test: 'bob' }, null)
|
|
58
|
-
await cache.set('john', { test: 'john' }, '1 minute')
|
|
59
|
-
|
|
60
|
-
const value = await cache.get('bob')
|
|
61
|
-
expect(value).toEqual({ test: 'bob' })
|
|
62
|
-
|
|
63
|
-
await cache.del('bob')
|
|
64
|
-
const clearBob = await cache.get('bob')
|
|
65
|
-
expect(clearBob).toBeUndefined()
|
|
66
|
-
|
|
67
|
-
const john = await cache.get('john')
|
|
68
|
-
expect(john).toEqual({ test: 'john' })
|
|
69
|
-
|
|
70
|
-
await cache.clear()
|
|
71
|
-
const clearJohn = await cache.get('john')
|
|
72
|
-
expect(clearJohn).toBeUndefined()
|
|
73
|
-
|
|
74
|
-
const mockSet = vi.fn()
|
|
75
|
-
cache.set = mockSet
|
|
76
|
-
|
|
77
|
-
await cache.set('bob', { test: 'bob' }, null)
|
|
78
|
-
expect(mockSet).toHaveBeenCalled()
|
|
79
|
-
expect(mockSet).toHaveBeenCalledWith('bob', { test: 'bob' }, null)
|
|
80
|
-
|
|
81
|
-
await cache.close()
|
|
82
|
-
})
|
|
83
|
-
})
|