@stacksjs/cache 0.64.6 → 0.65.0
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/dist/drivers/dynamodb.d.ts +2 -0
- package/dist/drivers/filesystem.d.ts +2 -0
- package/dist/drivers/index.d.ts +2 -0
- package/dist/drivers/memory.d.ts +2 -0
- package/dist/drivers/redis.d.ts +2 -0
- package/dist/drivers/type.d.ts +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +702 -17
- package/dist/index.js.map +265 -202
- package/package.json +11 -15
- package/src/drivers/dynamodb.ts +65 -89
- package/src/drivers/filesystem.ts +66 -0
- package/src/drivers/index.ts +29 -1
- package/src/drivers/memory.ts +66 -0
- package/src/drivers/redis.ts +65 -0
- package/src/drivers/type.ts +12 -5
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/cache",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.65.0",
|
|
5
5
|
"description": "Caching the Stacks way.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
|
+
"contributors": ["Chris Breuer <chris@stacksjs.org>"],
|
|
7
8
|
"license": "MIT",
|
|
8
9
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
|
9
10
|
"homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/cache#readme",
|
|
@@ -35,25 +36,20 @@
|
|
|
35
36
|
},
|
|
36
37
|
"module": "dist/index.js",
|
|
37
38
|
"types": "dist/index.d.ts",
|
|
38
|
-
"
|
|
39
|
-
"Chris Breuer <chris@stacksjs.org>"
|
|
40
|
-
],
|
|
41
|
-
"files": [
|
|
42
|
-
"README.md",
|
|
43
|
-
"dist",
|
|
44
|
-
"src"
|
|
45
|
-
],
|
|
39
|
+
"files": ["README.md", "dist", "src"],
|
|
46
40
|
"scripts": {
|
|
47
|
-
"build": "bun
|
|
48
|
-
"typecheck": "bun
|
|
41
|
+
"build": "bun build.ts",
|
|
42
|
+
"typecheck": "bun tsc --noEmit",
|
|
49
43
|
"prepublishOnly": "bun run build"
|
|
50
44
|
},
|
|
51
45
|
"dependencies": {
|
|
52
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
53
|
-
"@stacksjs/config": "
|
|
54
|
-
"bentocache": "^1.0.0-beta.9"
|
|
46
|
+
"@aws-sdk/client-dynamodb": "^3.668.0",
|
|
47
|
+
"@stacksjs/config": "0.64.6",
|
|
48
|
+
"bentocache": "^1.0.0-beta.9",
|
|
49
|
+
"ioredis": "^5.4.1"
|
|
55
50
|
},
|
|
56
51
|
"devDependencies": {
|
|
57
|
-
"@stacksjs/development": "
|
|
52
|
+
"@stacksjs/development": "0.64.6",
|
|
53
|
+
"dynamodb-tooling": "^0.3.2"
|
|
58
54
|
}
|
|
59
55
|
}
|
package/src/drivers/dynamodb.ts
CHANGED
|
@@ -1,104 +1,80 @@
|
|
|
1
|
-
import type { PutItemCommandInput } from '@aws-sdk/client-dynamodb'
|
|
2
|
-
import { DynamoDB, ListTablesCommand } from '@aws-sdk/client-dynamodb'
|
|
3
|
-
import { cache } from '@stacksjs/config'
|
|
4
1
|
import type { CacheDriver } from './type'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const tables = await client.send(new ListTablesCommand({}))
|
|
25
|
-
|
|
26
|
-
const tableExists = tables.TableNames?.includes('cache')
|
|
27
|
-
|
|
28
|
-
if (tableExists) return
|
|
29
|
-
|
|
30
|
-
const params = {
|
|
31
|
-
AttributeDefinitions: [
|
|
32
|
-
{
|
|
33
|
-
AttributeName: 'key',
|
|
34
|
-
AttributeType: 'S',
|
|
2
|
+
import process from 'node:process'
|
|
3
|
+
import { BentoCache, bentostore } from 'bentocache'
|
|
4
|
+
import { dynamoDbDriver } from 'bentocache/drivers/dynamodb'
|
|
5
|
+
|
|
6
|
+
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID || 'dummy'
|
|
7
|
+
const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY || 'dummy'
|
|
8
|
+
const dynamoEndpoint = process.env.AWS_DYNAMODB_ENDPOINT || 'http://localhost:8000'
|
|
9
|
+
const tableName = process.env.AWS_DYNAMODB_TABLE || 'stacks'
|
|
10
|
+
const region = process.env.AWS_REGION || 'us-east-1'
|
|
11
|
+
|
|
12
|
+
const client = new BentoCache({
|
|
13
|
+
default: 'dynamo',
|
|
14
|
+
stores: {
|
|
15
|
+
dynamo: bentostore().useL2Layer(
|
|
16
|
+
dynamoDbDriver({
|
|
17
|
+
endpoint: dynamoEndpoint,
|
|
18
|
+
region,
|
|
19
|
+
table: {
|
|
20
|
+
name: tableName,
|
|
35
21
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
AttributeName: 'key',
|
|
40
|
-
KeyType: 'HASH',
|
|
22
|
+
credentials: {
|
|
23
|
+
accessKeyId: awsAccessKeyId,
|
|
24
|
+
secretAccessKey: awsSecretAccessKey,
|
|
41
25
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
ReadCapacityUnits: 5,
|
|
45
|
-
WriteCapacityUnits: 5,
|
|
46
|
-
},
|
|
47
|
-
TableName: tableName,
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
client.createTable(params)
|
|
26
|
+
}),
|
|
27
|
+
),
|
|
51
28
|
},
|
|
29
|
+
})
|
|
52
30
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
await client.putItem(params)
|
|
31
|
+
export const dynamodb: CacheDriver = {
|
|
32
|
+
async set(key: string, value: string, ttl?: number): Promise<void> {
|
|
33
|
+
await client.set({
|
|
34
|
+
key,
|
|
35
|
+
value,
|
|
36
|
+
gracePeriod: { enabled: true, duration: '5m' },
|
|
37
|
+
})
|
|
38
|
+
},
|
|
39
|
+
async setForever(key: string, value: string, ttl?: number): Promise<void> {
|
|
40
|
+
await client.setForever({
|
|
41
|
+
key,
|
|
42
|
+
value,
|
|
43
|
+
})
|
|
67
44
|
},
|
|
68
|
-
|
|
69
45
|
async get(key: string): Promise<string | undefined | null> {
|
|
70
|
-
const
|
|
71
|
-
TableName: tableName,
|
|
72
|
-
Key: {
|
|
73
|
-
[keyAttribute]: {
|
|
74
|
-
S: key,
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const response = await client.getItem(params)
|
|
46
|
+
const items = await client.get<string>(key)
|
|
80
47
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return response.Item[valueAttribute].S ?? response.Item[valueAttribute].N
|
|
48
|
+
return items
|
|
84
49
|
},
|
|
50
|
+
async getOrSet(key: string, value: string): Promise<string | undefined | null> {
|
|
51
|
+
const items = await client.getOrSet(key, () => value)
|
|
85
52
|
|
|
53
|
+
return items
|
|
54
|
+
},
|
|
55
|
+
async del(key: string): Promise<void> {
|
|
56
|
+
await client.delete({ key })
|
|
57
|
+
},
|
|
58
|
+
async deleteMany(keys: string[]): Promise<void> {
|
|
59
|
+
await client.deleteMany({ keys })
|
|
60
|
+
},
|
|
86
61
|
async remove(key: string): Promise<void> {
|
|
87
|
-
|
|
88
|
-
TableName: tableName,
|
|
89
|
-
Key: {
|
|
90
|
-
[keyAttribute]: {
|
|
91
|
-
S: key,
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
await client.deleteItem(params)
|
|
62
|
+
await client.delete({ key })
|
|
97
63
|
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
64
|
+
async has(key: string): Promise<boolean> {
|
|
65
|
+
return await client.has({ key })
|
|
66
|
+
},
|
|
67
|
+
async missing(key: string): Promise<boolean> {
|
|
68
|
+
return await client.missing({ key })
|
|
69
|
+
},
|
|
70
|
+
async deleteAll(): Promise<void> {
|
|
71
|
+
await client.clear()
|
|
72
|
+
},
|
|
73
|
+
async clear(): Promise<void> {
|
|
74
|
+
await client.clear()
|
|
75
|
+
},
|
|
76
|
+
async disconnect(): Promise<void> {
|
|
77
|
+
await client.disconnect()
|
|
101
78
|
},
|
|
102
|
-
|
|
103
79
|
client,
|
|
104
80
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { CacheDriver } from './type'
|
|
2
|
+
import { BentoCache, bentostore } from 'bentocache'
|
|
3
|
+
import { fileDriver } from 'bentocache/drivers/file'
|
|
4
|
+
|
|
5
|
+
const client = new BentoCache({
|
|
6
|
+
default: 'redis',
|
|
7
|
+
stores: {
|
|
8
|
+
redis: bentostore().useL2Layer(
|
|
9
|
+
fileDriver({
|
|
10
|
+
directory: './cache',
|
|
11
|
+
pruneInterval: '1h',
|
|
12
|
+
}),
|
|
13
|
+
),
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export const fileSystem: CacheDriver = {
|
|
18
|
+
async set(key: string, value: string, ttl?: number): Promise<void> {
|
|
19
|
+
await client.set({
|
|
20
|
+
key,
|
|
21
|
+
value,
|
|
22
|
+
gracePeriod: { enabled: true, duration: '5m' },
|
|
23
|
+
})
|
|
24
|
+
},
|
|
25
|
+
async setForever(key: string, value: string, ttl?: number): Promise<void> {
|
|
26
|
+
await client.setForever({
|
|
27
|
+
key,
|
|
28
|
+
value,
|
|
29
|
+
})
|
|
30
|
+
},
|
|
31
|
+
async get(key: string): Promise<string | undefined | null> {
|
|
32
|
+
const items = await client.get<string>(key)
|
|
33
|
+
|
|
34
|
+
return items
|
|
35
|
+
},
|
|
36
|
+
async getOrSet(key: string, value: string): Promise<string | undefined | null> {
|
|
37
|
+
const items = await client.getOrSet(key, () => value)
|
|
38
|
+
|
|
39
|
+
return items
|
|
40
|
+
},
|
|
41
|
+
async del(key: string): Promise<void> {
|
|
42
|
+
await client.delete({ key })
|
|
43
|
+
},
|
|
44
|
+
async deleteMany(keys: string[]): Promise<void> {
|
|
45
|
+
await client.deleteMany({ keys })
|
|
46
|
+
},
|
|
47
|
+
async remove(key: string): Promise<void> {
|
|
48
|
+
await client.delete({ key })
|
|
49
|
+
},
|
|
50
|
+
async has(key: string): Promise<boolean> {
|
|
51
|
+
return await client.has({ key })
|
|
52
|
+
},
|
|
53
|
+
async missing(key: string): Promise<boolean> {
|
|
54
|
+
return await client.missing({ key })
|
|
55
|
+
},
|
|
56
|
+
async deleteAll(): Promise<void> {
|
|
57
|
+
await client.clear()
|
|
58
|
+
},
|
|
59
|
+
async clear(): Promise<void> {
|
|
60
|
+
await client.clear()
|
|
61
|
+
},
|
|
62
|
+
async disconnect(): Promise<void> {
|
|
63
|
+
await client.disconnect()
|
|
64
|
+
},
|
|
65
|
+
client,
|
|
66
|
+
}
|
package/src/drivers/index.ts
CHANGED
|
@@ -1 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
import type { CacheDriver } from './type'
|
|
2
|
+
import { config } from '@stacksjs/config'
|
|
3
|
+
import { dynamodb } from './dynamodb'
|
|
4
|
+
import { fileSystem } from './filesystem'
|
|
5
|
+
import { memory } from './memory'
|
|
6
|
+
|
|
7
|
+
import { redis } from './redis'
|
|
8
|
+
|
|
9
|
+
const driver = config.cache.driver || 'memory'
|
|
10
|
+
|
|
11
|
+
let driverInstance = fileSystem
|
|
12
|
+
|
|
13
|
+
if (driver === 'redis') {
|
|
14
|
+
driverInstance = redis
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (driver === 'fileSystem') {
|
|
18
|
+
driverInstance = fileSystem
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (driver === 'memory') {
|
|
22
|
+
driverInstance = memory
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (driver === 'dynamodb') {
|
|
26
|
+
driverInstance = dynamodb
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const cache: CacheDriver = driverInstance
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { CacheDriver } from './type'
|
|
2
|
+
import { BentoCache, bentostore } from 'bentocache'
|
|
3
|
+
import { memoryDriver } from 'bentocache/drivers/memory'
|
|
4
|
+
|
|
5
|
+
const client = new BentoCache({
|
|
6
|
+
default: 'memory',
|
|
7
|
+
stores: {
|
|
8
|
+
memory: bentostore().useL1Layer(
|
|
9
|
+
memoryDriver({
|
|
10
|
+
maxSize: 10 * 1024 * 1024,
|
|
11
|
+
maxItems: 1000,
|
|
12
|
+
}),
|
|
13
|
+
),
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export const memory: CacheDriver = {
|
|
18
|
+
async set(key: string, value: string, ttl?: number): Promise<void> {
|
|
19
|
+
await client.set({
|
|
20
|
+
key,
|
|
21
|
+
value,
|
|
22
|
+
gracePeriod: { enabled: true, duration: '5m' },
|
|
23
|
+
})
|
|
24
|
+
},
|
|
25
|
+
async setForever(key: string, value: string, ttl?: number): Promise<void> {
|
|
26
|
+
await client.setForever({
|
|
27
|
+
key,
|
|
28
|
+
value,
|
|
29
|
+
})
|
|
30
|
+
},
|
|
31
|
+
async get(key: string): Promise<string | undefined | null> {
|
|
32
|
+
const items = await client.get<string>(key)
|
|
33
|
+
|
|
34
|
+
return items
|
|
35
|
+
},
|
|
36
|
+
async getOrSet(key: string, value: string): Promise<string | undefined | null> {
|
|
37
|
+
const items = await client.getOrSet(key, () => value)
|
|
38
|
+
|
|
39
|
+
return items
|
|
40
|
+
},
|
|
41
|
+
async del(key: string): Promise<void> {
|
|
42
|
+
await client.delete({ key })
|
|
43
|
+
},
|
|
44
|
+
async deleteMany(keys: string[]): Promise<void> {
|
|
45
|
+
await client.deleteMany({ keys })
|
|
46
|
+
},
|
|
47
|
+
async remove(key: string): Promise<void> {
|
|
48
|
+
await client.delete({ key })
|
|
49
|
+
},
|
|
50
|
+
async has(key: string): Promise<boolean> {
|
|
51
|
+
return await client.has({ key })
|
|
52
|
+
},
|
|
53
|
+
async missing(key: string): Promise<boolean> {
|
|
54
|
+
return await client.missing({ key })
|
|
55
|
+
},
|
|
56
|
+
async deleteAll(): Promise<void> {
|
|
57
|
+
await client.clear()
|
|
58
|
+
},
|
|
59
|
+
async clear(): Promise<void> {
|
|
60
|
+
await client.clear()
|
|
61
|
+
},
|
|
62
|
+
async disconnect(): Promise<void> {
|
|
63
|
+
await client.disconnect()
|
|
64
|
+
},
|
|
65
|
+
client,
|
|
66
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { CacheDriver } from './type'
|
|
2
|
+
import { BentoCache, bentostore } from 'bentocache'
|
|
3
|
+
import { redisDriver } from 'bentocache/drivers/redis'
|
|
4
|
+
|
|
5
|
+
const client = new BentoCache({
|
|
6
|
+
default: 'redis',
|
|
7
|
+
stores: {
|
|
8
|
+
redis: bentostore().useL2Layer(
|
|
9
|
+
redisDriver({
|
|
10
|
+
connection: { host: '127.0.0.1', port: 6379 },
|
|
11
|
+
}),
|
|
12
|
+
),
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const redis: CacheDriver = {
|
|
17
|
+
async set(key: string, value: string, ttl?: number): Promise<void> {
|
|
18
|
+
await client.set({
|
|
19
|
+
key,
|
|
20
|
+
value,
|
|
21
|
+
gracePeriod: { enabled: true, duration: '5m' },
|
|
22
|
+
})
|
|
23
|
+
},
|
|
24
|
+
async setForever(key: string, value: string, ttl?: number): Promise<void> {
|
|
25
|
+
await client.setForever({
|
|
26
|
+
key,
|
|
27
|
+
value,
|
|
28
|
+
})
|
|
29
|
+
},
|
|
30
|
+
async get(key: string): Promise<string | undefined | null> {
|
|
31
|
+
const items = await client.get<string>(key)
|
|
32
|
+
|
|
33
|
+
return items
|
|
34
|
+
},
|
|
35
|
+
async getOrSet(key: string, value: string): Promise<string | undefined | null> {
|
|
36
|
+
const items = await client.getOrSet(key, () => value)
|
|
37
|
+
|
|
38
|
+
return items
|
|
39
|
+
},
|
|
40
|
+
async del(key: string): Promise<void> {
|
|
41
|
+
await client.delete({ key })
|
|
42
|
+
},
|
|
43
|
+
async deleteMany(keys: string[]): Promise<void> {
|
|
44
|
+
await client.deleteMany({ keys })
|
|
45
|
+
},
|
|
46
|
+
async remove(key: string): Promise<void> {
|
|
47
|
+
await client.delete({ key })
|
|
48
|
+
},
|
|
49
|
+
async has(key: string): Promise<boolean> {
|
|
50
|
+
return await client.has({ key })
|
|
51
|
+
},
|
|
52
|
+
async missing(key: string): Promise<boolean> {
|
|
53
|
+
return await client.missing({ key })
|
|
54
|
+
},
|
|
55
|
+
async deleteAll(): Promise<void> {
|
|
56
|
+
await client.clear()
|
|
57
|
+
},
|
|
58
|
+
async clear(): Promise<void> {
|
|
59
|
+
await client.clear()
|
|
60
|
+
},
|
|
61
|
+
async disconnect(): Promise<void> {
|
|
62
|
+
await client.disconnect()
|
|
63
|
+
},
|
|
64
|
+
client,
|
|
65
|
+
}
|
package/src/drivers/type.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BentoCache } from 'bentocache'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export interface CacheDriver {
|
|
4
|
+
set: (key: string, value: string, ttl?: number) => Promise<void>
|
|
5
|
+
setForever: (key: string, value: string, ttl?: number) => Promise<void>
|
|
6
6
|
get: (key: string) => Promise<string | undefined | null>
|
|
7
|
+
getOrSet: (key: string, value: string) => Promise<string | undefined | null>
|
|
7
8
|
remove: (key: string) => Promise<void>
|
|
9
|
+
has: (key: string) => Promise<boolean>
|
|
10
|
+
missing: (key: string) => Promise<boolean>
|
|
8
11
|
del: (key: string) => Promise<void>
|
|
9
|
-
|
|
12
|
+
deleteMany: (keys: string[]) => Promise<void>
|
|
13
|
+
clear: () => Promise<void>
|
|
14
|
+
deleteAll: () => Promise<void>
|
|
15
|
+
disconnect: () => Promise<void>
|
|
16
|
+
client: BentoCache<Record<string, any>>
|
|
10
17
|
}
|
package/src/index.ts
CHANGED