mirror of
https://github.com/umami-software/umami.git
synced 2026-02-25 06:55:35 +01:00
deprecate @umami/redis-client, add redis lib
Some checks failed
Node.js CI / build (push) Has been cancelled
Some checks failed
Node.js CI / build (push) Has been cancelled
This commit is contained in:
parent
99a328359b
commit
8530329e14
3 changed files with 109 additions and 19 deletions
|
|
@ -67,7 +67,6 @@
|
|||
"@svgr/cli": "^8.1.0",
|
||||
"@tanstack/react-query": "^5.90.21",
|
||||
"@umami/react-zen": "^0.245.0",
|
||||
"@umami/redis-client": "^0.30.0",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"chalk": "^5.6.2",
|
||||
"chart.js": "^4.5.1",
|
||||
|
|
@ -110,6 +109,7 @@
|
|||
"react-simple-maps": "^2.3.0",
|
||||
"react-use-measure": "^2.0.4",
|
||||
"react-window": "^1.8.6",
|
||||
"redis": "^4.5.1",
|
||||
"request-ip": "^3.3.0",
|
||||
"semver": "^7.7.4",
|
||||
"serialize-error": "^12.0.0",
|
||||
|
|
|
|||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
|
|
@ -44,9 +44,6 @@ importers:
|
|||
'@umami/react-zen':
|
||||
specifier: ^0.245.0
|
||||
version: 0.245.0(@types/react@19.2.14)(immer@10.2.0)(react-aria-components@1.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.1.18)(use-sync-external-store@1.6.0(react@19.2.4))
|
||||
'@umami/redis-client':
|
||||
specifier: ^0.30.0
|
||||
version: 0.30.0
|
||||
bcryptjs:
|
||||
specifier: ^3.0.2
|
||||
version: 3.0.3
|
||||
|
|
@ -173,6 +170,9 @@ importers:
|
|||
react-window:
|
||||
specifier: ^1.8.6
|
||||
version: 1.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
redis:
|
||||
specifier: ^4.5.1
|
||||
version: 4.7.1
|
||||
request-ip:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
|
|
@ -328,8 +328,6 @@ importers:
|
|||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
|
||||
dist: {}
|
||||
|
||||
packages:
|
||||
|
||||
'@ampproject/remapping@2.3.0':
|
||||
|
|
@ -2965,9 +2963,6 @@ packages:
|
|||
react-aria-components: ^1.0.0
|
||||
react-dom: ^18.0.0 || ^19.0.0
|
||||
|
||||
'@umami/redis-client@0.30.0':
|
||||
resolution: {integrity: sha512-pqeMPdEFMH+9GDpiQd5MdRdTppif4vPl/sp8Y9hPY277g/UFlJAbCUJluESmZRBHjFdXtBPtLzQkxjvdjlRzuQ==}
|
||||
|
||||
acorn-walk@8.3.4:
|
||||
resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
|
@ -10062,13 +10057,6 @@ snapshots:
|
|||
- tailwindcss
|
||||
- use-sync-external-store
|
||||
|
||||
'@umami/redis-client@0.30.0':
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@8.1.1)
|
||||
redis: 4.7.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
acorn-walk@8.3.4:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
|
|
|
|||
108
src/lib/redis.ts
108
src/lib/redis.ts
|
|
@ -1,10 +1,112 @@
|
|||
import { UmamiRedisClient } from '@umami/redis-client';
|
||||
import debug from 'debug';
|
||||
import { createClient, type RedisClientType } from 'redis';
|
||||
|
||||
const log = debug('umami:redis-client');
|
||||
|
||||
export const DELETED = '__DELETED__';
|
||||
export const DEFAULT_TTL = 3600;
|
||||
|
||||
const logError = (err: unknown) => log(err);
|
||||
|
||||
class UmamiRedisClient {
|
||||
url: string;
|
||||
client: RedisClientType;
|
||||
isConnected: boolean;
|
||||
|
||||
constructor(url: string) {
|
||||
const client = createClient({ url }).on('error', logError);
|
||||
|
||||
this.url = url;
|
||||
this.client = client as RedisClientType;
|
||||
this.isConnected = false;
|
||||
}
|
||||
|
||||
async connect() {
|
||||
if (!this.isConnected) {
|
||||
this.isConnected = true;
|
||||
|
||||
await this.client.connect();
|
||||
|
||||
log('Redis connected');
|
||||
}
|
||||
}
|
||||
|
||||
async get(key: string) {
|
||||
await this.connect();
|
||||
|
||||
const data = await this.client.get(key);
|
||||
|
||||
try {
|
||||
return JSON.parse(data as string);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async set(key: string, value: any, time?: number) {
|
||||
await this.connect();
|
||||
|
||||
const ttl = time && time > 0 ? time : DEFAULT_TTL;
|
||||
|
||||
return this.client.set(key, JSON.stringify(value), { EX: ttl });
|
||||
}
|
||||
|
||||
async del(key: string) {
|
||||
await this.connect();
|
||||
|
||||
return this.client.del(key);
|
||||
}
|
||||
|
||||
async incr(key: string) {
|
||||
await this.connect();
|
||||
|
||||
return this.client.incr(key);
|
||||
}
|
||||
|
||||
async expire(key: string, seconds: number) {
|
||||
await this.connect();
|
||||
|
||||
return this.client.expire(key, seconds);
|
||||
}
|
||||
|
||||
async rateLimit(key: string, limit: number, seconds: number): Promise<boolean> {
|
||||
await this.connect();
|
||||
|
||||
const res = await this.client.incr(key);
|
||||
|
||||
if (res === 1) {
|
||||
await this.client.expire(key, seconds);
|
||||
}
|
||||
|
||||
return res >= limit;
|
||||
}
|
||||
|
||||
async fetch(key: string, query: () => Promise<any>, time?: number) {
|
||||
const result = await this.get(key);
|
||||
|
||||
if (result === DELETED) return null;
|
||||
|
||||
if (!result && query) {
|
||||
const data = await query();
|
||||
if (data) {
|
||||
await this.set(key, data, time);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async remove(key: string, soft = false) {
|
||||
return soft ? this.set(key, DELETED) : this.del(key);
|
||||
}
|
||||
}
|
||||
|
||||
const REDIS = 'redis';
|
||||
const enabled = !!process.env.REDIS_URL;
|
||||
|
||||
function getClient() {
|
||||
const redis = new UmamiRedisClient({ url: process.env.REDIS_URL });
|
||||
const redis = new UmamiRedisClient(process.env.REDIS_URL);
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
globalThis[REDIS] = redis;
|
||||
|
|
@ -13,6 +115,6 @@ function getClient() {
|
|||
return redis;
|
||||
}
|
||||
|
||||
const client = globalThis[REDIS] || getClient();
|
||||
const client: UmamiRedisClient = globalThis[REDIS] || getClient();
|
||||
|
||||
export default { client, enabled };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue