import { Observable } from '../utils/rx' import type { ArrayOrSpreadFn } from '../utils/fp' import type { Unsubscribe, SharedSubscribable } from '../utils/subscriptions' import { $Exact } from '../types' import type { Clause, QueryDescription } from '../QueryDescription' import type Model from '../Model' import type { AssociationInfo, RecordId } from '../Model' import type Collection from '../Collection' import type { TableName, ColumnName } from '../Schema' export type QueryAssociation = $Exact<{ from: TableName to: TableName info: AssociationInfo }> export type SerializedQuery = $Exact<{ table: TableName description: QueryDescription associations: QueryAssociation[] }> interface QueryCountProxy { then( onFulfill?: (value: number) => Promise | U, onReject?: (error: any) => Promise | U, ): Promise } export default class Query { // Used by withObservables to differentiate between object types static _wmelonTag: string collection: Collection description: QueryDescription _rawDescription: QueryDescription _cachedSubscribable: SharedSubscribable _cachedCountSubscribable: SharedSubscribable _cachedCountThrottledSubscribable: SharedSubscribable // Note: Don't use this directly, use Collection.query(...) constructor(collection: Collection, clauses: Clause[]) // Creates a new Query that extends the clauses of this query extend: ArrayOrSpreadFn> pipe(transform: (_: this) => T): T // Queries database and returns an array of matching records fetch(): Promise then( onFulfill?: (value: Record[]) => Promise | U, onReject?: (error: any) => Promise | U, ): Promise // Emits an array of matching records, then emits a new array every time it changes observe(): Observable // Same as `observe()` but also emits the list when any of the records // on the list has one of `columnNames` chaged observeWithColumns(columnNames: ColumnName[]): Observable // Queries database and returns the number of matching records fetchCount(): Promise get count(): QueryCountProxy // Emits the number of matching records, then emits a new count every time it changes // Note: By default, the Observable is throttled! observeCount(isThrottled?: boolean): Observable // Queries database and returns an array with IDs of matching records fetchIds(): Promise // Queries database and returns an array with unsanitized raw results // You MUST NOT mutate these objects! unsafeFetchRaw(): Promise experimentalSubscribe(subscriber: (records: Record[]) => void): Unsubscribe experimentalSubscribeWithColumns( columnNames: ColumnName[], subscriber: (records: Record[]) => void, ): Unsubscribe experimentalSubscribeToCount(subscriber: (_: number) => void): Unsubscribe // Marks as deleted all records matching the query markAllAsDeleted(): Promise // Destroys all records matching the query destroyAllPermanently(): Promise // MARK: - Internals get modelClass(): Record get table(): TableName get secondaryTables(): TableName[] get allTables(): TableName[] get associations(): QueryAssociation[] // Serialized version of Query (e.g. for sending to web worker) serialize(): SerializedQuery }