import { SubscriptionRegistry, Handler, DeepstreamConfig, DeepstreamServices, SocketWrapper } from '@deepstream/types'; import { ListenerRegistry } from '../../listen/listener-registry'; import { RecordMessage, RecordWriteMessage } from '../../constants'; export default class RecordHandler extends Handler { private readonly config; private readonly services; private readonly metaData?; private subscriptionRegistry; private listenerRegistry; private transitions; private recordRequestsInProgress; private recordRequest; /** * The entry point for record related operations */ constructor(config: DeepstreamConfig, services: DeepstreamServices, subscriptionRegistry?: SubscriptionRegistry, listenerRegistry?: ListenerRegistry, metaData?: any | undefined); close(): Promise; /** * Handles incoming record requests. * * Please note that neither CREATE nor READ is supported as a * client send action. Instead the client sends CREATEORREAD * and deepstream works which one it will be */ handle(socketWrapper: SocketWrapper | null, message: RecordMessage): void; private handleClusterUpdate; private recordUpdatedWithoutDeepstream; /** * Returns just the current version number of a record * Results in a HEAD_RESPONSE * If the record is not found, the version number will be -1 */ private head; private subscribeAndHeadBulk; private onSubscribeCreateAndRead; private onSubscribeAndRead; /** * An upsert operation where the record will be created and written to * with the data in the message. Important to note that each operation, * the create and the write are permissioned separately. * * This method also takes note of the storageHotPathPatterns option, when a record * with a name that matches one of the storageHotPathPatterns is written to with * the CREATEANDUPDATE action, it will be permissioned for both CREATE and UPDATE, then * inserted into the cache and storage. */ private createAndUpdate; /** * Forcibly writes to the cache and storage layers without going via * the RecordTransition. Usually updates and patches will go via the * transition which handles write acknowledgements, however in the * case of a hot path write acknowledgement we need to handle that * case here. */ private forceWrite; /** * Handles write acknowledgements during a force write. Usually * this case is handled via the record transition. */ handleForceWriteAcknowledgement(socketWrapper: SocketWrapper, message: RecordWriteMessage, cacheResponse: boolean, storageResponse: boolean, error: Error | string | null): void; /** * Creates a new, empty record and triggers a read operation once done */ private create; /** * Subscribes to updates for a record and sends its current data once done */ private readAndSubscribe; /** * Applies both full and partial updates. Creates a new record transition that will live as * long as updates are in flight and new updates come in */ private update; /** * Invoked by RecordTransition. Notifies local subscribers and other deepstream * instances of record updates */ broadcastUpdate(name: string, message: RecordMessage, noDelay: boolean, originalSender: SocketWrapper | null): void; /** * Called by a RecordTransition, either if it is complete or if an error occured. Removes * the transition from the registry */ transitionComplete(recordName: string): void; /** * Executes or schedules a callback function once all transitions are complete * * This is called from the PermissionHandler destroy method, which * could occur in cases where 'runWhenRecordStable' is never called, * such as when no cross referencing or data loading is used. */ removeRecordRequest(recordName: string): void; /** * Executes or schedules a callback function once all record requests are removed. * This is critical to block reads until writes have occured for a record, which is * only from permissions when a rule is required to be run and the cache has not * verified it has the latest version */ runWhenRecordStable(recordName: string, callback: Function): void; /** * Deletes a record. If a transition is in progress it will be stopped. Once the deletion is * complete, an ACK is returned to the sender and broadcast to the message bus. */ private delete; /** * Handle a remote record deletion from the message bus. We assume that the original deepstream node * has already deleted the record from cache and storage and we only need to broadcast the message * to subscribers. * * If a transition is in progress it will be stopped. */ private remoteDelete; private onDeleted; /** * A secondary permissioning step that is performed once we know if the record exists (READ) * or if it should be created (CREATE) */ private permissionAction; private onPermissionResponse; }