From cb276e31a8dc2795451c6dc762029e683ffeef25 Mon Sep 17 00:00:00 2001 From: Om Gate Date: Mon, 19 Jan 2026 15:32:58 +0530 Subject: [PATCH 01/66] feat: removing `Job` handling completely --- src/core/collection.ts | 28 ++- src/core/video.ts | 110 +++++------ src/index.ts | 3 +- src/interfaces/core.ts | 11 +- src/utils/httpClient.ts | 89 +++++++-- src/utils/index.ts | 21 --- src/utils/job.ts | 394 ---------------------------------------- src/utils/upload.ts | 33 +++- 8 files changed, 169 insertions(+), 520 deletions(-) delete mode 100644 src/utils/job.ts diff --git a/src/core/collection.ts b/src/core/collection.ts index 49cb4ec..d9fa5db 100644 --- a/src/core/collection.ts +++ b/src/core/collection.ts @@ -184,28 +184,24 @@ export class Collection implements ICollection { }; /** - * @param filePath - absolute path to a file - * @param callbackUrl- [optional] A url that will be called once upload is finished - * @param name - [optional] Name of the file - * @param description - [optional] Description of the file - * - * @see - * Providing a callbackUrl will return undefined and not providing one - * will return a Job object (TODO: Implement proper type for this condition) + * Upload a file from the local filesystem. + * @param data.filePath - absolute path to a file + * @param data.callbackUrl - [optional] A url that will be called once upload is finished + * @param data.name - [optional] Name of the file + * @param data.description - [optional] Description of the file + * @returns Video, Audio, or Image object. Returns undefined if callbackUrl is provided. */ public uploadFile = async (data: FileUploadConfig) => { return uploadToServer(this.#vhttp, this.meta.id, data); }; /** - * @param URL - URL of the hosted file - * @param callbackUrl- [optional] A url that will be called once upload is finished - * @param name - [optional] Name of the file - * @param description - [optional] Description of the file - * - * @see - * Providing a callbackUrl will return undefined and not providing one - * will return a Job object (TODO: Implement proper type for this condition) + * Upload a file from a URL. + * @param data.url - URL of the hosted file + * @param data.callbackUrl - [optional] A url that will be called once upload is finished + * @param data.name - [optional] Name of the file + * @param data.description - [optional] Description of the file + * @returns Video, Audio, or Image object. Returns undefined if callbackUrl is provided. */ public uploadURL = async (data: URLUploadConfig) => { return uploadToServer(this.#vhttp, this.meta.id, data); diff --git a/src/core/video.ts b/src/core/video.ts index 66ecb22..a682b78 100644 --- a/src/core/video.ts +++ b/src/core/video.ts @@ -9,6 +9,9 @@ import { type GenerateStreamResponse, ListSceneCollection, SceneCollectionResponse, + TranscriptResponse, + GetSceneIndexResponse, + NoDataResponse, } from '@/types/response'; import type { Timeline, Transcript } from '@/types/video'; import { fromCamelToSnake, playStream } from '@/utils'; @@ -19,12 +22,6 @@ import { IndexTypeValues, SceneExtractionType, } from '@/core/config'; -import { - IndexJob, - TranscriptJob, - SceneIndexJob, - ExtractScenesJob, -} from '@/utils/job'; import { SearchFactory } from './search'; import { ExtractSceneConfig, @@ -34,7 +31,7 @@ import { import { SearchType, IndexType } from '@/types/search'; import { SceneIndexRecords, SceneIndexes } from '@/types'; -const { video, stream, thumbnail, workflow, index, scene, scenes } = ApiPath; +const { video, stream, thumbnail, workflow, index, scene, scenes, transcription } = ApiPath; /** * The base Video class @@ -137,29 +134,41 @@ export class Video implements IVideo { * Fetches the transcript of the video if it exists, generates one * if it doesn't. * @param forceCreate - Forces transcript generation even if it exists - * @returns A promise of - - * - If the transcript exists, an object of the type Transcript - * - If it doesn't, an instance of TranscriptJob which can be used - * to start transcript generation. + * @returns The transcript data */ - public getTranscript = (forceCreate = false) => { + public getTranscript = async (forceCreate = false): Promise => { if (this.transcript && !forceCreate) return this.transcript; - const job = new TranscriptJob(this.#vhttp, this.meta.id, forceCreate); - return job; + + const res = await this.#vhttp.get([ + video, + this.meta.id, + transcription, + `?force=${String(forceCreate)}`, + ]); + + const transcript = fromSnakeToCamel(res.data) as unknown as Transcript; + this.transcript = transcript; + return transcript; }; /** - * Indexs the video semantically - * @returns an awaited boolean signifying whether the process - * was successful or not + * Indexes the video semantically + * @returns Whether the process was successful */ - public indexSpokenWords = () => { - const indexJob = new IndexJob( - this.#vhttp, - this.meta.id, - IndexTypeValues.spoken + public indexSpokenWords = async (): Promise<{ success: boolean; message?: string }> => { + const reqData = fromCamelToSnake({ indexType: IndexTypeValues.spoken }); + const res = await this.#vhttp.post( + [video, this.meta.id, index], + reqData ); - return indexJob; + + if (res.data?.success !== undefined) { + return { + success: res.data.success, + message: res.data.message, + }; + } + return { success: true }; }; public _formatSceneCollectionData = ( @@ -199,7 +208,9 @@ export class Video implements IVideo { }); }; - public extractScenes = async (config: Partial = {}) => { + public extractScenes = async ( + config: Partial = {} + ): Promise => { const defaultConfig = { extractionType: SceneExtractionType.shotBased, extractionConfig: {}, @@ -208,25 +219,14 @@ export class Video implements IVideo { const extractScenePayload = fromCamelToSnake( Object.assign({}, defaultConfig, config) ); - const extractScenesJob = new ExtractScenesJob( - this.#vhttp, - this.meta.id, + + const res = await this.#vhttp.post<{ sceneCollection: object }, object>( + [video, this.meta.id, scenes], extractScenePayload ); - return new Promise((resolve, reject) => { - extractScenesJob.on('success', data => { - resolve(this._formatSceneCollectionData(data)); - }); - extractScenesJob.on('error', err => { - reject(err); - }); - extractScenesJob - .start() - .then(() => {}) - .catch(err => { - reject(err); - }); - }); + + const data = fromSnakeToCamel(res.data.sceneCollection); + return this._formatSceneCollectionData(data); }; public listSceneCollection = async () => { @@ -303,26 +303,16 @@ export class Video implements IVideo { return transformed as SceneIndexes; }; - public getSceneIndex = async (sceneIndexId: string) => { - const sceneIndexJob = new SceneIndexJob( - this.#vhttp, + public getSceneIndex = async (sceneIndexId: string): Promise => { + const res = await this.#vhttp.get([ + video, this.meta.id, - sceneIndexId - ); - return new Promise((resolve, reject) => { - sceneIndexJob.on('success', data => { - resolve(data); - }); - sceneIndexJob.on('error', err => { - reject(err); - }); - sceneIndexJob - .start() - .then(() => {}) - .catch(err => { - reject(err); - }); - }); + index, + scene, + sceneIndexId, + ]); + + return fromSnakeToCamel(res.data).sceneIndexRecords as SceneIndexRecords; }; public deleteSceneIndex = async (sceneIndexId: string) => { diff --git a/src/index.ts b/src/index.ts index cb48a03..1755157 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,10 +32,9 @@ export { AudioAssetConfig, } from './types/config'; export { SubtitleAlignment, SubtitleBorderStyle } from './core/config'; -export { IndexJob, UploadJob, TranscriptJob } from './utils/job'; export { Shot } from './core/shot'; export { VideodbError } from './utils/error'; export { SearchResult } from './core/search/searchResult'; -export { playStream, waitForJob } from './utils/index'; +export { playStream } from './utils/index'; export { connect, Connection }; diff --git a/src/interfaces/core.ts b/src/interfaces/core.ts index ecd93fc..83f66cd 100644 --- a/src/interfaces/core.ts +++ b/src/interfaces/core.ts @@ -1,9 +1,10 @@ import { SearchResult } from '@/core/search/searchResult'; import { Video } from '@/core/video'; +import { Audio } from '@/core/audio'; +import { Image } from '@/core/image'; import type { SearchType } from '@/types/search'; import type { FileUploadConfig, URLUploadConfig } from '@/types/collection'; import type { StreamableURL, Timeline, Transcript } from '@/types/video'; -import { IndexJob, TranscriptJob, UploadJob } from '@/utils/job'; import { AudioAsset, VideoAsset } from '..'; import { IndexSceneConfig, SubtitleStyleProps } from '@/types/config'; @@ -23,8 +24,8 @@ export interface ICollection { getVideos: () => Promise; getVideo: (videoId: string) => Promise