@hotmeshio/hotmesh
Version:
Serverless Workflow
796 lines (795 loc) • 33.6 kB
TypeScript
import { HotMesh } from '../hotmesh';
import { WorkflowOptions, WorkflowSearchOptions, FindJobsOptions, FindOptions, FindWhereOptions, SearchResults, FindWhereQuery } from '../../types/meshflow';
import { CallOptions, ConnectionInput, ExecInput, HookInput } from '../../types/meshdata';
import { StringAnyType, StringStringType } from '../../types/serializer';
import { JobInterruptOptions, JobOutput } from '../../types/job';
import { QuorumMessage, QuorumMessageCallback, QuorumProfile, RollCallOptions, SubscriptionOptions, ThrottleOptions } from '../../types/quorum';
import { MeshFlowJobExport, ExportOptions } from '../../types/exporter';
import { ProviderConfig, ProvidersConfig } from '../../types/provider';
/**
* The `MeshData` service extends the `MeshFlow` service.
* It serves to unify both data record and
* transactional workflow principles into a single
* *Operational Data Layer*. Deployments with a 'search'
* provider configured (e.g.,Redis FT.SEARCH) can deliver
* both OLTP (transactions) and OLAP (analytics)
* with no additional infrastructure.
*
* The following example depicts the full end-to-end
* lifecycle of a `MeshData` app, including the
* connection of a worker function, the execution of
* a remote function, the retrieval of data,
* the creation of a search index, and the execution
* of a full-text search query.
*
* @example
* ```typescript
* import { MeshData, Types } from '@hotmeshio/hotmesh';
* import * as Redis from 'redis';
*
* //1) Define a search schema
* const schema = {
* schema: {
* id: { type: 'TAG', sortable: true },
* plan: { type: 'TAG', sortable: true },
* active: { type: 'TEXT', sortable: false },
* },
* index: 'user',
* prefix: ['user'], //index items with keys starting with 'user'
* } as unknown as Types.WorkflowSearchOptions;
*
* //2) Initialize MeshData and Redis
* const meshData = new MeshData(
* {
* class: Redis,
* options: { url: 'redis://:key_admin@redis:6379' },
* },
* schema,
* );
*
* //3) Connect a 'user' worker function
* await meshData.connect({
* entity: 'user',
* target: async function(userID: string): Promise<string> {
* //used the `search` extension to add searchable data
* const search = await MeshData.workflow.search();
* await search.set('active', 'yes');
* return `Welcome, ${userID}.`;
* },
* options: { namespace: 'meshdata' },
* });
*
* const userID = 'someTestUser123';
*
* //4) Call the 'user' worker function; include search data
* const response = await meshData.exec({
* entity: 'user',
* args: [userID],
* options: {
* ttl: 'infinity',
* id: userID,
* search: {
* data: { id: userID, plan: 'pro' }
* },
* namespace: 'meshdata',
* },
* });
*
* //5) Read data by field name
* const data = await meshData.get(
* 'user',
* userID,
* {
* fields: ['plan', 'id', 'active'],
* namespace: 'meshdata'
* },
* );
*
* //6) Create a search index
* await meshData.createSearchIndex('user', { namespace: 'meshdata' }, schema);
*
* //7) Perform Full Text Search on the indexed dataset
* const results = await meshData.findWhere('user', {
* query: [{ field: 'id', is: '=', value: userID }],
* limit: { start: 0, size: 100 },
* return: ['plan', 'id', 'active']
* });
*
* //8) Shutdown MeshData
* await MeshData.shutdown();
* ```
*
*/
declare class MeshData {
/**
* unused; allows wrapped functions to be stringified
* so their source can be shared on the network for
* remote analysis. this is useful for targeting which
* version of a function is being executed.
* @private
*/
connectionSignatures: StringStringType;
/**
* The provider configuration for the MeshData service.
* @private
* @example
* // Example 1) Instantiate MeshData with `ioredis`
* import Redis from 'ioredis';
*
* const meshData = new MeshData({
* class: Redis,
* options: {
* host: 'localhost',
* port: 6379,
* password: 'shhh123',
* db: 0,
* }});
*
* // Example 2) Instantiate MeshData with `redis`
* import * as Redis from 'redis';
*
* const meshData = new MeshData({
* class: Redis,
* options: {
* url: 'redis://:shhh123@localhost:6379'
* }});
*
* // Example 3) Instantiate MeshData with `postgres`
* import { Client as PostgresClient } from 'pg';
*
* const meshData = new MeshData({
* class: PostgresClient,
* options: {
* connectionString: 'postgresql://usr:pwd@localhost:5432/db',
* }});
*
* // Example 4) Instantiate MeshData with `postgres` and `nats`
* import { connect as NATS } from 'nats';
*
* const meshData = new MeshData({
* store:{
* class: PostgresClient,
* options: {
* connectionString: 'postgresql://usr:pwd@localhost:5432/db',
* }
* },
* stream:{
* class: PostgresClient,
* options: {
* connectionString: 'postgresql://usr:pwd@localhost:5432/db',
* }
* },
* sub :{
* class: NATS,
* options: {
* server: ['nats://localhost:4222'],
* }
* },
* });
*/
connection: ProviderConfig | ProvidersConfig;
/**
* Cached local instances (map) of HotMesh organized by namespace
* @private
*/
instances: Map<string, Promise<HotMesh> | HotMesh>;
/**
* Search backend configuration (indexed/searchable fields and types)
*/
search: WorkflowSearchOptions;
/**
* Provides a set of static extensions that can be invoked by
* your linked workflow functions during their execution.
* @example
*
* function greet (email: string, user: { first: string}) {
* //persist the user's email and newsletter preferences
* const search = await MeshData.workflow.search();
* await search.set('email', email, 'newsletter', 'yes');
*
* //hook a function to send a newsletter
* await MeshData.workflow.hook({
* entity: 'user.newsletter',
* args: [email]
* });
*
* return `Hello, ${user.first}. Your email is [${email}].`;
* }
*/
static workflow: {
sleep: typeof import("../meshflow/workflow/sleepFor").sleepFor;
sleepFor: typeof import("../meshflow/workflow/sleepFor").sleepFor;
signal: typeof import("../meshflow/workflow/signal").signal;
hook: typeof import("../meshflow/workflow/hook").hook;
waitForSignal: typeof import("../meshflow/workflow/waitFor").waitFor;
waitFor: typeof import("../meshflow/workflow/waitFor").waitFor;
getHotMesh: typeof import("../..").workflow.getHotMesh;
random: typeof import("../meshflow/workflow/random").random;
search: typeof import("../meshflow/workflow/searchMethods").search;
getContext: typeof import("../meshflow/workflow/context").getContext;
/**
* Interrupts a job by its entity and id.
*/
interrupt: (entity: string, id: string, options?: JobInterruptOptions) => Promise<void>;
/**
* Starts a new, subordinated workflow/job execution. NOTE: The child workflow's
* lifecycle is bound to the parent workflow, and it will be terminated/scrubbed
* when the parent workflow is terminated/scrubbed.
*
* @template T The expected return type of the target function.
*/
execChild: <T>(options?: Partial<WorkflowOptions>) => Promise<T>;
/**
* Starts a new, subordinated workflow/job execution. NOTE: The child workflow's
* lifecycle is bound to the parent workflow, and it will be terminated/scrubbed
* when the parent workflow is terminated/scrubbed.
*
* @template T The expected return type of the target function.
*/
executeChild: <T_1>(options?: Partial<WorkflowOptions>) => Promise<T_1>;
/**
* Starts a new, subordinated workflow/job execution, awaiting only the jobId, namely,
* the confirmation that the suboridinated job has begun. NOTE: The child workflow's
* lifecycle is bound to the parent workflow, and it will be terminated/scrubbed
* when the parent workflow is terminated/scrubbed.
*/
startChild: (options?: Partial<WorkflowOptions>) => Promise<string>;
};
/**
* Instances a new `MeshData` service.
* @param {ProviderConfig|ProvidersConfig} connection - the connection class and options
* @param {WorkflowSearchOptions} search - the search options for JSON-based configuration of the backend search module (e.g., Redis FT.Search)
* @example
* // Example 1) Instantiate MeshData with `ioredis`
* import Redis from 'ioredis';
*
* const meshData = new MeshData({
* class: Redis,
* options: {
* host: 'localhost',
* port: 6379,
* password: 'shhh123',
* db: 0,
* }});
*
* // Example 2) Instantiate MeshData with `redis`
* import * as Redis from 'redis';
*
* const meshData = new MeshData({
* class: Redis,
* options: {
* url: 'redis://:shhh123@localhost:6379'
* }});
*
* // Instantiate MeshData with `postgres`
* //...
*/
constructor(connection: ProviderConfig | ProvidersConfig, search?: WorkflowSearchOptions);
/**
* @private
*/
validate(entity: string): void;
/**
* @private
*/
getConnection(): Promise<ProviderConfig | ProvidersConfig>;
/**
* Return a MeshFlow client
* @private
*/
getClient(): import("../..").Client;
/**
* @private
*/
safeKey(key: string): string;
/**
* @private
* todo: move to `utils` (might already be there);
* also might be better as specialized provider utils
*/
arrayToHash(input: [number, ...Array<string | string[]>]): StringStringType[];
/**
* serialize using the HotMesh `toString` format
* @private
*/
toString(value: unknown): string | undefined;
/**
* returns an entity-namespaced guid
* @param {string|null} entity - entity namespace
* @param {string} [id] - workflow id (allowed to be namespaced)
* @returns {string}
* @private
*/
static mintGuid(entity: string, id?: string): string;
/**
* Returns a HotMesh client
* @param {string} [namespace='meshflow'] - the namespace for the client
* @returns {Promise<HotMesh>}
*/
getHotMesh(namespace?: string): Promise<HotMesh>;
/**
* Returns the HASH key given an `entity` name and workflow/job. The
* item identified by this key is a HASH record with multidimensional process
* data interleaved with the function state data.
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} workflowId - the workflow/job id
* @param {string} [namespace='meshflow'] - the namespace for the client
* @returns {Promise<string>}
* @example
* // mint a key
* const key = await meshData.mintKey('greeting', 'jsmith123');
*
* // returns 'hmsh:meshflow:j:greeting-jsmith123'
*/
mintKey(entity: string, workflowId: string, namespace?: string): Promise<string>;
/**
* Exposes the the service mesh control plane through the
* mesh 'events' (pub/sub) system. This is useful for
* monitoring and managing the operational data layer.
*/
mesh: {
/**
* subscribes to the mesh control plane
* @param {QuorumMessageCallback} callback - the callback function
* @param {SubscriptionOptions} options - connection options
* @returns {Promise<void>}
*/
sub: (callback: QuorumMessageCallback, options?: SubscriptionOptions) => Promise<void>;
/**
* publishes a message to the mesh control plane
* @param {QuorumMessage} message - the message payload
* @param {SubscriptionOptions} options - connection options
* @returns {Promise<void>}
*/
pub: (message: QuorumMessage, options?: SubscriptionOptions) => Promise<void>;
/**
* unsubscribes from the mesh control plane
* @param {QuorumMessageCallback} callback - the callback function
* @param {SubscriptionOptions} options - connection options
* @returns {Promise<void>}
*/
unsub: (callback: QuorumMessageCallback, options?: SubscriptionOptions) => Promise<void>;
};
/**
* Connects a function to the operational data layer.
*
* @template T The expected return type of the target function.
*
* @param {object} connection - The options for connecting a function.
* @param {string} connection.entity - The global entity identifier for the function (e.g, 'user', 'order', 'product').
* @param {(...args: any[]) => T} connection.target - Function to connect, returns type T.
* @param {ConnectOptions} connection.options={} - Extended connection options (e.g., ttl, taskQueue). A
* ttl of 'infinity' will cache the function indefinitely.
*
* @returns {Promise<boolean>} True if connection is successfully established.
*
* @example
* // Instantiate MeshData with Redis configuration.
* const meshData = new MeshData({
* class: Redis,
* options: { host: 'localhost', port: 6379 }
* });
*
* // Define and connect a function with the 'greeting' entity.
* // The function will be cached indefinitely (infinite TTL).
* await meshData.connect({
* entity: 'greeting',
* target: (email, user) => `Hello, ${user.first}.`,
* options: { ttl: 'infinity' }
* });
*/
connect<T>({ entity, target, options, }: ConnectionInput<T>): Promise<boolean>;
/**
* During remote execution, an argument is injected (the last argument)
* this is then used by the 'connect' function to determine if the call
* is a hook or a exec call. If it is an exec, the connected function has
* precedence and can say that all calls are cached indefinitely.
*
* @param {any[]} args
* @param {StringAnyType} callOptions
* @returns {StringAnyType}
* @private
*/
bindCallOptions(args: any[], callOptions?: CallOptions): StringAnyType;
/**
* Sleeps/WaitsForSignal to keep the function open
* and remain part of the operational data layer
*
* @template T The expected return type of the remote function
*
* @param {string} result - the result to emit before going to sleep
* @param {CallOptions} options - call options
* @private
*/
pauseForTTL<T>(result: T, options: CallOptions): Promise<void>;
/**
* Publishes the job result, because pausing the job (in support of
* the 'ttl' option) interrupts the response.
*
* @template T The expected return type of the remote function
*
* @param {string} result - the result to emit before going to sleep
* @param {HotMesh} hotMesh - call options
* @param {CallOptions} options - call options
*
* @returns {Promise<void>}
* @private
*/
publishDone<T>(result: T, hotMesh: HotMesh, options: CallOptions): Promise<void>;
/**
* Flushes a function with a `ttl` of 'infinity'. These entities were
* created by a connect method that was configured with a
* `ttl` of 'infinity'. It can take several seconds for the function
* to be removed from the cache as it might be actively orchestrating
* sub-workflows.
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - The workflow/job id
* @param {string} [namespace='meshflow'] - the namespace for the client
*
* @example
* // Flush a function
* await meshData.flush('greeting', 'jsmith123');
*/
flush(entity: string, id: string, namespace?: string): Promise<string | void>;
/**
* Interrupts a job by its entity and id. It is best not to call this
* method directly for entries with a ttl of `infinity` (call `flush` instead).
* For those entities that are cached for a specified duration (e.g., '15 minutes'),
* this method will interrupt the job and start the cascaded cleanup/expire/delete.
* As jobs are asynchronous, there is no way to stop descendant flows immediately.
* Use an `expire` option to keep the interrupted job in the cache for a specified
* duration before it is fully removed.
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - The workflow/job id
* @param {JobInterruptOptions} [options={}] - call options
* @param {string} [namespace='meshflow'] - the namespace for the client
*
* @example
* // Interrupt a function
* await meshData.interrupt('greeting', 'jsmith123');
*/
interrupt(entity: string, id: string, options?: JobInterruptOptions, namespace?: string): Promise<void>;
/**
* Signals a Hook Function or Main Function to awaken that
* is paused and registered to awaken upon receiving the signal
* matching @guid.
*
* @param {string} guid - The global identifier for the signal
* @param {StringAnyType} payload - The payload to send with the signal
* @param {string} [namespace='meshflow'] - the namespace for the client
* @returns {Promise<string>} - the signal id
* @example
* // Signal a function with a payload
* await meshData.signal('signal123', { message: 'hi!' });
*
* // returns '123456732345-0' (stream message receipt)
*/
signal(guid: string, payload: StringAnyType, namespace?: string): Promise<string>;
/**
* Sends a signal to the backend Service Mesh (workers and engines)
* to announce their presence, including message counts, target
* functions, topics, etc. This is useful for establishing
* the network profile and overall message throughput
* of the operational data layer as a unified quorum.
* @param {RollCallOptions} options
* @returns {Promise<QuorumProfile[]>}
*/
rollCall(options?: RollCallOptions): Promise<QuorumProfile[]>;
/**
* Throttles a worker or engine in the backend Service Mesh, using either
* a 'guid' to target a specific worker or engine, or a 'topic' to target
* a group of worker(s) connected to that topic. The throttle value is
* specified in milliseconds and will cause the target(s) to delay consuming
* the next message by this amount. By default, the value is set to `0`.
* @param {ThrottleOptions} options
* @returns {Promise<boolean>}
*
* @example
* // Throttle a worker or engine
* await meshData.throttle({ guid: '1234567890', throttle: 10_000 });
*/
throttle(options: ThrottleOptions): Promise<boolean>;
/**
* Similar to `exec`, except it augments the workflow state without creating a new job.
*
* @param {object} input - The input parameters for hooking a function.
* @param {string} input.entity - The target entity name (e.g., 'user', 'order', 'product').
* @param {string} input.id - The target execution/workflow/job id.
* @param {string} input.hookEntity - The hook entity name (e.g, 'user.notification').
* @param {any[]} input.hookArgs - The arguments for the hook function; must be JSON serializable.
* @param {HookOptions} input.options={} - Extended hook options (taskQueue, namespace, etc).
* @returns {Promise<string>} The signal id.
*
* @example
* // Hook a function
* const signalId = await meshData.hook({
* entity: 'greeting',
* id: 'jsmith123',
* hookEntity: 'greeting.newsletter',
* hookArgs: ['xxxx@xxxxx'],
* options: {}
* });
*/
hook({ entity, id, hookEntity, hookArgs, options, }: HookInput): Promise<string>;
/**
* Executes a remote function by its global entity identifier with specified arguments.
* If options.ttl is infinity, the function will be cached indefinitely and can only be
* removed by calling `flush`. During this time, the function will remain active and
* its state can be augmented by calling `set`, `incr`, `del`, etc OR by calling a
* transactional 'hook' function.
*
* @template T The expected return type of the remote function.
*
* @param {object} input - The execution parameters.
* @param {string} input.entity - The function entity name (e.g., 'user', 'order', 'user.bill').
* @param {any[]} input.args - The arguments for the remote function.
* @param {CallOptions} input.options={} - Extended configuration options for execution (e.g, taskQueue).
*
* @returns {Promise<T>} A promise that resolves with the result of the remote function execution. If
* the input options include `await: false`, the promise will resolve with the
* workflow ID (string) instead of the result. Make sure to pass string as the
* return type if you are using `await: false`.
*
* @example
* // Invoke a remote function with arguments and options
* const response = await meshData.exec({
* entity: 'greeting',
* args: ['jsmith@hotmesh', { first: 'Jan' }],
* options: { ttl: '15 minutes', id: 'jsmith123' }
* });
*/
exec<T>({ entity, args, options }: ExecInput): Promise<T>;
/**
* Retrieves the job profile for the function execution, including metadata such as
* execution status and result.
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - identifier for the job
* @param {CallOptions} [options={}] - Configuration options for the execution,
* including custom IDs, time-to-live (TTL) settings, etc.
* Defaults to an empty object if not provided.
*
* @returns {Promise<JobOutput>} A promise that resolves with the job's output, which
* includes metadata about the job's execution status. The
* structure of `JobOutput` should contain all relevant
* information such as execution result, status, and any
* error messages if the job failed.
*
* @example
* // Retrieve information about a remote function's execution by job ID
* const jobInfoById = await meshData.info('greeting', 'job-12345');
*
* // Response: JobOutput
* {
* metadata: {
* tpc: 'meshflow.execute',
* app: 'meshflow',
* vrs: '1',
* jid: 'greeting-jsmith123',
* aid: 't1',
* ts: '0',
* jc: '20240208014803.980',
* ju: '20240208065017.762',
* js: 0
* },
* data: {
* done: true,
* response: 'Hello, Jan. Your email is [jsmith@hotmesh.com].',
* workflowId: 'greeting-jsmith123'
* }
* }
*/
info(entity: string, id: string, options?: CallOptions): Promise<JobOutput>;
/**
* Exports the job profile for the function execution, including
* all state, process, and timeline data. The information in the export
* is sufficient to capture the full state of the function in the moment
* and over time.
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - The workflow/job id
* @param {ExportOptions} [options={}] - Configuration options for the export
* @param {string} [namespace='meshflow'] - the namespace for the client
*
* @example
* // Export a function
* await meshData.export('greeting', 'jsmith123');
*/
export(entity: string, id: string, options?: ExportOptions, namespace?: string): Promise<MeshFlowJobExport>;
/**
* Returns the remote function state. this is different than the function response
* returned by the `exec` method which represents the return value from the
* function at the moment it completed. Instead, function state represents
* mutable shared state that can be set:
* 1) when the record is first created (provide `options.search.data` to `exec`)
* 2) during function execution ((await MeshData.workflow.search()).set(...))
* 3) during hook execution ((await MeshData.workflow.search()).set(...))
* 4) via the meshData SDK (`meshData.set(...)`)
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - the job id
* @param {CallOptions} [options={}] - call options
*
* @returns {Promise<StringAnyType>} - the function state
*
* @example
* // get the state of a function
* const state = await meshData.get('greeting', 'jsmith123', { fields: ['fred', 'barney'] });
*
* // returns { fred: 'flintstone', barney: 'rubble' }
*/
get(entity: string, id: string, options?: CallOptions): Promise<StringAnyType>;
/**
* Returns the remote function state for all fields. NOTE:
* `all` can be less efficient than calling `get` as it returns all
* fields (HGETALL), not just the ones requested (HMGET). Depending
* upon the duration of the workflow, this could represent a large
* amount of process/history data.
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - the workflow/job id
* @param {CallOptions} [options={}] - call options
*
* @returns {Promise<StringAnyType>} - the function state
*
* @example
* // get the state of the job (this is not the response...this is job state)
* const state = await meshData.all('greeting', 'jsmith123');
*
* // returns { fred: 'flintstone', barney: 'rubble', ... }
*/
all(entity: string, id: string, options?: CallOptions): Promise<StringAnyType>;
/**
* Returns all fields in the HASH record:
*
* 1) `:`: workflow status (a semaphore where `0` is complete)
* 2) `_*`: function state (name/value pairs are prefixed with `_`)
* 3) `-*`: workflow cycle state (cycles are prefixed with `-`)
* 4) `[a-zA-Z]{3}`: mutable workflow job state
* 5) `[a-zA-Z]{3}[,\d]+`: immutable workflow activity state
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - the workflow/job id
* @param {CallOptions} [options={}] - call options
*
* @returns {Promise<StringAnyType>} - the function state
*
* @example
* // get the state of a function
* const state = await meshData.raw('greeting', 'jsmith123');
*
* // returns { : '0', _barney: 'rubble', aBa: 'Hello, John Doe. Your email is [jsmith@hotmesh].', ... }
*/
raw(entity: string, id: string, options?: CallOptions): Promise<StringAnyType>;
/**
* Sets the remote function state. this is different than the function response
* returned by the exec method which represents the return value from the
* function at the moment it completed. Instead, function state represents
* mutable shared state that can be set
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - the job id
* @param {CallOptions} [options={}] - call options
*
* @returns {Promise<number>} - count. The number inserted (Postgres) / updated(Redis)
* @example
* // set the state of a function
* const count = await meshData.set('greeting', 'jsmith123', { search: { data: { fred: 'flintstone', barney: 'rubble' } } });
*/
set(entity: string, id: string, options?: CallOptions): Promise<number>;
/**
* Increments a field in the remote function state.
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - the job id
* @param {string} field - the field name
* @param {number} amount - the amount to increment
* @param {CallOptions} [options={}] - call options
*
* @returns {Promise<number>} - the new value
* @example
* // increment a field in the function state
* const count = await meshData.incr('greeting', 'jsmith123', 'counter', 1);
*/
incr(entity: string, id: string, field: string, amount: number, options?: CallOptions): Promise<number>;
/**
* Deletes one or more fields from the remote function state.
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {string} id - the job id
* @param {CallOptions} [options={}] - call options
*
* @returns {Promise<number>} - the count of fields deleted
* @example
* // remove two hash fields from the function state
* const count = await meshData.del('greeting', 'jsmith123', { fields: ['fred', 'barney'] });
*/
del(entity: string, id: string, options: CallOptions): Promise<number>;
/**
* For those implementations without a search backend, this quasi-equivalent
* method is provided with a cursor for rudimentary pagination.
* @param {FindJobsOptions} [options]
* @returns {Promise<[string, string[]]>}
* @example
* // find jobs
* const [cursor, jobs] = await meshData.findJobs({ match: 'greeting*' });
*
* // returns [ '0', [ 'hmsh:meshflow:j:greeting-jsmith123', 'hmsh:meshflow:j:greeting-jdoe456' ] ]
*/
findJobs(options?: FindJobsOptions): Promise<[string, string[]]>;
/**
* Executes the search query; optionally specify other commands
* @example '@_quantity:[89 89]'
* @example '@_quantity:[89 89] @_name:"John"'
* @example 'FT.search my-index @_quantity:[89 89]'
* @param {FindOptions} options
* @param {any[]} args
* @returns {Promise<string[] | [number] | Array<number, string | number | string[]>>}
*/
find(entity: string, options: FindOptions, ...args: string[]): Promise<string[] | [number] | Array<string | number | string[]>>;
/**
* Provides a JSON abstraction for the backend search engine
* (e.g, `count`, `query`, `return`, `limit`)
* NOTE: If the type is TAG for an entity, `.`, `@`, and `-` must be escaped.
*
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {FindWhereOptions} options - find options (the query). A custom search schema may be provided.
* @returns {Promise<SearchResults | number>} Returns a number if `count` is true, otherwise a SearchResults object.
* @example
* const results = await meshData.findWhere('greeting', {
* query: [
* { field: 'name', is: '=', value: 'John' },
* { field: 'age', is: '>', value: 2 },
* { field: 'quantity', is: '[]', value: [89, 89] }
* ],
* count: false,
* limit: { start: 0, size: 10 },
* return: ['name', 'quantity']
* });
*
* // returns { count: 1, query: 'FT.SEARCH my-index @_name:"John" @_age:[2 +inf] @_quantity:[89 89] LIMIT 0 10', data: [ { name: 'John', quantity: '89' } ] }
*/
findWhere(entity: string, options: FindWhereOptions): Promise<SearchResults | number>;
/**
* Generates a search query from a FindWhereQuery array
* @param {FindWhereQuery[] | string} [query]
* @param {WorkflowSearchOptions} [search]
* @returns {string}
* @private
*/
generateSearchQuery(query: FindWhereQuery[] | string, search?: WorkflowSearchOptions): string;
/**
* Creates a search index for the specified search backend (e.g., FT.search).
* @param {string} entity - the entity name (e.g, 'user', 'order', 'product')
* @param {CallOptions} [options={}] - call options
* @param {WorkflowSearchOptions} [searchOptions] - search options
* @returns {Promise<string>} - the search index name
* @example
* // create a search index for the 'greeting' entity. pass in search options.
* const index = await meshData.createSearchIndex('greeting', {}, { prefix: 'greeting', ... });
*
* // creates a search index for the 'greeting' entity, using the default search options.
* const index = await meshData.createSearchIndex('greeting');
*/
createSearchIndex(entity: string, options?: CallOptions, searchOptions?: WorkflowSearchOptions): Promise<void>;
/**
* Lists all search indexes in the operational data layer when the
* targeted search backend is configured/enabled.
* @returns {Promise<string[]>}
* @example
* // list all search indexes
* const indexes = await meshData.listSearchIndexes();
*
* // returns ['greeting', 'user', 'order', 'product']
*/
listSearchIndexes(): Promise<string[]>;
/**
* Wrap activities in a proxy that will durably run them, once.
*/
static proxyActivities: typeof import("../..").proxyActivities;
/**
* shut down MeshData (typically on sigint or sigterm)
*/
static shutdown(): Promise<void>;
}
export { MeshData };