@samet-it/be-redis-common 1.1.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/LICENSE +24 -0
- package/README.md +89 -0
- package/dist/assets/.gitkeep +0 -0
- package/dist/channel/index.d.ts +3 -0
- package/dist/channel/index.js +19 -0
- package/dist/channel/index.types.d.ts +39 -0
- package/dist/channel/index.types.js +2 -0
- package/dist/channel/redis-direct.channel.d.ts +17 -0
- package/dist/channel/redis-direct.channel.js +21 -0
- package/dist/channel/redis.channel.d.ts +28 -0
- package/dist/channel/redis.channel.js +179 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.types.d.ts +31 -0
- package/dist/config/index.types.js +2 -0
- package/dist/config/redis-common.config.d.ts +5 -0
- package/dist/config/redis-common.config.js +18 -0
- package/dist/connection/index.d.ts +4 -0
- package/dist/connection/index.js +20 -0
- package/dist/connection/index.types.d.ts +74 -0
- package/dist/connection/index.types.js +2 -0
- package/dist/connection/redis-connection.fn.d.ts +8 -0
- package/dist/connection/redis-connection.fn.js +14 -0
- package/dist/connection/redis-direct.connection.d.ts +18 -0
- package/dist/connection/redis-direct.connection.js +25 -0
- package/dist/connection/redis.connection.d.ts +48 -0
- package/dist/connection/redis.connection.js +205 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Samet Global
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Web: https://sametglobal.com
|
|
24
|
+
Responsible: Mustafa Yelmer (mustafay@samet.com.tr)
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Samet IT : Redis Common
|
|
2
|
+
`ts` `component` `backend`
|
|
3
|
+
```
|
|
4
|
+
___
|
|
5
|
+
________ ____/ (______ _________ ____ ___ ____ ___ ____ ____
|
|
6
|
+
/ ___/ _ \/ __ / / ___/ / ___/ __ \/ __ `__ \/ __ `__ \/ __ \/ __ \
|
|
7
|
+
/ / / __/ /_/ / (__ ) / /__/ /_/ / / / / / / / / / / / /_/ / / / /
|
|
8
|
+
/_/ \___/\__,_/_/____/ \___/\____/_/ /_/ /_/_/ /_/ /_/\____/_/ /_/
|
|
9
|
+
```
|
|
10
|
+
<!-- https://patorjk.com/software/taag/#p=display&f=Slant&t=redis+common&x=none&v=4&h=3&w=80&we=false -->
|
|
11
|
+
- `EN`: Use it for redis connections
|
|
12
|
+
- `TR`: Redis (cache) bağlantıları için bu bileşeni kullanınız
|
|
13
|
+
|
|
14
|
+
## Prerequisite
|
|
15
|
+
- [Help](https://github.com/samet-digital/help)
|
|
16
|
+
- [1 - Install Git](https://github.com/samet-digital/help/blob/main//install-git.MD)
|
|
17
|
+
- [2 - Build Up a Git Connection](https://github.com/samet-digital/help/blob/main//build-git-connection.MD)
|
|
18
|
+
- [3 - Install Node/NPM](https://github.com/samet-digital/help/blob/main//install-npm.MD)
|
|
19
|
+
- [4 - Create Project Folder](https://github.com/samet-digital/help/blob/main//create-project-folder.MD)
|
|
20
|
+
- [5 - Bind Projects Folder to Git](https://github.com/samet-digital/help/blob/main//bind-project-folder.MD)
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
- `EN`: How to add into your project?
|
|
24
|
+
- `TR`: Projene nasıl eklersin?
|
|
25
|
+
|
|
26
|
+
```shell
|
|
27
|
+
npm i @samet-it/be-redis-common
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Environments
|
|
31
|
+
- [RedisCommonConf](./src/config/redis-common.config.ts)
|
|
32
|
+
|
|
33
|
+
| Name | Type | Default | Required | Secret | Description |
|
|
34
|
+
|-------------------|---------|---------|----------|--------|--------------------------|
|
|
35
|
+
| `REDIS_HOST` | string | | ✅ | ⭕ | Redis Host or IP Address |
|
|
36
|
+
| `REDIS_PORT` | integer | _6379_ | ✅ | ⭕ | Redis port |
|
|
37
|
+
| `REDIS_USER` | string | | | ⭕ | Redis User |
|
|
38
|
+
| `REDIS_PASS` | string | | | ⭕ | Redis Password |
|
|
39
|
+
| `REDIS_PREFIX` | string | | | | Prefix for keys |
|
|
40
|
+
| `REDIS_DB_NUMBER` | integer | | | | Redis DB number |
|
|
41
|
+
|
|
42
|
+
## Contents
|
|
43
|
+
- `abstract` [RedisConnection](src/connection/redis.connection.ts) - abstract connection class
|
|
44
|
+
- `class` [RedisDirectConnection](src/connection/redis-direct.connection.ts) - Direct connection class
|
|
45
|
+
- `function` [redisConnection()](src/connection/redis-connection.fn.ts) - Direct connection function
|
|
46
|
+
- `abstract` [RedisChannel](src/channel/redis.channel.ts) - abstract repository
|
|
47
|
+
- `class` [RedisDirectChannel](src/channel/redis-direct.channel.ts) - direct repository
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Development
|
|
51
|
+
> You can start to develop on it
|
|
52
|
+
>
|
|
53
|
+
### Step 1
|
|
54
|
+
- [Go to project folder](https://github.com/samet-digital/help/blob/main/go-to-project-folder.MD)
|
|
55
|
+
|
|
56
|
+
### Step 2
|
|
57
|
+
- `EN`: Clone the project
|
|
58
|
+
- `TR`: Projeyi bilgisiyarına çek
|
|
59
|
+
```shell
|
|
60
|
+
git clone https://github.com/samet-digital/be-redis-common.git -b development
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Dependencies
|
|
64
|
+
- `@samet-it/be-base-common`: **samet** base common
|
|
65
|
+
- `@samet-it/be-cache-common`: **samet** cache common
|
|
66
|
+
- `@leyyo/*`: leyyo utilities
|
|
67
|
+
- `@nestjs/*`: nestjs framework
|
|
68
|
+
- `redis`: redis client
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
- [Component Commands](https://github.com/samet-digital/help/blob/main/commands-component.MD)
|
|
72
|
+
|
|
73
|
+
## Standards
|
|
74
|
+
```diff
|
|
75
|
+
+ language: TS
|
|
76
|
+
+ lint: eslint
|
|
77
|
+
+ inspections: intelli-j code inspections
|
|
78
|
+
+ ddd: domain driven development
|
|
79
|
+
+ edd: exception driven development
|
|
80
|
+
! tdd: test driven development
|
|
81
|
+
+ ldd: log driven development
|
|
82
|
+
+ ddd: document driven development
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## History
|
|
86
|
+
| Date | Developer | Info | Ticket |
|
|
87
|
+
|------------|----------------|--------------|-------------------------|
|
|
88
|
+
| 2025-08-13 | Mustafa Yelmer | _Created_ | ~~[none](./README.md)~~ |
|
|
89
|
+
| 2026-01-11 | Mustafa Yelmer | _Refactored_ | ~~[none](./README.md)~~ |
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./index.types"), exports);
|
|
18
|
+
__exportStar(require("./redis.channel"), exports);
|
|
19
|
+
__exportStar(require("./redis-direct.channel"), exports);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { RedisConnectionLike } from "../connection";
|
|
2
|
+
import type { CacheChannelProps, CacheChannelLike, CacheChannelOpt } from "@samet-it/be-cache-common";
|
|
3
|
+
import type { Entity } from "@samet-it/be-base-common";
|
|
4
|
+
import type { RedisClientType } from "redis";
|
|
5
|
+
import type { KeyValue } from "@leyyo/common";
|
|
6
|
+
/**
|
|
7
|
+
* Redis channel interface
|
|
8
|
+
* */
|
|
9
|
+
export interface RedisChannelLike<ID extends KeyValue, ENTITY extends Entity<ID>> extends CacheChannelLike<RedisConnectionLike, ID, ENTITY> {
|
|
10
|
+
/** @inheritDoc */
|
|
11
|
+
get props(): Readonly<RedisChannelProps>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Redis channel option
|
|
15
|
+
* */
|
|
16
|
+
export interface RedisChannelOpt extends CacheChannelOpt {
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Redis channel props
|
|
20
|
+
* */
|
|
21
|
+
export interface RedisChannelProps extends CacheChannelProps<RedisConnectionLike>, RedisChannelOpt {
|
|
22
|
+
/**
|
|
23
|
+
* Redis client
|
|
24
|
+
*
|
|
25
|
+
* @type {RedisClientType}
|
|
26
|
+
* */
|
|
27
|
+
client: RedisClientType;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Redis direct channel options
|
|
31
|
+
* */
|
|
32
|
+
export interface RedisDirectChannelOpt extends RedisChannelOpt {
|
|
33
|
+
/**
|
|
34
|
+
* Name for logger
|
|
35
|
+
*
|
|
36
|
+
* @type {string}
|
|
37
|
+
* */
|
|
38
|
+
name?: string;
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RedisChannel } from "./redis.channel";
|
|
2
|
+
import { type Entity } from "@samet-it/be-base-common";
|
|
3
|
+
import type { RedisConnectionLike } from "../connection";
|
|
4
|
+
import type { RedisDirectChannelOpt } from "./index.types";
|
|
5
|
+
import type { KeyValue } from "@leyyo/common";
|
|
6
|
+
/**
|
|
7
|
+
* Redis direct channel class
|
|
8
|
+
* */
|
|
9
|
+
export declare class RedisDirectChannel<ID extends KeyValue, ENTITY extends Entity<ID>> extends RedisChannel<ID, ENTITY> {
|
|
10
|
+
/**
|
|
11
|
+
* Constructor
|
|
12
|
+
*
|
|
13
|
+
* @param {RedisConnectionLike} conn - connection
|
|
14
|
+
* @param {RedisDirectChannelOpt?} opt - direct options
|
|
15
|
+
* */
|
|
16
|
+
constructor(conn: RedisConnectionLike, opt?: RedisDirectChannelOpt);
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisDirectChannel = void 0;
|
|
4
|
+
const redis_channel_1 = require("./redis.channel");
|
|
5
|
+
const be_base_common_1 = require("@samet-it/be-base-common");
|
|
6
|
+
/**
|
|
7
|
+
* Redis direct channel class
|
|
8
|
+
* */
|
|
9
|
+
class RedisDirectChannel extends redis_channel_1.RedisChannel {
|
|
10
|
+
/**
|
|
11
|
+
* Constructor
|
|
12
|
+
*
|
|
13
|
+
* @param {RedisConnectionLike} conn - connection
|
|
14
|
+
* @param {RedisDirectChannelOpt?} opt - direct options
|
|
15
|
+
* */
|
|
16
|
+
constructor(conn, opt) {
|
|
17
|
+
super(conn, opt);
|
|
18
|
+
this.logger = be_base_common_1.logger.of(`RedisDirect${opt.name ? '#' + opt.name : ''}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.RedisDirectChannel = RedisDirectChannel;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RedisConnectionLike } from "../connection";
|
|
2
|
+
import type { RedisChannelProps, RedisChannelLike, RedisChannelOpt } from "./index.types";
|
|
3
|
+
import { type Entity } from "@samet-it/be-base-common";
|
|
4
|
+
import { CacheChannel } from "@samet-it/be-cache-common";
|
|
5
|
+
import type { KeyValue, Opt } from "@leyyo/common";
|
|
6
|
+
/**
|
|
7
|
+
* Redis abstract channel class
|
|
8
|
+
* */
|
|
9
|
+
export declare abstract class RedisChannel<ID extends KeyValue, ENTITY extends Entity<ID>> extends CacheChannel<RedisConnectionLike, ID, ENTITY> implements RedisChannelLike<ID, ENTITY> {
|
|
10
|
+
/** @inheritDoc */
|
|
11
|
+
protected _props: RedisChannelProps;
|
|
12
|
+
protected constructor(conn: RedisConnectionLike, opt?: RedisChannelOpt);
|
|
13
|
+
protected _checkError(e: Error, opt?: Opt): void;
|
|
14
|
+
/** @inheritDoc */
|
|
15
|
+
get props(): Readonly<RedisChannelProps>;
|
|
16
|
+
/** @inheritDoc */
|
|
17
|
+
$get(...paths: Array<string>): Promise<Array<string>>;
|
|
18
|
+
/** @inheritDoc */
|
|
19
|
+
$set(map: Record<string, string>): Promise<number>;
|
|
20
|
+
/** @inheritDoc */
|
|
21
|
+
$delete(...paths: string[]): Promise<number>;
|
|
22
|
+
/** @inheritDoc */
|
|
23
|
+
$addLinks(idPath: string, paths: string): Promise<number>;
|
|
24
|
+
/** @inheritDoc */
|
|
25
|
+
$expire(path: string, seconds: number): Promise<boolean>;
|
|
26
|
+
/** @inheritDoc */
|
|
27
|
+
$getLinks(idPath: string): Promise<Array<string>>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RedisChannel = void 0;
|
|
13
|
+
const be_base_common_1 = require("@samet-it/be-base-common");
|
|
14
|
+
const be_cache_common_1 = require("@samet-it/be-cache-common");
|
|
15
|
+
// noinspection JSUnusedGlobalSymbols
|
|
16
|
+
/**
|
|
17
|
+
* Redis abstract channel class
|
|
18
|
+
* */
|
|
19
|
+
class RedisChannel extends be_cache_common_1.CacheChannel {
|
|
20
|
+
// endregion protected-property
|
|
21
|
+
constructor(conn, opt) {
|
|
22
|
+
super(conn, opt);
|
|
23
|
+
conn.onFirstConnected(() => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
this._props.client = conn.props.client;
|
|
25
|
+
this._props.isConnected = true;
|
|
26
|
+
}));
|
|
27
|
+
conn.onConnected(() => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
this._props.client = conn.props.client;
|
|
29
|
+
this._props.isConnected = true;
|
|
30
|
+
}));
|
|
31
|
+
conn.onDisconnected(() => __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
this._props.client = undefined;
|
|
33
|
+
this._props.isConnected = false;
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
_checkError(e, opt) {
|
|
37
|
+
be_base_common_1.errorHandler.addStat(e);
|
|
38
|
+
if (e instanceof be_cache_common_1.CacheError) {
|
|
39
|
+
// todo append params
|
|
40
|
+
throw e;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw be_base_common_1.errorHandler.common.castForClass(be_cache_common_1.CacheError, e, opt);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// region getter
|
|
47
|
+
/** @inheritDoc */
|
|
48
|
+
get props() {
|
|
49
|
+
return this._props;
|
|
50
|
+
}
|
|
51
|
+
// endregion getter
|
|
52
|
+
// region native-calls
|
|
53
|
+
/** @inheritDoc */
|
|
54
|
+
$get(...paths) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const { client } = this._props;
|
|
57
|
+
if (!client) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (paths.length < 1) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
if (paths.length == 1) {
|
|
64
|
+
const rec = (yield client.get(paths[0]));
|
|
65
|
+
return rec ? [rec] : [];
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
return (yield client.mGet(paths));
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
this._checkError(e, { redis: 'MGET' });
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/** @inheritDoc */
|
|
76
|
+
$set(map) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
const { client } = this._props;
|
|
79
|
+
if (!client) {
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
if (!map || typeof map !== 'object' || Array.isArray(map)) {
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
const keys = Object.keys(map);
|
|
86
|
+
switch (keys.length) {
|
|
87
|
+
case 0:
|
|
88
|
+
return 0;
|
|
89
|
+
case 1:
|
|
90
|
+
const key = keys[0];
|
|
91
|
+
try {
|
|
92
|
+
yield client.set(key, map[key]);
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
this._checkError(e, { redis: 'SET' });
|
|
96
|
+
}
|
|
97
|
+
return 1;
|
|
98
|
+
default:
|
|
99
|
+
try {
|
|
100
|
+
yield client.mSet(map);
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
this._checkError(e, { redis: 'MSET' });
|
|
104
|
+
}
|
|
105
|
+
return keys.length;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/** @inheritDoc */
|
|
110
|
+
$delete(...paths) {
|
|
111
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
const { client } = this._props;
|
|
113
|
+
if (!client) {
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
if (paths.length < 1) {
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
yield client.del(paths);
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
this._checkError(e, { redis: 'DEL' });
|
|
124
|
+
}
|
|
125
|
+
return paths.length;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/** @inheritDoc */
|
|
129
|
+
$addLinks(idPath, paths) {
|
|
130
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
+
const { client } = this._props;
|
|
132
|
+
if (!client) {
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
if (paths.length < 1) {
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
yield client.sAdd(idPath, paths);
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
this._checkError(e, { redis: 'SADD' });
|
|
143
|
+
}
|
|
144
|
+
return paths.length;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/** @inheritDoc */
|
|
148
|
+
$expire(path, seconds) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const { client } = this._props;
|
|
151
|
+
if (!client) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
return (yield client.expire(path, seconds)) > 0;
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
this._checkError(e, { redis: 'EXPIRE' });
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/** @inheritDoc */
|
|
163
|
+
$getLinks(idPath) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
var _a;
|
|
166
|
+
const { client } = this._props;
|
|
167
|
+
if (!client) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
return (_a = (yield client.sMembers(idPath))) !== null && _a !== void 0 ? _a : [];
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
this._checkError(e, { redis: 'SMEMBERS' });
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.RedisChannel = RedisChannel;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./redis-common.config"), exports);
|
|
18
|
+
__exportStar(require("./index.types"), exports);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { EnvBase } from "@leyyo/env";
|
|
2
|
+
export interface RedisCommonConf extends EnvBase {
|
|
3
|
+
/**
|
|
4
|
+
* Redis Protocol
|
|
5
|
+
* */
|
|
6
|
+
readonly PROTOCOL: string;
|
|
7
|
+
/**
|
|
8
|
+
* Redis Host
|
|
9
|
+
* */
|
|
10
|
+
readonly HOST: string;
|
|
11
|
+
/**
|
|
12
|
+
* Redis Port
|
|
13
|
+
* */
|
|
14
|
+
readonly PORT: number;
|
|
15
|
+
/**
|
|
16
|
+
* DB User
|
|
17
|
+
* */
|
|
18
|
+
readonly USER: string;
|
|
19
|
+
/**
|
|
20
|
+
* DB Password
|
|
21
|
+
* */
|
|
22
|
+
readonly PASS: string;
|
|
23
|
+
/**
|
|
24
|
+
* Redis prefix for keys
|
|
25
|
+
* */
|
|
26
|
+
readonly PREFIX: string;
|
|
27
|
+
/**
|
|
28
|
+
* Redis DB number
|
|
29
|
+
* */
|
|
30
|
+
readonly DB_NUMBER: number;
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redisCommonConfig = void 0;
|
|
4
|
+
const env_1 = require("@leyyo/env");
|
|
5
|
+
/**
|
|
6
|
+
* Redis common config
|
|
7
|
+
* */
|
|
8
|
+
exports.redisCommonConfig = env_1.envCore.configure
|
|
9
|
+
.scope('RedisCommon', 'REDIS')
|
|
10
|
+
.start()
|
|
11
|
+
.field('PROTOCOL').text().def('redis').end()
|
|
12
|
+
.field('HOST').text().required().end()
|
|
13
|
+
.field('PORT').integer().def(6379).end()
|
|
14
|
+
.field('USER').text().end()
|
|
15
|
+
.field('PASS').text().end()
|
|
16
|
+
.field('PREFIX').text().end()
|
|
17
|
+
.field('DB_NUMBER').integer().end()
|
|
18
|
+
.finish();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./index.types"), exports);
|
|
18
|
+
__exportStar(require("./redis.connection"), exports);
|
|
19
|
+
__exportStar(require("./redis-direct.connection"), exports);
|
|
20
|
+
__exportStar(require("./redis-connection.fn"), exports);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { CacheConnectionLike, CacheConnOpt, CacheExecOpt } from "@samet-it/be-cache-common";
|
|
2
|
+
import type { RedisClientType } from "redis";
|
|
3
|
+
import type { Entity } from "@samet-it/be-base-common";
|
|
4
|
+
import type { RedisDirectChannelOpt, RedisChannelLike } from "../channel";
|
|
5
|
+
import type { CacheConnProps } from "@samet-it/be-cache-common";
|
|
6
|
+
import { KeyValue } from "@leyyo/common";
|
|
7
|
+
/**
|
|
8
|
+
* Redis connection interface
|
|
9
|
+
* */
|
|
10
|
+
export interface RedisConnectionLike extends CacheConnectionLike<RedisExecOpt> {
|
|
11
|
+
/** @inheritDoc */
|
|
12
|
+
get props(): Readonly<RedisConnProps>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Redis direct connection interface
|
|
16
|
+
* */
|
|
17
|
+
export interface RedisDirectConnectionLike extends RedisConnectionLike {
|
|
18
|
+
/**
|
|
19
|
+
* Create new channel
|
|
20
|
+
*
|
|
21
|
+
* @param {RedisDirectChannelOpt?} opt - direct channel options
|
|
22
|
+
* @return {RedisChannelLike<Entity>} - new channel
|
|
23
|
+
* */
|
|
24
|
+
newChannel<ID extends KeyValue, ENTITY extends Entity<ID>>(opt?: RedisDirectChannelOpt): RedisChannelLike<ID, ENTITY>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Redis connection option
|
|
28
|
+
* */
|
|
29
|
+
export interface RedisConnOpt extends CacheConnOpt {
|
|
30
|
+
/**
|
|
31
|
+
* Redis DB number
|
|
32
|
+
*
|
|
33
|
+
* @type {number}
|
|
34
|
+
* */
|
|
35
|
+
dbNumber?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Redis direct connection option
|
|
39
|
+
* */
|
|
40
|
+
export interface RedisConnDirectOpt extends RedisConnOpt {
|
|
41
|
+
/**
|
|
42
|
+
* logger name
|
|
43
|
+
*
|
|
44
|
+
* @type {string}
|
|
45
|
+
* */
|
|
46
|
+
name?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Redis connection props
|
|
50
|
+
* */
|
|
51
|
+
export interface RedisConnProps extends CacheConnProps, RedisConnOpt {
|
|
52
|
+
/**
|
|
53
|
+
* Redis client
|
|
54
|
+
*
|
|
55
|
+
* @type {RedisClientType}
|
|
56
|
+
* */
|
|
57
|
+
client: RedisClientType;
|
|
58
|
+
/**
|
|
59
|
+
* Connection try count
|
|
60
|
+
*
|
|
61
|
+
* @type {number}
|
|
62
|
+
* */
|
|
63
|
+
tryCount: number;
|
|
64
|
+
/**
|
|
65
|
+
* Connection url
|
|
66
|
+
*
|
|
67
|
+
* @type {string}
|
|
68
|
+
* */
|
|
69
|
+
producedUrl: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Redis query option
|
|
73
|
+
* */
|
|
74
|
+
export type RedisExecOpt = CacheExecOpt;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RedisConnDirectOpt, RedisDirectConnectionLike } from "./index.types";
|
|
2
|
+
/**
|
|
3
|
+
* Crete new redis connection
|
|
4
|
+
*
|
|
5
|
+
* @param {RedisConnDirectOpt} opt - option
|
|
6
|
+
* @return {RedisDirectConnectionLike} - new redis connection
|
|
7
|
+
* */
|
|
8
|
+
export declare function redisConnection(opt?: RedisConnDirectOpt): RedisDirectConnectionLike;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redisConnection = redisConnection;
|
|
4
|
+
const redis_direct_connection_1 = require("./redis-direct.connection");
|
|
5
|
+
// noinspection JSUnusedGlobalSymbols
|
|
6
|
+
/**
|
|
7
|
+
* Crete new redis connection
|
|
8
|
+
*
|
|
9
|
+
* @param {RedisConnDirectOpt} opt - option
|
|
10
|
+
* @return {RedisDirectConnectionLike} - new redis connection
|
|
11
|
+
* */
|
|
12
|
+
function redisConnection(opt) {
|
|
13
|
+
return new redis_direct_connection_1.RedisDirectConnection(opt);
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RedisConnection } from "./redis.connection";
|
|
2
|
+
import { type Entity } from "@samet-it/be-base-common";
|
|
3
|
+
import { type RedisDirectChannelOpt, type RedisChannelLike } from "../channel";
|
|
4
|
+
import type { RedisConnDirectOpt, RedisDirectConnectionLike } from "./index.types";
|
|
5
|
+
import type { KeyValue } from "@leyyo/common";
|
|
6
|
+
/**
|
|
7
|
+
* Redis connection direct class
|
|
8
|
+
* */
|
|
9
|
+
export declare class RedisDirectConnection extends RedisConnection implements RedisDirectConnectionLike {
|
|
10
|
+
/**
|
|
11
|
+
* Constructor
|
|
12
|
+
*
|
|
13
|
+
* @param {RedisConnDirectOpt} opt - options
|
|
14
|
+
* */
|
|
15
|
+
constructor(opt?: RedisConnDirectOpt);
|
|
16
|
+
/** @inheritDoc */
|
|
17
|
+
newChannel<ID extends KeyValue, ENTITY extends Entity<ID>>(opt?: RedisDirectChannelOpt): RedisChannelLike<ID, ENTITY>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisDirectConnection = void 0;
|
|
4
|
+
const redis_connection_1 = require("./redis.connection");
|
|
5
|
+
const be_base_common_1 = require("@samet-it/be-base-common");
|
|
6
|
+
const channel_1 = require("../channel");
|
|
7
|
+
/**
|
|
8
|
+
* Redis connection direct class
|
|
9
|
+
* */
|
|
10
|
+
class RedisDirectConnection extends redis_connection_1.RedisConnection {
|
|
11
|
+
/**
|
|
12
|
+
* Constructor
|
|
13
|
+
*
|
|
14
|
+
* @param {RedisConnDirectOpt} opt - options
|
|
15
|
+
* */
|
|
16
|
+
constructor(opt) {
|
|
17
|
+
super(opt);
|
|
18
|
+
this.logger = be_base_common_1.logger.of(`RedisConnection${(opt === null || opt === void 0 ? void 0 : opt.name) ? '#' + (opt === null || opt === void 0 ? void 0 : opt.name) : ''}`);
|
|
19
|
+
}
|
|
20
|
+
/** @inheritDoc */
|
|
21
|
+
newChannel(opt) {
|
|
22
|
+
return new channel_1.RedisDirectChannel(this, opt);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.RedisDirectConnection = RedisDirectConnection;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RedisConnectionLike, RedisExecOpt, RedisConnProps, RedisConnOpt } from "./index.types";
|
|
2
|
+
import { CacheConnection } from "@samet-it/be-cache-common";
|
|
3
|
+
/**
|
|
4
|
+
* Redis connection abstract class
|
|
5
|
+
* */
|
|
6
|
+
export declare abstract class RedisConnection extends CacheConnection<RedisExecOpt> implements RedisConnectionLike {
|
|
7
|
+
/**
|
|
8
|
+
* Base/starting/min delay
|
|
9
|
+
*
|
|
10
|
+
* @type {number} - as seconds
|
|
11
|
+
* */
|
|
12
|
+
private static readonly BASE_DELAY;
|
|
13
|
+
/**
|
|
14
|
+
* Last/max delay
|
|
15
|
+
*
|
|
16
|
+
* @type {number} - as seconds
|
|
17
|
+
* */
|
|
18
|
+
private static readonly MAX_DELAY;
|
|
19
|
+
/**
|
|
20
|
+
* Try count
|
|
21
|
+
*
|
|
22
|
+
* @type {number} - times
|
|
23
|
+
* */
|
|
24
|
+
private static readonly TRY_COUNT;
|
|
25
|
+
/** {@inheritDoc} */
|
|
26
|
+
protected _props: RedisConnProps;
|
|
27
|
+
protected constructor(opt?: RedisConnOpt);
|
|
28
|
+
/** @inheritDoc */
|
|
29
|
+
get props(): Readonly<RedisConnProps>;
|
|
30
|
+
/**
|
|
31
|
+
* Read credentials from environment
|
|
32
|
+
* */
|
|
33
|
+
protected _readFromEnv(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Build url from credentials
|
|
36
|
+
* */
|
|
37
|
+
protected _buildUrl(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Generate next delay time with exponential & randomized manner
|
|
40
|
+
*
|
|
41
|
+
* @return {number}
|
|
42
|
+
* */
|
|
43
|
+
protected _delayWithJitter(): number;
|
|
44
|
+
/** {@inheritDoc} */
|
|
45
|
+
connect(): Promise<boolean>;
|
|
46
|
+
/** {@inheritDoc} */
|
|
47
|
+
ping(next?: boolean): Promise<boolean>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.RedisConnection = void 0;
|
|
46
|
+
const redis = __importStar(require("redis"));
|
|
47
|
+
const config_1 = require("../config");
|
|
48
|
+
const be_cache_common_1 = require("@samet-it/be-cache-common");
|
|
49
|
+
/**
|
|
50
|
+
* Redis connection abstract class
|
|
51
|
+
* */
|
|
52
|
+
class RedisConnection extends be_cache_common_1.CacheConnection {
|
|
53
|
+
// endregion protected-property
|
|
54
|
+
constructor(opt) {
|
|
55
|
+
super(opt);
|
|
56
|
+
this._props.tryCount = 0;
|
|
57
|
+
this._readFromEnv();
|
|
58
|
+
this._buildUrl();
|
|
59
|
+
}
|
|
60
|
+
// region getter
|
|
61
|
+
/** @inheritDoc */
|
|
62
|
+
get props() {
|
|
63
|
+
return this._props;
|
|
64
|
+
}
|
|
65
|
+
// endregion getter
|
|
66
|
+
// region protected-method
|
|
67
|
+
/**
|
|
68
|
+
* Read credentials from environment
|
|
69
|
+
* */
|
|
70
|
+
_readFromEnv() {
|
|
71
|
+
var _a, _b, _c, _d, _e, _f;
|
|
72
|
+
const { _props: props } = this;
|
|
73
|
+
let env = config_1.redisCommonConfig.valueShort;
|
|
74
|
+
if (props.envVariant) {
|
|
75
|
+
env = config_1.redisCommonConfig.configure.getVariation(props.envVariant).valueShort;
|
|
76
|
+
}
|
|
77
|
+
this._props.protocol = (_a = this._props.protocol) !== null && _a !== void 0 ? _a : env.PROTOCOL;
|
|
78
|
+
this._props.host = (_b = this._props.host) !== null && _b !== void 0 ? _b : env.HOST;
|
|
79
|
+
this._props.port = (_c = this._props.port) !== null && _c !== void 0 ? _c : env.PORT;
|
|
80
|
+
this._props.username = (_d = this._props.username) !== null && _d !== void 0 ? _d : env.USER;
|
|
81
|
+
this._props.password = (_e = this._props.password) !== null && _e !== void 0 ? _e : env.PASS;
|
|
82
|
+
this._props.dbNumber = (_f = this._props.dbNumber) !== null && _f !== void 0 ? _f : env.DB_NUMBER;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build url from credentials
|
|
86
|
+
* */
|
|
87
|
+
_buildUrl() {
|
|
88
|
+
const { username, password, dbNumber, port, host, protocol } = this._props;
|
|
89
|
+
let _secure = '';
|
|
90
|
+
if (username) {
|
|
91
|
+
_secure = username;
|
|
92
|
+
if (password) {
|
|
93
|
+
_secure += ':' + password;
|
|
94
|
+
}
|
|
95
|
+
_secure += '@';
|
|
96
|
+
}
|
|
97
|
+
let _db = '';
|
|
98
|
+
if (dbNumber !== undefined) {
|
|
99
|
+
_db = '/' + dbNumber;
|
|
100
|
+
}
|
|
101
|
+
let _port = '';
|
|
102
|
+
if (port !== undefined) {
|
|
103
|
+
_port = ':' + port;
|
|
104
|
+
}
|
|
105
|
+
this._props.producedUrl = `${protocol}://${_secure}${host}${_port}${_db}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Generate next delay time with exponential & randomized manner
|
|
109
|
+
*
|
|
110
|
+
* @return {number}
|
|
111
|
+
* */
|
|
112
|
+
_delayWithJitter() {
|
|
113
|
+
const exp = Math.min(RedisConnection.BASE_DELAY * Math.pow(2, this._props.tryCount), RedisConnection.MAX_DELAY);
|
|
114
|
+
return exp / 2 + Math.random() * (exp / 2);
|
|
115
|
+
}
|
|
116
|
+
// endregion protected-method
|
|
117
|
+
// region connect
|
|
118
|
+
/** {@inheritDoc} */
|
|
119
|
+
connect() {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
if (this._props.isConnected) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
if (this._props.tryCount > RedisConnection.TRY_COUNT) {
|
|
125
|
+
this.logger.error(`on[error/*], maximum try`);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
this._props.client = redis.createClient({ url: this._props.producedUrl });
|
|
130
|
+
this._props.client
|
|
131
|
+
.on("error", err => {
|
|
132
|
+
this.checkError(err, { silent: true, name: 'connection' });
|
|
133
|
+
this._props.tryCount++;
|
|
134
|
+
const old = this._props.isConnected;
|
|
135
|
+
this._props.isConnected = false;
|
|
136
|
+
if (old) {
|
|
137
|
+
this._triggerOnCase('disconnected', this._onDisconnected, false);
|
|
138
|
+
}
|
|
139
|
+
setTimeout(() => this.connect().then(), this._delayWithJitter());
|
|
140
|
+
})
|
|
141
|
+
.on('connect', () => {
|
|
142
|
+
this.logger.info(`on[connect]`);
|
|
143
|
+
this._props.isConnected = true;
|
|
144
|
+
this._props.tryCount = 0;
|
|
145
|
+
this._triggerOnCase('connected', this._onConnected, false);
|
|
146
|
+
if (this._props.isFirst === undefined) {
|
|
147
|
+
this._triggerOnCase('first-connected', this._onFirstConnected, true);
|
|
148
|
+
this._props.isFirst = false;
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
.on('ready', () => this.logger.info('on[ready]'))
|
|
152
|
+
.on('close', () => this.logger.info('on[close]'))
|
|
153
|
+
.on('reconnecting', () => this.logger.info('on[reconnecting]'))
|
|
154
|
+
.on('end', () => this.logger.info('on[end]'));
|
|
155
|
+
yield this._props.client.connect();
|
|
156
|
+
this.logger.log('Connected');
|
|
157
|
+
setTimeout(() => this.ping(true).then(), 30000);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
this.checkError(e, { name: 'connection' });
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** {@inheritDoc} */
|
|
166
|
+
ping(next) {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
// this._props.client.destroy()
|
|
169
|
+
let result = false;
|
|
170
|
+
if (this._props.isConnected) {
|
|
171
|
+
try {
|
|
172
|
+
yield this._props.client.ping();
|
|
173
|
+
result = true;
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
this.checkError(err, { silent: true, name: 'ping' });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (next) {
|
|
180
|
+
setTimeout(() => this.ping(true).then(), 30000);
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.RedisConnection = RedisConnection;
|
|
187
|
+
// region private-property
|
|
188
|
+
/**
|
|
189
|
+
* Base/starting/min delay
|
|
190
|
+
*
|
|
191
|
+
* @type {number} - as seconds
|
|
192
|
+
* */
|
|
193
|
+
RedisConnection.BASE_DELAY = 500; // 0.5 sec
|
|
194
|
+
/**
|
|
195
|
+
* Last/max delay
|
|
196
|
+
*
|
|
197
|
+
* @type {number} - as seconds
|
|
198
|
+
* */
|
|
199
|
+
RedisConnection.MAX_DELAY = 1000 * 60 * 60; // 1 hour
|
|
200
|
+
/**
|
|
201
|
+
* Try count
|
|
202
|
+
*
|
|
203
|
+
* @type {number} - times
|
|
204
|
+
* */
|
|
205
|
+
RedisConnection.TRY_COUNT = 100; // 100 times
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./connection"), exports);
|
|
18
|
+
__exportStar(require("./config"), exports);
|
|
19
|
+
__exportStar(require("./channel"), exports);
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@samet-it/be-redis-common",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "Redis common component",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"redis",
|
|
7
|
+
"cache"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/samet-digital/be-redis-common.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"email": "mustafay@samet.com.tr",
|
|
15
|
+
"url": "https://https://github.com/samet-digital/be-redis-common/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://https://github.com/samet-digital/be-redis-common#readme",
|
|
18
|
+
"author": {
|
|
19
|
+
"name": "Mustafa Yelmer",
|
|
20
|
+
"email": "mustafay@samet.com.tr"
|
|
21
|
+
},
|
|
22
|
+
"main": "dist/index.js",
|
|
23
|
+
"type": "commonjs",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"clear": "rimraf dist && rimraf coverage",
|
|
26
|
+
"clear:nm": "rimraf node_modules && npm run clear",
|
|
27
|
+
"lint": "eslint src/**/*.ts --quiet",
|
|
28
|
+
"lint:verbose": "eslint src/**/*.ts",
|
|
29
|
+
"asset": "node -r ts-node/register commands/assets.ts",
|
|
30
|
+
"build": "npm run clear && tsc && npm run asset",
|
|
31
|
+
"test": "jest --config=jest.json --detectOpenHandles",
|
|
32
|
+
"coverage": "rimraf coverage && jest --config=jest.json --coverage --coverageDirectory=coverage",
|
|
33
|
+
"sample": "node -r ts-node/register src/sample.ts",
|
|
34
|
+
"publish:public": "npm run build && npm publish -access=public"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist/*"
|
|
38
|
+
],
|
|
39
|
+
"license": "ISC",
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@babel/preset-env": "^7.28.0",
|
|
42
|
+
"@babel/preset-typescript": "^7.27.1",
|
|
43
|
+
"@eslint/js": "^9.33.0",
|
|
44
|
+
"@types/jest": "^30.0.0",
|
|
45
|
+
"@types/node": "^24.2.1",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^8.39.1",
|
|
47
|
+
"@typescript-eslint/parser": "^8.39.1",
|
|
48
|
+
"eslint": "^9.33.0",
|
|
49
|
+
"eslint-config-prettier": "^10.1.8",
|
|
50
|
+
"eslint-config-standard": "^17.1.0",
|
|
51
|
+
"eslint-plugin-import": "^2.32.0",
|
|
52
|
+
"eslint-plugin-jsdoc": "^54.0.0",
|
|
53
|
+
"eslint-plugin-node": "^11.1.0",
|
|
54
|
+
"husky": "^9.1.7",
|
|
55
|
+
"jest": "^29.7.0",
|
|
56
|
+
"prettier": "^3.6.2",
|
|
57
|
+
"rimraf": "^6.0.1",
|
|
58
|
+
"test": "^3.3.0",
|
|
59
|
+
"ts-jest": "^29.4.1",
|
|
60
|
+
"ts-node": "^10.9.2",
|
|
61
|
+
"typescript": "^5.9.2",
|
|
62
|
+
"typescript-eslint": "^8.39.1"
|
|
63
|
+
},
|
|
64
|
+
"overrides": {
|
|
65
|
+
"eslint-config-standard": {
|
|
66
|
+
"eslint": "^9.33.0"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@leyyo/common": "^1.2.1",
|
|
71
|
+
"@leyyo/env": "^1.2.1",
|
|
72
|
+
"@samet-it/be-base-common": "^1.1.1",
|
|
73
|
+
"@samet-it/be-cache-common": "^1.1.1",
|
|
74
|
+
"redis": "^5.10.0"
|
|
75
|
+
}
|
|
76
|
+
}
|