UNPKG

thorish

Version:

This is a library of useful JS concepts and data structures for Node and the browser. It it, unashamedly, a dumping ground for code needed by [@samthor](https://twitter.com/samthor)'s projects.

93 lines (92 loc) 3.59 kB
import { ConditionListener, ConditionOptions } from './cond.js'; import { DeepObjectPartial } from './object-utils.js'; import type { AbortSignalArgs } from './types.js'; export { matchAny } from './object-utils.js'; /** * Used to express a filter for {@link Matcher}. */ export type Filter<T> = DeepObjectPartial<T>; /** * This can be added to a {@link Matcher} to recieve updates based on a filter. */ export interface MatcherSub<K> { add(k: K): any; delete(k: K): any; } /** * Matcher that allows us to observe groups of keyed objects as they transition through state. * * These objects must be cloneable via {@link structuredClone}. * * An `undefined` state is equivalent to blank/deleted: it does not exist. */ export declare class Matcher<K, T> { private objects; private groups; get(id: K): T | undefined; /** * Sets this value into the {@link Matcher}. This will trigger group state changes. */ set(id: K, value: T | undefined): void; delete(id: K): boolean; /** * Does any object match this filter? */ matchAny(filter: Filter<T>): boolean; /** * Matches objects immediately, without grouping. */ matchAll(filter: Filter<T>): Generator<K, void, void>; /** * Returns the intersection of reading the given keys. */ read(keys: Iterable<K>): DeepObjectPartial<T> | undefined; /** * Attaches a subscripton to this {@link Matcher} based on the given {@link Filter}. The filter * will be frozen before use, so you cannot change it later. * * This will add all initially matching objects to the {@link MatcherSub}. However, the current * matching set will not be cleared when the passed signal is aborted. */ sub(filter: Filter<T>, g: MatcherSub<K>, options?: AbortSignalArgs): void; } export interface Group { active(): boolean; addListener(fn: (state: boolean) => any, options?: ConditionOptions): boolean; removeListener(fn: (state: boolean) => any): boolean; } /** * Provides a wrapper for a number of {@link Group} instances. By default, this is active when * all of the passed groups (including zero) are active, an AND filter. */ export declare class CombineGroup implements Group { private groups; private cond; private isActive; static create(groups: Group[], isActive?: (groups: Group[]) => boolean): CombineGroup; constructor(groups: Group[], isActive?: (groups: Group[]) => boolean); active(): boolean; addListener(fn: ConditionListener<boolean>, options?: ConditionOptions): boolean; removeListener(fn: ConditionListener<boolean>): boolean; } /** * Provides a wrapper to manage a {@link Filter} over a {@link Matcher}, both with matched keys * as well as a derived "active" state. * * By default, the group is active if any item matches the filter, however subclasses can change * this behavior by overriding {@link MatcherGroupprivate isActive}. */ export declare class MatcherGroup<K, T> implements Group { private filter; private matcher; private signal; private matchingSet; private cond; static create<K, T>(filter: Filter<T>, matcher: Matcher<K, T>, options?: AbortSignalArgs): MatcherGroup<K, T>; constructor(filter: Filter<T>, matcher: Matcher<K, T>, options?: AbortSignalArgs); protected isActive(matchingKeys: ReadonlySet<K>): boolean; active(): boolean; matching(): Iterable<K>; addListener(fn: ConditionListener<boolean>, options?: AbortSignalArgs): boolean; removeListener(fn: ConditionListener<boolean>): boolean; }