Skip to content

Instantly share code, notes, and snippets.

@luoling8192
Created May 8, 2025 10:38
Show Gist options
  • Select an option

  • Save luoling8192/65a3c7374368a04a4872e77d406cd2e4 to your computer and use it in GitHub Desktop.

Select an option

Save luoling8192/65a3c7374368a04a4872e77d406cd2e4 to your computer and use it in GitHub Desktop.
Telegram Search Microtask
import type { TakeoutTaskMetadata } from '../services/takeout'
import { useLogger } from '@tg-search/common'
import defu from 'defu'
type CoreTaskType = 'takeout' | 'getMessage' | 'embed'
interface CoreTasks {
takeout: TakeoutTaskMetadata
getMessage: undefined
embed: undefined
}
export interface CoreTask<T extends CoreTaskType> {
taskId: string
type: T
progress: number
lastMessage?: string
lastError?: string
metadata: CoreTasks[T]
createdAt: Date
updatedAt: Date
abortController: AbortController
}
function createTask<T extends CoreTaskType>(type: T, metadata: CoreTasks[T]): CoreTask<T> {
return {
taskId: crypto.randomUUID(),
type,
progress: 0,
metadata,
createdAt: new Date(),
updatedAt: new Date(),
abortController: new AbortController(),
}
}
export function useTasks<T extends CoreTaskType>(type: T) {
const tasks = new Map<string, CoreTask<T>>()
function updateTask(taskId: string, partialTask: Partial<CoreTask<T>>) {
const task = tasks.get(taskId)
if (!task) {
throw new Error(`Task ${taskId} not found`)
}
const updatedTask = defu<CoreTask<T>, Partial<CoreTask<T>>[]>({}, partialTask, task, {
updatedAt: new Date(),
})
tasks.set(taskId, updatedTask)
return updatedTask
}
function updateTaskProgress(taskId: string, progress: number, message?: string) {
return updateTask(taskId, {
progress,
lastMessage: message,
})
}
function updateTaskError(taskId: string, error: Error) {
return updateTask(taskId, {
progress: -1,
lastError: error.message,
})
}
function abortTask(taskId: string) {
const task = tasks.get(taskId)
if (!task) {
throw new Error(`Task ${taskId} not found`)
}
task.abortController.abort()
updateTaskError(taskId, new Error('Task aborted'))
useLogger().withFields({ taskId }).verbose('Task aborted')
}
return {
createTask: (data: CoreTasks[T]) => {
const task = createTask(type, data)
tasks.set(task.taskId, task)
return task
},
listTasks: () => {
return Array.from(tasks.values())
},
getTask: (taskId: string) => {
return tasks.get(taskId)
},
updateTaskProgress,
updateTaskError,
abortTask,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment