import type { AnyUpdate } from './custom-update.js';
/**
* static metadata attached to every `Filter` — lets the dispatcher short-circuit
* predicate eval and gives debug printers a readable name
*/
export interface FilterMeta {
/** human-readable name, used by debug/inspect output and runtime conflict checks */
readonly name: string;
/**
* kind hint — dispatcher skips this filter for updates whose `kind` isn't
* listed. `undefined` = evaluate against any update
*/
readonly kinds?: readonly string[];
}
/**
* the public filter shape — a callable type-guard plus metadata, a structural
* `Mod` refinement marker, and fluent composition methods
*
* `Base` and `Mod` are independent: kind/structural filters narrow `Base`,
* presence and value filters narrow `Mod`. `tg.on(filter, handler)` sees the
* arg typed as `Base & Mod`; raw `if (filter(u))` checks narrow only `Base`
*
* @example
* ```ts
* tg.on(kind.message.and(hasText), (m) => {
* // m: MessageUpdate & { text: string } — `text` is no longer `string | undefined`
* m.text.toLowerCase()
* })
* ```
*/
export interface Filter extends FilterMeta {
(update: AnyUpdate): update is AnyUpdate & Base;
/** intersect — match when both match; intersects `Base` and `Mod` */
and: (other: Filter) => Filter;
/** union — match when either matches; unions `Base` and `Mod` */
or: (other: Filter) => Filter;
/** negate — drops both narrowings */
not: () => Filter;
}
/**
* async variant — predicate returns `Promise` instead of a sync
* type-guarded boolean. composes with sync filters; result is async if any operand is
*/
export interface AsyncFilter extends FilterMeta {
(update: AnyUpdate): Promise;
and: (other: Filter | AsyncFilter) => AsyncFilter;
or: (other: Filter | AsyncFilter) => AsyncFilter;
not: () => AsyncFilter;
}
/** structural type for the composition method set, exposed for filter shim authors */
export type FilterMethods = Pick, 'and' | 'or' | 'not'>;
/** extract the `Base` narrowing from a filter type — used by `tg.on(filter, handler)` to type the handler arg */
export type ExtractBase = F extends Filter ? B : F extends AsyncFilter ? B : never;
/** extract the structural `Mod` refinement from a filter type */
export type ExtractMod = F extends Filter ? M : F extends AsyncFilter ? M : never;
/** combine `Base` and `Mod` into the type a handler sees for the matched update */
export type FilterMatch = ExtractBase & ExtractMod;
/**
* structural runtime check — any callable with `and`/`or`/`not` function props
* counts as a filter, so userland shims work without going through `defineFilter`
*/
export declare function isFilter(value: unknown): value is Filter;
interface DefineMeta {
kinds?: readonly string[];
}
/**
* build a `Filter` from a sync predicate. predicate may be a plain
* `boolean` returner or a type-guard `(u): u is Base` — type-guards make raw
* `if (filter(u))` narrow `u` to `Base`; `tg.on(filter, h)` always sees `Base & Mod`
*/
export declare function defineFilter(name: string, predicate: (update: AnyUpdate) => boolean, meta?: DefineMeta): Filter;
/**
* async variant of `defineFilter` — predicate returns `Promise` and
* doesn't narrow at the call site (TS has no async type-guard)
*/
export declare function defineAsyncFilter(name: string, predicate: (update: AnyUpdate) => Promise, meta?: DefineMeta): AsyncFilter;
type AnyFilter = Filter | AsyncFilter;
/** intersection — short-circuits on the first false operand. intersects `Base` and `Mod` */
export declare function and(a: Filter): Filter;
export declare function and(a: Filter, b: Filter): Filter;
export declare function and(a: Filter, b: Filter, c: Filter): Filter;
export declare function and(a: Filter, b: Filter, c: Filter, d: Filter): Filter;
export declare function and(...filters: readonly AnyFilter[]): Filter;
/** union — short-circuits on the first true operand. unions `Base` and `Mod` */
export declare function or(a: Filter): Filter;
export declare function or(a: Filter, b: Filter): Filter;
export declare function or(a: Filter, b: Filter, c: Filter): Filter;
export declare function or(a: Filter, b: Filter, c: Filter, d: Filter): Filter;
export declare function or(...filters: readonly AnyFilter[]): Filter;
/** negation — match when the operand does not match. drops both `Base` and `Mod` narrowing */
export declare function not(filter: AnyFilter): Filter;
/** alias for `and` — reads more naturally for "every operand must match" intents */
export declare const every: typeof and;
/** alias for `or` — reads more naturally for "any operand may match" intents */
export declare const some: typeof or;
export {};
//# sourceMappingURL=filter-runtime.d.ts.map