-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
5,306 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# editorconfig.org | ||
root = true | ||
|
||
[*] | ||
end_of_line = lf | ||
indent_style = tab | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.{yaml,yml}] | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
{ | ||
"env": { | ||
"node": true | ||
}, | ||
"extends": [ | ||
"airbnb-base", | ||
"plugin:import/errors", | ||
"plugin:import/warnings", | ||
"plugin:import/typescript", | ||
"plugin:@typescript-eslint/recommended" | ||
], | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"project": "./tsconfig.json", | ||
"sourceType": "module" | ||
}, | ||
"plugins": [ | ||
"import", | ||
"@typescript-eslint" | ||
], | ||
"rules": { | ||
"@typescript-eslint/no-unused-expressions": ["error"], | ||
"@typescript-eslint/no-non-null-assertion": "off", | ||
"@typescript-eslint/naming-convention": [ | ||
"error", | ||
{ | ||
"selector": "interface", | ||
"format": ["PascalCase"], | ||
"prefix": ["I"] | ||
}, | ||
{ | ||
"selector": "property", | ||
"format": ["camelCase", "UPPER_CASE", "PascalCase"] | ||
} | ||
], | ||
"@typescript-eslint/ban-ts-comment": ["error", { | ||
"ts-ignore": true, | ||
"ts-expect-error": false | ||
}], | ||
"@typescript-eslint/ban-types": ["error", { | ||
"types": { | ||
"{}": false, | ||
"object": false, | ||
"Function": false | ||
}, | ||
"extendDefaults": true | ||
}], | ||
"@typescript-eslint/indent": ["error", "tab"], | ||
"@typescript-eslint/semi": ["error"], | ||
"import/extensions": ["error", "ignorePackages", { | ||
"js": "never", | ||
"ts": "never" | ||
}], | ||
"import/prefer-default-export": "off", | ||
"import/no-default-export": ["error"], | ||
"import/no-cycle": "off", | ||
"no-restricted-syntax": ["error", "WithStatement"], | ||
"linebreak-style": ["error", "unix"], | ||
"comma-dangle": ["error", "never"], | ||
"no-param-reassign": ["error", { | ||
"props": false | ||
}], | ||
"no-unused-expressions": "off", | ||
"no-dupe-class-members": "off", | ||
"no-await-in-loop": "off", | ||
"arrow-parens": "off", | ||
"no-continue": "off", | ||
"no-tabs": ["error", { | ||
"allowIndentationTabs": true | ||
}], | ||
"camelcase": "off", | ||
"indent": "off", | ||
"semi": "off" | ||
}, | ||
"overrides": [ | ||
{ | ||
"files": ["packages/*/test/**/*.test.ts"], | ||
"env": { | ||
"jest": true | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
|
||
# Dependency directories | ||
node_modules | ||
|
||
# Build | ||
packages/*/lib | ||
app.ts | ||
app.js | ||
app.mjs | ||
|
||
docs/.vuepress/dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"name": "cacher-monorepo", | ||
"verbose": true, | ||
"preset": "ts-jest", | ||
"testEnvironment": "node", | ||
"testMatch": ["<rootDir>/packages/*/test/*.test.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "cacher-monorepo", | ||
"private": true, | ||
"workspaces": [ | ||
"packages/*" | ||
], | ||
"engines": { | ||
"node": ">=14.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "^26.0.13", | ||
"@types/node": "^14.6.3", | ||
"@typescript-eslint/eslint-plugin": "^4.0.1", | ||
"@typescript-eslint/parser": "^4.0.1", | ||
"eslint": "^7.8.1", | ||
"eslint-config-airbnb-base": "^14.2.0", | ||
"eslint-plugin-import": "^2.22.0", | ||
"jest": "^26.4.2", | ||
"rollup": "^2.26.9", | ||
"rollup-plugin-typescript2": "^0.27.2", | ||
"ts-jest": "^26.3.0", | ||
"typescript": "^4.0.2" | ||
}, | ||
"scripts": { | ||
"prepare": "yarn run rollup:build && yarn run test", | ||
"build": "yarn run rollup:build", | ||
"watch": "yarn run rollup:watch", | ||
"rollup:build": "NODE_ENV=production rollup -c rollup.config.js", | ||
"rollup:watch": "yarn run rollup:build -w", | ||
"test": "yarn run test:jest && yarn run test:eslint", | ||
"test:jest": "jest --config jest.config.json --no-cache", | ||
"test:eslint": "eslint --ext .ts --ignore-path .gitignore packages/*/src/**/*.ts" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# cacher | ||
Modern implement key-value storage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "@cacher/cacher", | ||
"version": "1.0.0", | ||
"description": "Modern implementation of key-value storage", | ||
"license": "MIT", | ||
"author": { | ||
"name": "Vladlen (Negezor)", | ||
"email": "[email protected]" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/negezor/cacher.git", | ||
"directory": "packages/cacher" | ||
}, | ||
"homepage": "https://github.com/negezor/cacher#readme", | ||
"bugs": "https://github.com/negezor/cacher/issues", | ||
"keywords": [ | ||
"cache" | ||
], | ||
"files": [ | ||
"lib" | ||
], | ||
"main": "lib/index.js", | ||
"types": "./lib/index.d.ts", | ||
"engines": { | ||
"node": ">=14.0.0" | ||
}, | ||
"peerDependencies": { | ||
|
||
}, | ||
"dependencies": { | ||
|
||
}, | ||
"devDependencies": { | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export interface IAdapterSetOptions { | ||
key: string; | ||
value: string; | ||
ttl?: number; | ||
} | ||
|
||
export interface IAdapterTouchOptions { | ||
key: string; | ||
ttl: number; | ||
} | ||
|
||
export interface IAdapter { | ||
get(keys: string[]): Promise<(string | undefined)[]>; | ||
|
||
set(keys: IAdapterSetOptions[]): Promise<void>; | ||
|
||
delete(keys: string[]): Promise<void>; | ||
|
||
touch(keys: IAdapterTouchOptions[]): Promise<void>; | ||
|
||
clear(namespace: string): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './adapter'; | ||
|
||
export * from './memory'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { IAdapter, IAdapterSetOptions } from './adapter'; | ||
|
||
export interface IMapLike<K, V> { | ||
get(key: K): V | undefined; | ||
set(key: K, value: V): this | undefined; | ||
delete(key: K): boolean; | ||
keys(): K[] | IterableIterator<K>; | ||
} | ||
|
||
export interface IMemoryAdapterOptions { | ||
storage?: IMapLike<string, string>; | ||
} | ||
|
||
export class MemoryAdapter implements IAdapter { | ||
protected readonly storage: IMapLike<string, string>; | ||
|
||
public constructor({ storage = new Map() }: IMemoryAdapterOptions = {}) { | ||
this.storage = storage; | ||
} | ||
|
||
public async get(keys: string[]): Promise<(string | undefined)[]> { | ||
return keys.map(key => ( | ||
this.storage.get(key) ?? undefined | ||
)); | ||
} | ||
|
||
public async set(keys: IAdapterSetOptions[]): Promise<void> { | ||
for (const { key, value } of keys) { | ||
this.storage.set(key, value); | ||
} | ||
} | ||
|
||
public async delete(keys: string[]): Promise<void> { | ||
for (const key of keys) { | ||
this.storage.delete(key); | ||
} | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-empty-function, class-methods-use-this | ||
public async touch(): Promise<void> {} | ||
|
||
public async clear(namespace: string): Promise<void> { | ||
for (const key of this.storage.keys()) { | ||
if (key.startsWith(namespace)) { | ||
this.storage.delete(key); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { IAdapter, MemoryAdapter } from './adapters'; | ||
import { | ||
ICacherOptions, | ||
ICacherGetOptions, | ||
ICacherSetOptions, | ||
ICacherTouchOptions, | ||
|
||
Serializer, | ||
Deserializer, | ||
|
||
AllowArray | ||
} from './types'; | ||
import { arraify } from './helpers'; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export class Cacher<V = any> { | ||
protected adapter: IAdapter; | ||
|
||
protected namespace: string; | ||
|
||
protected serializer: Serializer<V>; | ||
|
||
protected deserializer: Deserializer<V>; | ||
|
||
public constructor({ | ||
adapter = new MemoryAdapter(), | ||
|
||
namespace, | ||
|
||
serializer = JSON.stringify, | ||
deserializer = JSON.parse | ||
}: ICacherOptions<V>) { | ||
this.adapter = adapter; | ||
|
||
this.namespace = namespace; | ||
|
||
this.serializer = serializer; | ||
this.deserializer = deserializer; | ||
} | ||
|
||
public async get<K extends string = string, A extends string = string>( | ||
rawKeys: AllowArray<ICacherGetOptions<K, A>> | ||
): Promise<Record<K, V | undefined> & Record<A, V | undefined>> { | ||
const keys = arraify(rawKeys); | ||
|
||
const rawValues = await this.adapter.get( | ||
keys.map(item => this.getNamespaceKey(item.key)) | ||
); | ||
|
||
return Object.fromEntries( | ||
rawValues.map((rawValue, i) => { | ||
const key = keys[i].alias ?? keys[i].key; | ||
|
||
const value = rawValue !== undefined | ||
? this.deserializer(rawValue) | ||
: undefined; | ||
|
||
return [key, value]; | ||
}) | ||
) as unknown as Record<K, V | undefined> & Record<A, V | undefined>; | ||
} | ||
|
||
public set( | ||
rawKeys: AllowArray<ICacherSetOptions<V>> | ||
): Promise<void> { | ||
const keys = arraify(rawKeys); | ||
|
||
return this.adapter.set(keys.map(item => ({ | ||
key: this.getNamespaceKey(item.key), | ||
value: this.serializer(item.value), | ||
ttl: item.ttl | ||
}))); | ||
} | ||
|
||
public async delete(rawKeys: AllowArray<string>): Promise<void> { | ||
const keys = arraify(rawKeys); | ||
|
||
return this.adapter.delete(keys.map(key => ( | ||
this.getNamespaceKey(key) | ||
))); | ||
} | ||
|
||
public async touch(rawKeys: ICacherTouchOptions[]): Promise<void> { | ||
const keys = arraify(rawKeys); | ||
|
||
return this.adapter.touch(keys.map(item => ({ | ||
key: this.getNamespaceKey(item.key), | ||
ttl: item.ttl | ||
}))); | ||
} | ||
|
||
public clear(): Promise<void> { | ||
return this.adapter.clear(this.namespace); | ||
} | ||
|
||
protected getNamespaceKey(key: string): string { | ||
return `${this.namespace}:${key}`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const arraify = <T>(value: T | T[]): T[] => ( | ||
Array.isArray(value) | ||
? value | ||
: [value] | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from './cacher'; | ||
|
||
export * from './adapters'; | ||
|
||
export * from './types'; |
Oops, something went wrong.