UNPKG

@equinor/fusion-query

Version:

Reactive data fetching and caching library with observable streams and comprehensive event system

106 lines (101 loc) 4.74 kB
import { Subject, type Subscription } from 'rxjs'; import { finalize, map } from 'rxjs/operators'; import type { QueryOptions, QueryTaskCompleted } from './types'; import type { QueryClientJob } from './client/QueryClientJob'; import { v4 as generateGUID } from 'uuid'; /** * The `QueryTask` class is designed to manage and execute query operations efficiently. It extends the RxJS `Subject` to * allow for easy subscription to the outcome of the query operation. This class is generic and can be used with any type * of query result (`TType`) and arguments (`TArgs`) necessary for executing the query. * * Upon instantiation, each `QueryTask` is assigned a unique identifier and a timestamp marking its creation. This * information, along with the key and arguments provided during construction, are used to manage and track the query * throughout its lifecycle. * * The primary method, `processJob`, takes a `QueryClientJob` and an optional `ILogger` for logging purposes. It processes * the job by mapping its result to a `QueryTaskCompleted` object, logging the completion, and then notifying all * subscribers of the completion. This method leverages RxJS operators for a clean and manageable implementation. * * ### Generics: * - `TType`: The expected type of the query result. This type will be used to type-check the result of the query operation, * ensuring type safety throughout the usage of this class. * - `TArgs`: The type of the arguments required to perform the query. This ensures that only the correct types of arguments * are passed to execute the query, preventing runtime errors and ensuring type safety. * * ### Properties: * - `key`: A string that represents the key associated with the query. This key is used to identify the query operation. * - `args`: The arguments required for performing the query. The type of `args` is generic and specified by `TArgs`. * - `options`: An optional parameter that allows for additional configuration of the query execution. This is a partial * of `QueryOptions<TType, TArgs>`, allowing for flexibility in specifying query options. * - `created`: A read-only property that returns the timestamp marking the creation of the `QueryTask` instance. * - `uuid`: A read-only property that returns the unique identifier of the `QueryTask` instance. * * ### Method: * - `processJob(job: QueryClientJob<TType, TArgs>, logger?: ILogger): Subscription`: Processes the provided `QueryClientJob`, * applying necessary transformations and finalizations. It returns a `Subscription` to the job's result, allowing for * further manipulation or cleanup if necessary. * * This class provides a robust and type-safe way to handle query operations, making it a valuable tool for managing * asynchronous data retrieval and processing within the application. * * @template TType - The type of the query result. * @template TArgs - The type of the query arguments. */ export class QueryTask<TType, TArgs> extends Subject<QueryTaskCompleted<TType>> { #created: number = Date.now(); /** * Gets the creation timestamp of the query task. */ get created(): number { return this.#created; } #uuid: string = generateGUID(); /** * Gets the unique identifier of the query task. */ get uuid(): string { return this.#uuid; } /** * Initializes a new instance of the QueryTask class. * @param key A string representing the key associated with the query. * @param args The arguments required for performing the query. * @param options Optional. Additional options that may influence the query execution. */ constructor( public readonly key: string, public readonly args: TArgs, public readonly options?: Partial<QueryOptions<TType, TArgs>>, ) { super(); } /** * Processes the given `QueryClientJob`, applying necessary transformations and finalizations. * Once the job completes, it notifies all subscribers with the result and logs the completion. * * @param job The `QueryClientJob` to be processed. * @param logger Optional. A logger for logging the completion of the job. * @returns A subscription to the job's result. */ processJob(job: QueryClientJob<TType, TArgs>): Subscription { return job .pipe( map((result) => { const { key, uuid, created } = this; return { key, uuid, created, status: 'complete', transaction: job.transaction, complete: result.completed, value: result.value, } satisfies QueryTaskCompleted<TType>; }), finalize(() => { job.complete(); }), ) .subscribe(this); } }