Skip to content

Commit

Permalink
πŸš€ feat: lets go to jsr [SMALL BREAKING: READ COMMIT MSG]
Browse files Browse the repository at this point in the history
βž• feat: use node redis instead of denodrivers redis
  • Loading branch information
Helloyunho committed Apr 28, 2024
1 parent 9ca7082 commit 47677d3
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 46 deletions.
13 changes: 12 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,16 @@
},
"name": "@harmony/harmony",
"version": "2.9.1",
"exports": "./mod.ts"
"exports": "./mod.ts",
"publish": {
"include": [
"mod.ts",
"deps.ts",
"deploy.ts",
"src/**/*",
"assets/*",
"README.md",
"tsconfig.json"
]
}
}
39 changes: 16 additions & 23 deletions src/cache/redis.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { ICacheAdapter } from './adapter.ts'
// Not in deps.ts to allow optional dep loading
import {
connect,
Redis,
RedisConnectOptions,
RedisValue
} from 'https://deno.land/x/redis@v0.25.1/mod.ts'
import { createClient, RedisClientOptions } from 'npm:redis@4.6.13'

/** Redis Cache Adapter for using Redis as a cache-provider. */
export class RedisCacheAdapter implements ICacheAdapter {
_redis: Promise<Redis>
redis?: Redis
_redis: Promise<ReturnType<typeof createClient>>
redis?: ReturnType<typeof createClient>
ready: boolean = false
readonly _expireIntervalTimer: number = 5000
private _expireInterval?: number

constructor(options: RedisConnectOptions) {
this._redis = connect(options)
constructor(options: RedisClientOptions) {
this._redis = createClient(options).connect()
this._redis.then(
(redis) => {
this.redis = redis
Expand All @@ -31,17 +26,17 @@ export class RedisCacheAdapter implements ICacheAdapter {

private _startExpireInterval(): void {
this._expireInterval = setInterval(() => {
this.redis?.scan(0, { pattern: '*:expires' }).then(([_, names]) => {
this.redis?.scan(0, { MATCH: '*:expires' }).then(({ keys: names }) => {
for (const name of names) {
this.redis?.hvals(name).then((vals) => {
this.redis?.hVals(name).then((vals) => {
for (const val of vals) {
const expireVal: {
name: string
key: string
at: number
} = JSON.parse(val)
const expired = new Date().getTime() > expireVal.at
if (expired) this.redis?.hdel(expireVal.name, expireVal.key)
if (expired) this.redis?.hDel(expireVal.name, expireVal.key)
}
})
}
Expand All @@ -55,7 +50,7 @@ export class RedisCacheAdapter implements ICacheAdapter {

async get<T>(cacheName: string, key: string): Promise<T | undefined> {
await this._checkReady()
const cache = await this.redis?.hget(cacheName, key)
const cache = await this.redis?.hGet(cacheName, key)
if (cache === undefined) return
try {
return JSON.parse(cache) as T
Expand All @@ -71,15 +66,13 @@ export class RedisCacheAdapter implements ICacheAdapter {
expire?: number
): Promise<void> {
await this._checkReady()
await this.redis?.hset(
await this.redis?.hSet(
cacheName,
key,
typeof value === 'object'
? JSON.stringify(value)
: (value as unknown as RedisValue)
typeof value === 'object' ? JSON.stringify(value) : (value as any)
)
if (expire !== undefined) {
await this.redis?.hset(
await this.redis?.hSet(
`${cacheName}:expires`,
key,
JSON.stringify({
Expand All @@ -93,18 +86,18 @@ export class RedisCacheAdapter implements ICacheAdapter {

async delete(cacheName: string, ...keys: string[]): Promise<boolean> {
await this._checkReady()
return ((await this.redis?.hdel(cacheName, ...keys)) ?? 0) === keys.length
return ((await this.redis?.hDel(cacheName, keys)) ?? 0) === keys.length
}

async array<T>(cacheName: string): Promise<T[] | undefined> {
await this._checkReady()
const data = await this.redis?.hvals(cacheName)
const data = await this.redis?.hVals(cacheName)
return data?.map((e: string) => JSON.parse(e))
}

async keys(cacheName: string): Promise<string[] | undefined> {
await this._checkReady()
return this.redis?.hkeys(cacheName)
return this.redis?.hKeys(cacheName)
}

async deleteCache(cacheName: string): Promise<boolean> {
Expand All @@ -114,6 +107,6 @@ export class RedisCacheAdapter implements ICacheAdapter {

async size(cacheName: string): Promise<number | undefined> {
await this._checkReady()
return this.redis?.hlen(cacheName)
return this.redis?.hLen(cacheName)
}
}
9 changes: 7 additions & 2 deletions src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {
fetchGatewayInfo: boolean = true

/** Voice Connections Manager */
readonly voice = new VoiceManager(this)
readonly voice: VoiceManager = new VoiceManager(this)

/** Users Manager, containing all Users cached */
readonly users: UsersManager = new UsersManager(this)
Expand Down Expand Up @@ -487,7 +487,12 @@ export class Client extends HarmonyEventEmitter<ClientEvents> {

/** Event decorator to create an Event handler from function */
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export function event(name?: keyof ClientEvents) {
export function event(
name?: keyof ClientEvents
): (
original: (...args: any[]) => any,
ctx: ClassMethodDecoratorContext<Client | Extension>
) => (...args: any[]) => any {
return function (
original: (...args: any[]) => any,
{
Expand Down
18 changes: 15 additions & 3 deletions src/commands/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ export class CommandClient extends Client implements CommandClientOptions {
commands: CommandsManager = new CommandsManager(this)
categories: CategoriesManager = new CategoriesManager(this)

middlewares = new Array<CommandContextMiddleware<CommandContext>>()
middlewares: Array<CommandContextMiddleware<CommandContext>> = new Array<
CommandContextMiddleware<CommandContext>
>()

globalCommandCooldown = 0
globalCooldown = 0
Expand Down Expand Up @@ -518,7 +520,12 @@ export class CommandClient extends Client implements CommandClientOptions {
/**
* Command decorator. Decorates the function with optional metadata as a Command registered upon constructing class.
*/
export function command(options?: CommandOptions) {
export function command(
options?: CommandOptions
): (
original: (...args: any[]) => any,
ctx: ClassMethodDecoratorContext<CommandClient | Extension>
) => (...args: any[]) => any {
return function (
original: (...args: any[]) => any,
{
Expand Down Expand Up @@ -552,7 +559,12 @@ export function command(options?: CommandOptions) {
/**
* Sub Command decorator. Decorates the function with optional metadata as a Sub Command registered upon constructing class.
*/
export function subcommand(options?: CommandOptions) {
export function subcommand(
options?: CommandOptions
): (
original: (...args: any[]) => any,
ctx: ClassMethodDecoratorContext<Command>
) => (...args: any[]) => any {
return function (
original: (...args: any[]) => any,
{
Expand Down
2 changes: 1 addition & 1 deletion src/rest/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ let invalidCount = 0
let invalidCountResetTime: number | null = null

export class BucketHandler {
queue = new RequestQueue()
queue: RequestQueue = new RequestQueue()
reset = -1
remaining = -1
limit = -1
Expand Down
19 changes: 15 additions & 4 deletions src/structures/guildNewsChannel.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { Mixin } from '../../deps.ts'
import type { GuildNewsChannelPayload } from '../types/channel.ts'
import type { Client } from '../client/mod.ts'
import type { Guild } from './guild.ts'
import { GuildTextBasedChannel } from './guildTextChannel.ts'
import { GuildThreadAvailableChannel } from './guildThreadAvailableChannel.ts'

export class NewsChannel extends Mixin(
GuildTextBasedChannel,
GuildThreadAvailableChannel
) {}
const NewsChannelSuper: (abstract new (
client: Client,
data: GuildNewsChannelPayload,
guild: Guild
) => GuildTextBasedChannel & GuildThreadAvailableChannel) &
Pick<typeof GuildTextBasedChannel, keyof typeof GuildTextBasedChannel> &
Pick<
typeof GuildThreadAvailableChannel,
keyof typeof GuildThreadAvailableChannel
> = Mixin(GuildTextBasedChannel, GuildThreadAvailableChannel)

export class NewsChannel extends NewsChannelSuper {}
29 changes: 24 additions & 5 deletions src/structures/guildTextChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,19 @@ import { CHANNEL } from '../types/endpoint.ts'
import type { Message } from './message.ts'
import { GuildThreadAvailableChannel } from './guildThreadAvailableChannel.ts'

const GuildTextBasedChannelSuper: (abstract new (
client: Client,
data: GuildTextBasedChannelPayload,
guild: Guild
) => TextChannel & GuildChannel) &
Pick<typeof TextChannel, keyof typeof TextChannel> &
Pick<typeof GuildChannel, keyof typeof GuildChannel> = Mixin(
TextChannel,
GuildChannel
)

/** Represents a Text Channel but in a Guild */
export class GuildTextBasedChannel extends Mixin(TextChannel, GuildChannel) {
export class GuildTextBasedChannel extends GuildTextBasedChannelSuper {
constructor(
client: Client,
data: GuildTextBasedChannelPayload,
Expand Down Expand Up @@ -81,8 +92,16 @@ export class GuildTextBasedChannel extends Mixin(TextChannel, GuildChannel) {
}
}

const GuildTextChannelSuper: (abstract new (
client: Client,
data: any,
guild: Guild
) => GuildTextBasedChannel & GuildThreadAvailableChannel) &
Pick<typeof GuildTextBasedChannel, keyof typeof GuildTextBasedChannel> &
Pick<
typeof GuildThreadAvailableChannel,
keyof typeof GuildThreadAvailableChannel
> = Mixin(GuildTextBasedChannel, GuildThreadAvailableChannel)

// Still exist for API compatibility
export class GuildTextChannel extends Mixin(
GuildTextBasedChannel,
GuildThreadAvailableChannel
) {}
export class GuildTextChannel extends GuildTextChannelSuper {}
24 changes: 18 additions & 6 deletions src/structures/guildVoiceChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,26 @@ import type {
import { Mixin } from '../../deps.ts'
import { TextChannel } from './textChannel.ts'

export class VoiceChannel extends Mixin(GuildChannel, TextChannel) {
const VoiceChannelSuper: (abstract new (
client: Client,
data: GuildVoiceChannelPayload,
guild: Guild
) => TextChannel & GuildChannel) &
Pick<typeof TextChannel, keyof typeof TextChannel> &
Pick<typeof GuildChannel, keyof typeof GuildChannel> = Mixin(
TextChannel,
GuildChannel
)

export class VoiceChannel extends VoiceChannelSuper {
bitrate!: string
userLimit!: number
voiceStates = new GuildChannelVoiceStatesManager(
this.client,
this.guild.voiceStates,
this
)
voiceStates: GuildChannelVoiceStatesManager =
new GuildChannelVoiceStatesManager(
this.client,
this.guild.voiceStates,
this
)

constructor(client: Client, data: GuildVoiceChannelPayload, guild: Guild) {
super(client, data, guild)
Expand Down
2 changes: 1 addition & 1 deletion src/utils/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type PermissionResolvable = BitFieldResolvable
/** Represents permissions BitField */
export class Permissions extends BitField {
static DEFAULT = 104324673n
static ALL = Object.values(PermissionFlags).reduce(
static ALL: bigint = Object.values(PermissionFlags).reduce(
(all, p) => BigInt(all) | BigInt(p),
0n
)
Expand Down

0 comments on commit 47677d3

Please sign in to comment.