Skip to content
Merged

V3 #19

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,49 @@ name: Build

on:
push:
branches: [master, v3]
tags: ['*']
pull_request:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
quality:
name: Lint & format
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 24.x
cache: npm

- name: Install dependencies
run: npm ci

- name: Check formatting
run: npm run format:check

- name: Lint
run: npm run lint

test:
name: Test (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
node-version: [lts/*]

node-version: [22.x, 24.x]
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -20,9 +53,10 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm

- name: Install dependencies
run: npm install
run: npm ci

- name: Run tests
run: npm test
9 changes: 9 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"singleQuote": true,
"tabWidth": 4,
"printWidth": 80,
"semi": true,
"trailingComma": "all",
"arrowParens": "avoid",
"bracketSpacing": true
}
20 changes: 20 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"categories": {
"correctness": "error"
},
"rules": {
"no-debugger": "error",
"no-console": ["warn", { "allow": ["warn", "error", "info"] }],
"no-unused-vars": "warn"
},
"ignorePatterns": [
"**/*.js",
"**/*.d.ts",
"docs/",
"coverage/",
".nyc_output/",
".agent-out/",
"node_modules/"
]
}
60 changes: 0 additions & 60 deletions eslint.config.mjs

This file was deleted.

87 changes: 41 additions & 46 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,16 @@
* purchase a proprietary commercial license. Please contact us at
* <support@imqueue.com> to get commercial licensing options.
*/
import { ILogger, RedisCache } from '@imqueue/rpc';
import { Redis, ChainableCommander } from 'ioredis';
import { type ILogger, RedisCache } from '@imqueue/rpc';
import { type ChainableCommander, type Redis } from 'ioredis';

export const REDIS_INIT_ERROR = 'Redis engine is not initialized!';

/**
* Empty function used to ignore promises, for cases, when we do not care
* about results and just want to execute some routines in the background
*/
function ignore() { /* do nothing */ }

// noinspection JSUnusedGlobalSymbols
export class TagCache {

public logger: ILogger;
public redis?: Redis;
public readonly key: (key: string) => string;

// noinspection TypeScriptUnresolvedVariable,JSUnusedGlobalSymbols
/**
* @constructor
* @param {RedisCache} cache
Expand All @@ -50,7 +41,6 @@ export class TagCache {
this.key = (this.cache as any).key.bind(this.cache);
}

// noinspection JSUnusedGlobalSymbols
/**
* Returns data stored under given keys. If a single key provided
* returns a single result, otherwise it will return an array of results
Expand All @@ -59,18 +49,14 @@ export class TagCache {
* @param {string[]} keys
* @return Promise<any | null | Array<any | null>>
*/
public async get(
...keys: string[]
): Promise<any | null | (any | null)[]> {
public async get(...keys: string[]): Promise<any | null | (any | null)[]> {
if (!this.redis) {
throw new TypeError(REDIS_INIT_ERROR);
}

try {
if (keys.length === 1) {
const value = await this.redis.get(
this.key(keys[0]),
);
const value = await this.redis.get(this.key(keys[0]));

return value ? JSON.parse(value) : null;
}
Expand All @@ -79,15 +65,14 @@ export class TagCache {
keys.map(key => this.key(key)),
);

return values.map(value => value ? JSON.parse(value) : null);
return values.map(value => (value ? JSON.parse(value) : null));
} catch (err) {
this.logger.warn('TagCache: get error:', err.stack);
this.logger.warn('TagCache: get error:', (err as Error).stack);

return null;
}
}

// noinspection JSUnusedGlobalSymbols
/**
* Stores given value under a given key, tagging it with the given tags
*
Expand All @@ -96,7 +81,7 @@ export class TagCache {
* @param {string[]} tags - tag strings to mark data with
* @param {number} [ttl] - TTL in milliseconds
*/
public async set<T = any>(
public async set<_T = any>(
key: string,
value: any,
tags: string[],
Expand Down Expand Up @@ -130,7 +115,7 @@ export class TagCache {

return true;
} catch (err) {
this.logger.warn('TagCache: set error:', err.stack);
this.logger.warn('TagCache: set error:', (err as Error).stack);

return false;
}
Expand All @@ -150,24 +135,27 @@ export class TagCache {

try {
const tagKeys = tags.map(tag => this.key(`tag:${tag}`));
const keys: string[] = [...new Set(([] as string[]).concat(
...await Promise.all(
tagKeys.map(tag => {
const redis = this.redis;

if (!redis) {
throw new TypeError(REDIS_INIT_ERROR);
}

return new Promise(resolve => {
redis.smembers(
tag,
((_, reply) => resolve(reply)),
);
});
}),
) as unknown as string[],
))];
const keys: string[] = [
...new Set(
([] as string[]).concat(
...((await Promise.all(
tagKeys.map(tag => {
const redis = this.redis;

if (!redis) {
throw new TypeError(REDIS_INIT_ERROR);
}

return new Promise(resolve => {
redis.smembers(tag, (_, reply) =>
resolve(reply),
);
});
}),
)) as unknown as string[]),
),
),
];

if (!keys.length) {
// nothing to do, no keys found
Expand Down Expand Up @@ -195,19 +183,26 @@ export class TagCache {
}
} while (cursor !== '0');

multi.exec().catch(err => this.logger.warn(
'TagCache: invalidate error:', err.stack,
));
multi
.exec()
.catch(err =>
this.logger.warn(
'TagCache: invalidate error:',
(err as Error).stack,
),
);

return true;
} catch (err) {
this.logger.warn('TagCache: invalidate error:', err.stack);
this.logger.warn(
'TagCache: invalidate error:',
(err as Error).stack,
);

return false;
}
}

// noinspection JSUnusedGlobalSymbols
/**
* Destroys this cache instance
*/
Expand Down
Loading
Loading