/** * Bulk-subscription matchers — pure functions over `RawTx`. * * Per `docs/tx-tracker-spec.md` §11. Indexers want "all txs from * these senders" or "all txs touching this contract"; the tracker * supports `from` / `to` / `predicate` selectors. The matchers * themselves are pure (no I/O, no cached state) — `tracker.ts` * iterates the source's mempool snapshots and the canonical block's * `transactions` array per tick and asks each registered selector * whether each tx matches. * * `from` and `to` selectors normalize addresses to lowercase ASCII * before comparison because upstream RPCs are inconsistent about * checksum vs lowercase. Mempool snapshots are already lowercased * by `chain-source`'s `normalizeMempool`, but the same matcher is * called against block-tx records (where the upstream may emit * checksum form), so the selector normalizes its own * pre-stored target once and compares lowercase-vs-lowercase. * * Predicate selectors are caller-defined. The tracker calls them * O(N) per tick per matched-tx; spec §11.3 documents that slow * predicates degrade the tick. */ import type { RawTx } from '@valve-tech/chain-source'; import type { Hash } from './events.js'; import type { BulkSelector } from './store.js'; /** * One match the bulk subscription is about to emit. The tracker * builds the surrounding `TxMatchEvent` envelope (`source`, * `at`, etc.) before pushing to the consumer; this shape is just * the matcher's payload. */ export interface BulkMatchPayload { hash: Hash; matchedBy: 'from' | 'to' | 'predicate'; selector: BulkSelector; tx: RawTx; } /** * One compiled selector — `selector` is the original consumer-facing * shape, `match` is the cached pure function the tracker calls per * tx. The tracker compiles each registered selector once at * registration time so the per-tick fanout pays only the function * call, not a dispatch on `selector.kind`. */ export interface CompiledSelector { selector: BulkSelector; match: (tx: RawTx) => boolean; } /** * Compile a `BulkSelector` into its pure matcher. `from` / `to` * cache the lowercased address once; `predicate` returns the * caller's function as-is. * * Throws on a malformed selector (`from` / `to` without an address, * `predicate` without a function) — caught at registration time * rather than at the per-tick callsite, where the failure mode would * be silent zero matches. */ export declare const compileSelector: (selector: BulkSelector) => CompiledSelector; /** * Iterate `txs` against every compiled selector and yield one * `BulkMatchPayload` per (tx, selector) match. Used by the tracker's * per-tick fan-out over both `block.transactions` (after a new tip * lands) and the source's mempool snapshot deltas. * * The tracker, not this helper, decides whether to auto-track each * matched hash — `BulkTrackOptions.autoTrackMatched` (default true) * lives in `tracker.ts`. */ export declare const matchAll: (txs: ReadonlyArray, compiled: ReadonlyArray) => BulkMatchPayload[]; /** * Default per-tracker bulk-subscription cap (§11.3). Higher fan-out * is technically allowed but indicates the consumer should be * running an indexer-shaped store rather than the in-memory default. */ export declare const defaultMaxBulkSubscriptions = 16; /** * Reverse-lookup: find the bulk subscription whose compiled selector * is the same reference as `selector`. Returns `null` on miss. * * Pure / data-flow only — exported here so the tracker's * runBulkOn{Block,Mempool} paths can resolve match→bulk without * exposing the bulk registry, and so the defensive null-on-miss * branch is unit-testable (audit #7 hardening). The current public * API can't reach a miss in fanout (matchSubs has no sync subscribers, * so a sub can't be deleted between the `compiled` snapshot and the * lookup), but future internal changes that add synchronous matchSubs * subscribers, or any other path that mutates the registry mid-fanout, * would otherwise crash the entire emit loop. */ export declare const findBulkSubBySelector: (bulkSubs: ReadonlyMap, selector: BulkSelector) => T | null; //# sourceMappingURL=selectors.d.ts.map