diff --git a/README.md b/README.md index b54955e..82a5310 100644 --- a/README.md +++ b/README.md @@ -32,99 +32,24 @@ $ npm i @myunisoft/redis $ yarn add @myunisoft/redis ``` -## 📜 API - -

- Connection -

+---

- This class is used to instantiate and close connection to Redis. You need to re-use this instance in every other classes. + There are multiple adapters to exploit the different abstractions available.

-```ts -type ConnectionOptions = Partial & { - port?: number; - host?: string; - attempt?: number; - disconnectionTimeout?: number; -}; -``` - -### 📚 Usage - -```js -import assert from "assert"; -import { - Connection -} from "@myunisoft/redis"; - -const connection = new Connection(); - -try { - (await connection.initialize()).unwrap(); -} -finally { - await connection.close(); -} -``` - -### initialize(): Promise< Result< null, AssertConnectionErr > > - -```ts -type AssertConnectionErr = "Failed at initializing the Redis connection"; -``` - -This function either return void, or an error; - ---- - -### getConnectionPerf(): Promise< GetConnectionPerfResponse > - -```ts -type GetConnectionPerfResponse = { - isAlive: boolean; - perf: number; -}; -``` - -This function is used to check Redis connection state. - -```ts -const instancePerf = await getConnectionPerf(); - -if (!instancePerf.isAlive) { - console.log(instancePerf.isAlive); - console.log(instancePerf.perf); -} - -console.log(instancePerf.isAlive); -console.log(instancePerf.perf); -``` - ---- - -### closeRedis(forceExit: boolean = false): Promise< Result< null, CloseErr > > - -```ts -type AssertDisconnectionErr = AssertDisconnectionErrorMessage; -type CloseErr = AssertDisconnectionErrorMessage | "Redis connection already closed"; -``` - -This function is used to close the Redis connection related to the instance. - ---- - -The package also exports many classes listed below. - -- [KVPeer](./docs/KVPeer.md) -- [TimedKVPeer](./docs/TimedKVPeer.md) -- [RestrictedKV](./docs/RestrictedKV.md) -- [StoreContext](./docs/StoreContext.md) -- [PubSub](./docs/pubsub/Channel.md) -- [Stream](./docs/stream/Stream.md) - - [Intrapersonal](./docs/stream/Intrapersonal.md) - - [Interpersonal](./docs/stream/Interpersonal.md) +- Adapter + - [MemoryAdapter](./docs/adapter/memory.adapter.md) + - [RedisAdapter](./docs/adapter/redis.adapter.md) +- Abstraction + - [KVPeer](./docs/KVPeer.md) + - [TimedKVPeer](./docs/TimedKVPeer.md) + - [RestrictedKV](./docs/RestrictedKV.md) + - [StoreContext](./docs/StoreContext.md) + - [PubSub](./docs/pubsub/Channel.md) + - [Stream](./docs/stream/Stream.md) + - [Intrapersonal](./docs/stream/Intrapersonal.md) + - [Interpersonal](./docs/stream/Interpersonal.md) ## Contributors ✨ diff --git a/docs/KVPeer.md b/docs/KVPeer.md index 7b75b5f..99f5222 100644 --- a/docs/KVPeer.md +++ b/docs/KVPeer.md @@ -21,18 +21,17 @@ IsMetadataDefined : T; // How to restraint usage of the mapValue fn while T extends string? export type KVMapper | null = null> = (value: T) => MappedValue; -export class KVPeer | null = null> extends EventEmitter { - connection: Connection; +export interface KVOptions, K extends Record | null = null> { + adapter: DatabaseConnection; prefix?: string; type?: KVType; mapValue?: KVMapper; } -export interface SetValueOptions { - key: KeyType; - value: T; - expiresIn?: number; -} +export type KVPeerSetValueOptions = Omit< + RedisSetValueOptions, + "prefix" | "type" +>; ``` ## Constants @@ -42,7 +41,7 @@ export interface SetValueOptions { ## 📚 Usage ```ts -import { RedisKV, Connection } from "@myunisoft/redis"; +import { RedisKV, MemoryAdapter } from "@myunisoft/redis"; interface MyCustomObject { foo: string; @@ -52,12 +51,10 @@ interface Metadata { bar: string; } -const connection = new Connection(); - -await connection.initialize(); +const memoryAdapter = new MemoryAdapter(); const options: KVOptions = { - connection, + adapter: memoryAdapter, prefix: "local", type: "object", mapValue: (value: MyCustomObject) => { @@ -74,7 +71,7 @@ const customKvWrapper = new RedisKV(options); ## 📜 API -### setValue(options: SetValueOptions< T >): Promise< KeyType > +### setValue(options: KVPeerSetValueOptions< T >): Promise< KeyType > this method is used to set a key-value pair in Redis @@ -94,7 +91,7 @@ this method is used to get a value from Redis ```ts const returnValue = await customKvWrapper.getValue(key); -console.Log(returnValue); +console.log(returnValue); /* { foo: "bar", diff --git a/docs/RestrictedKV.md b/docs/RestrictedKV.md index 88da3a5..1587138 100644 --- a/docs/RestrictedKV.md +++ b/docs/RestrictedKV.md @@ -33,12 +33,15 @@ type KeyType = string | Buffer; ## 📚 Usage ```ts -import { RestrictedKV } from "@myunisoft/redis"; +import { RestrictedKV, MemoryAdapter } from "@myunisoft/redis"; const allowedAttempt = 2; const banTime = 60; +const memoryAdapter = new MemoryAdapter(); + const restrictedKV = new RestrictedKV({ + adapter: memoryAdapter, prefix: "foo-", allowedAttempt, banTimeInSecond: banTime diff --git a/docs/StoreContext.md b/docs/StoreContext.md index c1f7ef5..53c4e25 100644 --- a/docs/StoreContext.md +++ b/docs/StoreContext.md @@ -32,14 +32,12 @@ interface StoreContextOptions extends TimedKVPeerOptions { ## 📚 Usage ```ts -import { StoreContext, Connection } from "@myunisoft/redis"; +import { StoreContext, MemoryAdapter } from "@myunisoft/redis"; -const connection = new Connection(); - -await connection.initialize(); +const memoryAdapter = new MemoryAdapter(); const options = { - connection, + adapter: memoryAdapter, authenticationField: keyof T | null; cookiesOptions: SetOption; } diff --git a/docs/TimedKVPeer.md b/docs/TimedKVPeer.md index 8f82dbc..57987c4 100644 --- a/docs/TimedKVPeer.md +++ b/docs/TimedKVPeer.md @@ -20,7 +20,7 @@ export interface TimedKVPeerOptions({ + adapter: memoryAdapter, sessionDuration: 3600, randomKeyCallback }); diff --git a/docs/adapter/memory.adapter.md b/docs/adapter/memory.adapter.md new file mode 100644 index 0000000..9675055 --- /dev/null +++ b/docs/adapter/memory.adapter.md @@ -0,0 +1,87 @@ +

+ MemoryAdapter +

+ +

+ This class is a basic in-memory database adapter. +

+ +## Interface + +```ts +export interface InMemSetValueOptions { + key: string; + value: unknown; + expiresIn?: number; +} + +export interface InMemIsKeyExpiredOptions { + value: Record; + banTimeInSecond: number; +} +``` + +## 📚 Usage + +```ts +import { MemoryAdapter } from "@myunisoft/redis"; + +const memoryAdapter = new MemoryAdapter(); +``` + +## 📜 API + +### setValue(options: InMemSetValueOptions): Result + +this method is used to set a key-value pair in memory + +```ts +const key = "foo"; +const value = { + foo: "bar", +}; + +await memoryAdapter.setValue({ key, value }); +``` + +### deleteValue(key: string): number + +this method is used to delete a key-value pair in memory + +```ts +const key = "foo"; + +const result = await memoryAdapter.deleteValue(key); + +console.log(result); // 0 for Failure, 1 for Success +``` + +### clearExpired(options: { banTimeInSecond: number; }): (string | Buffer)[] + +this method is used to clear expired key-value pairs in memory + +```ts +const result = await memoryAdapter.clearExpired({ banTimeInSecond: 10 }); + +console.log(result); // [] +``` + +### getValue(key: string): null | unknown + +this method is used to get a value from memory + +```ts +const key = "foo"; + +const result = await memoryAdapter.getValue(key); + +console.log(result); // { foo: "bar" } +``` + +### flushall() + +this method is used to clear all key-value pairs in memory + +```ts +await memoryAdapter.flushall(); +``` diff --git a/docs/adapter/redis.adapter.md b/docs/adapter/redis.adapter.md new file mode 100644 index 0000000..f020041 --- /dev/null +++ b/docs/adapter/redis.adapter.md @@ -0,0 +1,142 @@ +

+ RedisAdapter +

+ +

+ This class is a basic redis database adapter. +

+ +## Interface + +```ts +export type KVType = "raw" | "object"; + +export type StringOrObject = string | Record; + +export interface GetConnectionPerfResponse { + isAlive: boolean; + perf: number; +} + +export interface ClearExpiredOptions { + prefix: string; + banTimeInSecond: number; +} + +export type RedisIsKeyExpiredOptions = ClearExpiredOptions & { + key: KeyType; +}; + +export interface RedisSetValueOptions> { + key: KeyType; + value: Partial; + type: KVType; + expiresIn?: number; +} + +export type RedisAdapterOptions = Partial & { + attempt?: number; + disconnectionTimeout?: number; +}; +``` + +## Constants + +```ts +const kDefaultAttempt = 4; +const kDefaultTimeout = 500; +``` + +## 📚 Usage + +```ts +import { RedisAdapter } from "@myunisoft/redis"; + +const redisAdapter = new RedisAdapter(); +``` + +## 📜 API + +### setValue(options: RedisSetValueOptions): Result + +this method is used to set a key-value pair in redis + +```ts +const key = "foo"; +const value = { + foo: "bar", +}; + +await redisAdapter.setValue({ key, value }); +``` + +### getValue(key: KeyType): null | unknown + +this method is used to get a value from redis + +```ts +const key = "foo"; + +const result = await redisAdapter.getValue(key); + +console.log(result); // { foo: "bar" } +``` + +### deleteValue(key: KeyType): number + +this method is used to delete a key-value pair in redis + +```ts +const key = "foo"; + +const result = await redisAdapter.deleteValue(key); + +console.log(result); // 0 for Failure, 1 for Success +``` + +### clearExpired(options: ClearExpiredOptions): (string | Buffer)[] + +this method is used to clear expired key-value pairs in redis + +```ts +const result = await redisAdapter.clearExpired({ banTimeInSecond: 10 }); + +console.log(result); // [] +``` + +### isKeyExpired(options: RedisIsKeyExpiredOptions): boolean + +this method is used to check if a key is expired in redis + +```ts +const key = "foo"; + +const result = await redisAdapter.isKeyExpired({ key, banTimeInSecond: 10 }); + +console.log(result); // false +``` + +### deepParseInput(input: Record | any[]): Generator | any[]> + +this method is used to deep parse input + +```ts +const input = { foo: "bar" }; + +const result = await redisAdapter.deepParseInput(input); + +console.log(result); // { foo: "bar" } +``` + +### parseInput(object: Record): Record + +this method is used to parse input + +```ts +const input = { foo: "bar" }; + +const result = await redisAdapter.parseInput(input); + +console.log(result); // { foo: "bar" } +``` + diff --git a/docs/stream/Interpersonal.md b/docs/stream/Interpersonal.md index d651dec..9e6b687 100644 --- a/docs/stream/Interpersonal.md +++ b/docs/stream/Interpersonal.md @@ -26,11 +26,7 @@ interface GroupConsumerOptions extends BasementOptions { ## 📚 Usage ```ts -import { GroupConsumer, Connection } from "@myunisoft/redis"; - -const connection = new Connection(); - -await connection.initialize(); +import { GroupConsumer } from "@myunisoft/redis"; const consumer = new GroupConsumer({ connection, @@ -45,6 +41,8 @@ const consumer = new GroupConsumer({ } }); +await consumer.initialize(); + const readable = Readable.from(firstConsumer[Symbol.asyncIterator]()); readable.on("readable", async() => { const chunk: Entry[] = readable.read(); diff --git a/docs/stream/Intrapersonal.md b/docs/stream/Intrapersonal.md index dfdf641..0f6d61d 100644 --- a/docs/stream/Intrapersonal.md +++ b/docs/stream/Intrapersonal.md @@ -10,11 +10,7 @@ ## 📚 Usage ```ts -import { Intrapersonal, Connection } from "@myunisoft/redis"; - -const connection = new Connection(); - -await connection.initialize(); +import { Intrapersonal } from "@myunisoft/redis"; const consumer = new Intrapersonal({ connection, @@ -24,6 +20,8 @@ const consumer = new Intrapersonal({ count: 10 }); +await consumer.initialize(); + const readable = Readable.from(basicStream[Symbol.asyncIterator]()); ``` diff --git a/docs/stream/Stream.md b/docs/stream/Stream.md index d155061..c2c08bc 100644 --- a/docs/stream/Stream.md +++ b/docs/stream/Stream.md @@ -65,19 +65,16 @@ interface ConsumeOptions { ## 📚 Usage ```ts -import { Stream, Connection } from "@myunisoft/redis"; - -const connection = new Connection(); - -await connection.initialize(); +import { Stream, RedisAdapter } from "@myunisoft/redis"; const redisStream = new Stream({ - connection, streamName: "my-stream-name", frequency: 10000, lastId: "0-0", count: 10 }); + +await redisStream.initialize(); ``` ## 📜 API