UNPKG

@camunda8/sdk

Version:

[![NPM](https://nodei.co/npm/@camunda8/sdk.png)](https://www.npmjs.com/package/@camunda8/sdk)

149 lines (148 loc) 7.03 kB
import TypedEmitter from 'typed-emitter'; export declare function QuerySubscription<T>(options: QuerySubscriptionConstructorWithPredicate<T>): _QuerySubscription<T>; export declare function QuerySubscription<T>(options: QuerySubscriptionConstructorsWithoutPredicate<T & { items: Array<unknown>; }>): _QuerySubscription<T>; type QuerySubscriptionReturnValue<T> = void | null | undefined | T | true | false; type QuerySubscriptionPredicate<T> = (previous: T | undefined, current: T) => QuerySubscriptionReturnValue<T> | Promise<QuerySubscriptionReturnValue<T>>; type QuerySubscriptionEvents<T> = { update: (update: T) => void; }; interface QuerySubscriptionConstructorBase<T> { query: () => Promise<T>; interval?: number; /** * Number of poll cycles to track emitted items for duplicate prevention. See: https://github.com/camunda/camunda-8-js-sdk/issues/540 * Set to 0 to disable tracking (not recommended). * Default: 5 */ trackingWindow?: number; } interface QuerySubscriptionConstructorWithPredicate<T> extends QuerySubscriptionConstructorBase<T> { predicate: QuerySubscriptionPredicate<T>; } interface QuerySubscriptionConstructorsWithoutPredicate<T extends { items: Array<unknown>; }> extends QuerySubscriptionConstructorBase<T> { /** predicate to check if the result is valid - optional when T has items array */ predicate?: QuerySubscriptionPredicate<T>; } /** * @description QuerySubscription is a utility class that allows you to subscribe to a query and receive updates when the query result changes. * It is useful for polling operations where you want to receive updates when the result of a query changes, such as when a process instance is created or updated. * It uses a predicate function to determine whether to emit an update event. When using the Orchestration Cluster API, the default predicate checks if the result has new items compared to the previous state. * The predicate function receives the previous state and the current state of the query result and should return a value that indicates whether to emit an update. * If the predicate returns `true`, the current state is emitted. If it returns an object, that object is emitted as the update. * If it returns `false`, no update is emitted. * @experimental This is an experimental feature and may change in the future. * It is not yet stable and may have breaking changes in future releases. We're still working on it, and we welcome feedback. * Please use it with caution and be prepared for potential changes. * @example * ```ts * const query = () => * c8.searchProcessInstances({ * filter: { * processDefinitionKey: key, * state: 'ACTIVE', * }, * sort: [{ field: 'startDate', order: 'ASC' }], * }) * * const subscription = QuerySubscription({ * query, * predicate: (previous, current) => { // This is the default predicate, shown here for clarity * const previousItems = (previous?.items ?? []) as Array<unknown> * const currentItems = current.items.filter( * (item) => * !previousItems.some((prevItem) => isDeepStrictEqual(prevItem, item)) * ) * if (currentItems.length > 0) { * return { * ...current, * items: currentItems, * page: { ...current.page, totalItems: currentItems.length }, * } * } * return false // No new items, do not emit * }, * interval: 500, * }) * subscription.on('update', (data) => { * console.log('Received new processes:', data.items) * }) * // After some time * subscription.stop() // Stop polling when no longer needed, you can also call `start()` to resume polling * subscription.cancel() // Or cancel the subscription to free resources * ``` * @see {@link PollingOperation} for a simpler polling operation that does a single query. */ declare class _QuerySubscription<T> { private _query; /** The current state of the query, used to compare with the next result */ private _state; private _predicate; private _pollHandle; /** We prevent further polling while we are calculating the predicate */ private _predicateLock; /** We prevent further polling while we are processing the current poll */ private _pollLock; /** Track items we've emitted to prevent duplicates within a limited window of poll cycles */ private _recentEmittedItems; /** Current poll cycle number, used for the rolling window of tracked items */ private _currentPollCycle; /** Number of poll cycles to track emitted items for duplicate prevention */ private _trackingWindow; private _interval; private emitter; on: <E extends 'update'>(event: E, listener: QuerySubscriptionEvents<T>[E]) => TypedEmitter<QuerySubscriptionEvents<T>>; off: <E extends 'update'>(event: E, listener: QuerySubscriptionEvents<T>[E]) => TypedEmitter<QuerySubscriptionEvents<T>>; once: <E extends 'update'>(event: E, listener: QuerySubscriptionEvents<T>[E]) => TypedEmitter<QuerySubscriptionEvents<T>>; private emit; removeListener: <E extends 'update'>(event: E, listener: QuerySubscriptionEvents<T>[E]) => TypedEmitter<QuerySubscriptionEvents<T>>; removeAllListeners: <E extends 'update'>(event?: E | undefined) => TypedEmitter<QuerySubscriptionEvents<T>>; prependListener: <E extends 'update'>(event: E, listener: QuerySubscriptionEvents<T>[E]) => TypedEmitter<QuerySubscriptionEvents<T>>; prependOnceListener: <E extends 'update'>(event: E, listener: QuerySubscriptionEvents<T>[E]) => TypedEmitter<QuerySubscriptionEvents<T>>; listeners: <E extends 'update'>(event: E) => QuerySubscriptionEvents<T>[E][]; private _poll?; constructor(options: QuerySubscriptionConstructorWithPredicate<T> | QuerySubscriptionConstructorsWithoutPredicate<T & { items: Array<unknown>; }>); pause(): void; cancel(): void; resume(): void; /** * Gets the hash for an item, used for tracking across poll cycles * @param item The item to hash * @returns The hash string for the item */ private getItemHash; /** * Gets the item set for a specific poll cycle * @param cycleOffset The offset from the current poll cycle * @returns The set of item hashes for that cycle, or undefined if none exist */ private getCycleItemSet; /** * Check if an item has already been emitted within the tracking window to prevent duplicates */ private hasEmittedItem; /** * Gets or creates an item set for the current poll cycle * @returns The set of item hashes for the current cycle */ private getCurrentCycleItemSet; /** * Advances the poll cycle and cleans up old data */ private advancePollCycle; /** * Mark an item as emitted to prevent duplicates within the tracking window */ private markItemAsEmitted; /** * Safely emit items, preventing duplicates */ private safeEmit; poll(): Promise<void>; } export {};