feat!: big feature changes

BREAKING CHANGES:
- Heartbeating removed
- `config.consoleLogLevel` -> `config.logLevel`

NEW FEATURES:
- Training messages
- Sequence number system
- WebSocket close codes used instead of disconnect packets

FIXES:
- Improved error handling
- Some performance improvements
- Made code more clean
- Updated dependencies
This commit is contained in:
PalmDevs
2024-03-28 21:41:59 +07:00
parent 77f1a9cb3e
commit b3b7723b4f
33 changed files with 562 additions and 506 deletions

View File

@@ -1,20 +1,33 @@
import type { ClientOperation } from '@revanced/bot-shared'
import type { Logger } from '@revanced/bot-shared'
import type { Wit } from 'node-wit'
import type { Worker as TesseractWorker } from 'tesseract.js'
import { ClientPacketObject } from '../classes/Client'
import type { Config } from '../utils/getConfig'
import type { ClientPacketObject } from '../classes/Client'
import type { Config } from '../utils/config'
export { default as parseTextEventHandler } from './parseText'
export { default as parseImageEventHandler } from './parseImage'
export { default as trainMessageEventHandler } from './trainMessage'
export type EventHandler<POp extends ClientOperation> = (
packet: ClientPacketObject<POp>,
context: EventContext,
) => void | Promise<void>
export type EventContext = {
witClient: Wit
tesseractWorker: TesseractWorker
wit: {
train(text: string, label: string): Promise<void>
message(text: string): Promise<WitMessageResponse>
}
tesseract: TesseractWorker
logger: Logger
config: Config
}
export interface WitMessageResponse {
text: string
intents: Array<{
id: string
name: string
confidence: number
}>
}

View File

@@ -1,19 +1,21 @@
import { ClientOperation, ServerOperation } from '@revanced/bot-shared'
import { type ClientOperation, ServerOperation } from '@revanced/bot-shared'
import { AsyncQueue } from '@sapphire/async-queue'
import type { EventHandler } from './index'
import type { EventHandler } from '.'
const queue = new AsyncQueue()
const parseImageEventHandler: EventHandler<ClientOperation.ParseImage> = async (
packet,
{ tesseractWorker, logger, config },
{ tesseract, logger, config },
) => {
const {
client,
d: { image_url: imageUrl, id },
d: { image_url: imageUrl },
} = packet
const nextSeq = client.currentSequence++
logger.debug(`Client ${client.id} requested to parse image from URL:`, imageUrl)
logger.debug(`Queue currently has ${queue.remaining}/${config.ocrConcurrentQueues} items in it`)
@@ -23,24 +25,27 @@ const parseImageEventHandler: EventHandler<ClientOperation.ParseImage> = async (
try {
logger.debug(`Recognizing image from URL for client ${client.id}`)
const { data, jobId } = await tesseractWorker.recognize(imageUrl)
const { data, jobId } = await tesseract.recognize(imageUrl)
logger.debug(`Recognized image from URL for client ${client.id} (job ${jobId}):`, data.text)
await client.send({
op: ServerOperation.ParsedImage,
d: {
id,
text: data.text,
await client.send(
{
op: ServerOperation.ParsedImage,
d: {
text: data.text,
},
},
})
nextSeq,
)
} catch {
logger.error(`Failed to parse image from URL for client ${client.id}:`, imageUrl)
await client.send({
op: ServerOperation.ParseImageFailed,
d: {
id,
await client.send(
{
op: ServerOperation.ParseImageFailed,
d: null,
},
})
nextSeq,
)
} finally {
queue.shift()
logger.debug(

View File

@@ -1,35 +1,41 @@
import { ClientOperation, ServerOperation } from '@revanced/bot-shared'
import { type ClientOperation, ServerOperation } from '@revanced/bot-shared'
import { inspect as inspectObject } from 'util'
import type { EventHandler } from './index'
import type { EventHandler } from '.'
const parseTextEventHandler: EventHandler<ClientOperation.ParseText> = async (packet, { witClient, logger }) => {
const parseTextEventHandler: EventHandler<ClientOperation.ParseText> = async (packet, { wit, logger }) => {
const {
client,
d: { text, id },
d: { text },
} = packet
logger.debug(`Client ${client.id} requested to parse text:`, text)
const nextSeq = client.currentSequence++
const actualText = text.slice(0, 279)
logger.debug(`Client ${client.id} requested to parse text:`, actualText)
try {
const { intents } = await witClient.message(text, {})
const { intents } = await wit.message(actualText)
const intentsWithoutIds = intents.map(({ id, ...rest }) => rest)
await client.send({
op: ServerOperation.ParsedText,
d: {
id,
labels: intentsWithoutIds,
await client.send(
{
op: ServerOperation.ParsedText,
d: {
labels: intentsWithoutIds,
},
},
})
nextSeq,
)
} catch (e) {
await client.send({
op: ServerOperation.ParseTextFailed,
d: {
id,
await client.send(
{
op: ServerOperation.ParseTextFailed,
d: null,
},
})
nextSeq,
)
if (e instanceof Error) logger.error(e.stack ?? e.message)
else logger.error(inspectObject(e))

View File

@@ -0,0 +1,43 @@
import { type ClientOperation, ServerOperation } from '@revanced/bot-shared'
import { inspect as inspectObject } from 'util'
import type { EventHandler } from '.'
const trainMessageEventHandler: EventHandler<ClientOperation.TrainMessage> = async (packet, { wit, logger }) => {
const {
client,
d: { text, label },
} = packet
const nextSeq = client.currentSequence++
const actualText = text.slice(0, 279)
logger.debug(`Client ${client.id} requested to train label ${label} with:`, actualText)
try {
await wit.train(actualText, label)
await client.send(
{
op: ServerOperation.TrainedMessage,
d: null,
},
nextSeq,
)
logger.debug(`Trained label ${label} with:`, actualText)
} catch (e) {
await client.send(
{
op: ServerOperation.TrainMessageFailed,
d: null,
},
nextSeq,
)
if (e instanceof Error) logger.error(e.stack ?? e.message)
else logger.error(inspectObject(e))
}
}
export default trainMessageEventHandler