import * as _atcute_identity_resolver from '@atcute/identity-resolver'; import { AtprotoAudience } from '@atcute/lexicons/syntax'; /** A labeler the operator wants contrail to track. */ interface LabelerSource { /** Labeler DID — `did:plc:...` or `did:web:...`. */ did: string; /** Override the service endpoint resolution. Otherwise resolved from the * DID doc's `service[id="#atproto_labeler"].serviceEndpoint`. */ endpoint?: string; /** Backfill from `cursor=0` on first sight. Defaults to true. Set false * for "start from now" — useful for very chatty labelers. */ backfill?: boolean; } interface LabelsConfig { /** Labelers to subscribe to and index. */ sources: LabelerSource[]; /** DIDs honored when the caller sends no `atproto-accept-labelers` / * `?labelers=`. Defaults to every entry in `sources`. Set `[]` for * opt-in-only — clients see no labels unless they ask. */ defaults?: string[]; /** Per-request cap. Default: 20 (matches Bluesky). */ maxPerRequest?: number; } declare const DEFAULT_LABELS_MAX_PER_REQUEST = 20; /** A single label as stored. Matches `com.atproto.label.defs#label`. */ interface LabelRow { /** Issuing labeler DID. */ src: string; /** Subject — at-URI for record labels, plain DID for account labels. */ uri: string; /** Label value — kebab-case, ≤128 bytes per spec. */ val: string; /** Optional CID pin to a specific record version. */ cid: string | null; /** When true, retracts a previously-emitted label for the same (src, uri, val). */ neg: boolean; /** Expiry, unix seconds. Past this, hydration drops the row. */ exp: number | null; /** Creation timestamp, unix seconds — what we collapse on. */ cts: number; /** Raw signature bytes. Stored when present so we can re-emit later; * not verified in v1. */ sig: Uint8Array | null; } /** Per-labeler state row — endpoint cache and last-seen seq cursor. */ interface LabelerCursorRow { did: string; cursor: number; endpoint: string | null; resolved_at: number | null; } /** Get the dialect from a Database, defaulting to SQLite (for D1 compatibility) */ declare function getDialect(db: { dialect?: SqlDialect; }): SqlDialect; /** Build the SQLite expression used by both incremental and set-based FTS * projection. Only JSON string values participate, matching buildFtsContent(). */ declare function sqliteFtsContentExpression(fields: string[], recordColumn?: string): string; interface SqlDialect { /** json_extract(col, '$.field') or col->>'field' */ jsonExtract(column: string, field: string): string; /** Convert INSERT INTO to ignore-duplicates form. * SQLite: INSERT INTO → INSERT OR IGNORE INTO * PG: appends ON CONFLICT DO NOTHING * Accepts full SQL starting with "INSERT INTO" (works with both VALUES and SELECT). */ insertOrIgnore(sql: string): string; /** Column type for the record column: TEXT (SQLite) or JSONB (PostgreSQL) */ readonly recordColumnType: string; /** FTS strategy: 'virtual-table' (SQLite FTS5) or 'generated-column' (PG tsvector) */ readonly ftsStrategy: "virtual-table" | "generated-column"; /** INTEGER type name — same on both, but PostgreSQL may want BIGINT for time_us */ readonly integerType: string; /** BIGINT type name for timestamps */ readonly bigintType: string; /** Wrap an expression for use in CREATE INDEX — PostgreSQL requires parens around expressions */ indexExpression(expr: string): string; } declare const sqliteDialect: SqlDialect; declare const postgresDialect: SqlDialect; /** Generate FTS schema statements based on dialect */ declare function buildFtsSchema(dialect: SqlDialect, recordsTable: string, fields: string[]): string[]; /** Generate FTS query clause based on dialect */ declare function ftsQueryClause(dialect: SqlDialect, recordsTable: string): { join: string; condition: string; orderExpr: string; orderDirection: "asc" | "desc"; }; interface Database { prepare(sql: string): Statement; batch(stmts: Statement[]): Promise; dialect?: SqlDialect; } interface Statement { bind(...values: any[]): Statement; run(): Promise; all(): Promise<{ results: T[]; }>; first(): Promise; } interface QueryableField { type?: "range"; } interface RelationConfig { /** Short name of the child collection (a key in `collections`). */ collection: string; field?: string; match?: "uri" | "did"; groupBy?: string; /** Enable materialized count columns on the parent. Defaults to true. */ count?: boolean; /** Count distinct values of a field (e.g. "did" for unique users) instead of total records. */ countDistinct?: string; /** Pre-resolved group mappings: shortName → full token (e.g. { going: "community.lexicon.calendar.rsvp#going" }). Auto-computed from groupBy if omitted. */ groups?: Record; } /** A forward reference: this collection's records point at another collection. */ interface ReferenceConfig { /** Short name of the target collection. */ collection: string; /** Field on this collection's records containing the target URI. */ field: string; } type CustomQueryHandler = (db: Database, params: URLSearchParams, config: ContrailConfig) => Promise; interface RecordSource { joins?: string; conditions?: string[]; params?: (string | number)[]; } type PipelineQueryHandler = (db: Database, params: URLSearchParams, config: ContrailConfig) => Promise; interface FeedTargetConfig { /** Short name of the target collection. */ collection: string; /** Per-target item cap. Falls back to FeedConfig.maxItems if unset. */ maxItems?: number; } interface FeedConfig { /** Short name of the follow collection. Defaults to "follow" * (auto-added with NSID `app.bsky.graph.follow`, `discover: false`). */ follow?: string; /** Target collections to fan out to. Each entry is either a short name * or `{ collection, maxItems? }` for per-target caps. */ targets: (string | FeedTargetConfig)[]; /** Default per-target item cap when a target doesn't specify its own * (default: 200). Oldest items per (actor, collection) are pruned. */ maxItems?: number; } declare const DEFAULT_FEED_MAX_ITEMS = 200; declare const DEFAULT_FOLLOW_NSID = "app.bsky.graph.follow"; declare const DEFAULT_FOLLOW_SHORT = "follow"; /** Normalize a feed target entry to FeedTargetConfig. */ declare function normalizeFeedTarget(t: string | FeedTargetConfig): FeedTargetConfig; /** Resolve a feed's per-target item cap, falling back to FeedConfig.maxItems then global default. */ declare function feedTargetMaxItems(feed: FeedConfig, target: FeedTargetConfig): number; /** Build a Map across all configured feeds, taking the * largest cap if the same target collection appears in multiple feeds. */ declare function buildFeedTargetCaps(config: ContrailConfig): Map; type CollectionMethod = "listRecords" | "getRecord"; declare const DEFAULT_COLLECTION_METHODS: CollectionMethod[]; interface CollectionConfig { /** Full NSID of the record type this collection indexes. May be omitted when * the collection's map key is itself the full NSID (an "NSID-keyed" config); * `resolveConfig` normalizes the omitted value to that key. */ collection?: string; /** Include this collection in Jetstream ingest / discovery (default true). * Set false for dependent collections (auto-fetched on demand). */ discover?: boolean; /** Validate creates/updates against this collection's pinned record Lexicon. * The runtime bundle is supplied by `createWorker({ lexicons })`, * `contrail dev`, or `new Contrail({ lexicons })`. Default: false unless * legacy top-level `validation` enables all collections. */ validate?: boolean; queryable?: Record; relations?: Record; /** Forward references: fields on this collection's records that point at another collection. */ references?: Record; queries?: Record; pipelineQueries?: Record; /** FTS5 search fields. Provide an array of field names to enable full-text search. Omit or set to false to disable. */ searchable?: string[] | false; /** XRPC methods to emit. Defaults to ['listRecords', 'getRecord']. */ methods?: CollectionMethod[]; /** JSON field used as record/application time across live ingest, backfill, * notify, and enrichment (clamped to source observation time). Default * `"createdAt"`. Set to `false` to use source observation time. */ timeField?: string | false; /** JSON field on the record holding a DID that this record points at * (e.g. `"subject"` for follows). When set on a `discover: false` * collection, ingest also drops records whose subject DID is not in * knownDids — useful for trimming network-wide social graphs to the * subjects we care about. */ subjectField?: string; /** Per-record predicate run during ingest. Returning false drops the * record before it hits the buffer / DB. Runs only for create/update; * deletes always pass through (the delete may target a record that *did* * pass an earlier version of the filter). Thrown errors are caught, * logged, and treated as "drop". Note: Jetstream filters only by * `wantedCollections`, so non-matching records still travel over the wire * — this trims what gets persisted, not bandwidth. */ recordFilter?: (record: Record) => boolean; } interface ProfileConfig { /** Full NSID of the profile record type. */ collection: string; /** Short name used for table/endpoint naming. Defaults to the NSID's last segment. */ shortName?: string; rkey?: string; } declare const DEFAULT_PROFILES: ProfileConfig[]; /** Normalize a profiles config entry (string or object) into ProfileConfig. */ declare function normalizeProfileConfig(p: string | ProfileConfig): ProfileConfig; /** Last NSID segment, used as fallback short name. */ declare function deriveShortName(nsid: string): string; declare const DEFAULT_JETSTREAMS: string[]; /** Canonical source identity used for both the v2 client and its durable * service binding. The official client addresses XRPC at the origin, so path, * query, credentials, and fragments are rejected instead of being discarded * ambiguously. WebSocket and HTTP spellings of the same origin are equivalent. */ declare function normalizeJetstreamService(service: string): string; /** Return the one pinned Jetstream v2 service used by live ingestion. * Sequence cursors are instance-local and cannot fail over between services. */ declare function jetstreamService(jetstreams: string[]): string; /** * Shape a configured jetstream list for the legacy `@atcute/jetstream` adapter * still used by v1 archive/bootstrap integrations. * * @atcute distinguishes a string url (one fixed instance) from an array url (a * pool it picks from at random each connect). For an array it seeds * `#lastUsedUrl=''` and rolls the cursor back 10s on the first connect, to absorb * clock skew between whichever pooled instances a resumed cursor may have * crossed. A string takes no rollback: a single instance emits a monotonic * cursor, so resuming at the saved value on that same instance can't skip its own * events — there is no second instance to be skewed against. * * Contrail's cron ingestion rebuilds the subscription every cycle, so for a * single-instance config that "first-connect" rollback fires *every* cycle and * redundantly re-ingests the last 10s. Collapsing a one-element pool to a string * matches @atcute's own single-instance semantics and drops that dead margin; a * real pool (2+) stays an array so the cross-instance rollback is preserved. */ declare function jetstreamUrlOption(jetstreams: string[]): string | string[]; declare const DEFAULT_RELAYS: string[]; interface Logger { log(...args: any[]): void; warn(...args: any[]): void; error(...args: any[]): void; } interface IngestValidationConfig { /** Recompute authoritative record CIDs from canonical DAG-CBOR (default true). */ verifyCid?: boolean; /** Enforce strict blob size/MIME constraints as well as normal Lexicon rules (default true). */ strict?: boolean; /** Sources allowed to emit CID-less creates/updates. Defaults to local/synthetic sources only. */ allowCidlessSources?: string[]; } interface OrderedSourceConfig { /** Stable logical identifier of the primary ordered change source. */ source: string; /** Operator-owned continuity epoch. Change it whenever cursor continuity changes. */ epoch: string; } /** How an accepted mutation entered the logical projection. */ type ProjectionPhase = "historical" | "live"; type ChangeConsumerInitialMode = "current" | "future" | "history"; /** Static, secret-free definition for one durable change-log consumer. */ interface ChangeConsumerConfig { /** Exact configured collection NSIDs. Short aliases are deliberately rejected. */ collections: string[]; /** Projection phases to observe. Defaults to both; `initial: "current"` requires both. */ phases?: ProjectionPhase[]; /** How the consumer establishes its first durable position. */ initial: ChangeConsumerInitialMode; /** Whether deployment generation activation may require this consumer. */ requiredForActivation?: boolean; } interface ChangeLogConfig { /** Stable consumer IDs mapped to their static delivery policy. */ consumers: Record; } type AtprotoServiceAuthMethod = "getFeed" | "notifyOfUpdate"; interface AtprotoServiceAuthConfig { /** Exact fragmented service reference used as the OAuth and JWT audience. */ audience: AtprotoAudience; /** Built-in methods that require a method-bound AT Protocol service token. */ methods: AtprotoServiceAuthMethod[]; /** Maximum accepted token lifetime and age. Default: 300 seconds. */ maxTokenAgeSeconds?: number; /** Optional DID resolver for private networks or controlled resolution. */ resolver?: _atcute_identity_resolver.DidDocumentResolver; } interface ContrailConfig { namespace: string; /** Collections to index, keyed by short name. Short names become endpoint URL segments * (`..listRecords`) and table suffixes (`records_`). */ collections: Record; /** Optional shared runtime Lexicon and CID validation. When configured, * every create/update from every source passes through it before projection. */ validation?: IngestValidationConfig; profiles?: (string | ProfileConfig)[]; relays?: string[]; /** Jetstream v2 service used for live ingestion (defaults to * {@link DEFAULT_JETSTREAMS}). Exactly one service is required: v2 sequence * cursors are instance-local and cannot fail over between servers. The array * shape is retained for configuration compatibility and will be simplified in * a later API cleanup. */ jetstreams?: string[]; /** Identity of the ordered source consumed by live ingestion. Its opaque * cursor is persisted atomically with projected mutations and may be exposed * to clients as a cache invalidation coordinate. */ orderedSource?: OrderedSourceConfig; /** Optional transactional projection change log. Runtime handlers and * destination credentials are bound separately and never belong here. */ changes?: ChangeLogConfig; feeds?: Record; logger?: Logger; /** Expose the notifyOfUpdate HTTP endpoint. Off by default. * Set to `true` for open access, or a string to require `Authorization: Bearer `. * Prefer `serviceAuth.methods: ["notifyOfUpdate"]` for portable user auth. */ notify?: boolean | string; /** Verify method-bound AT Protocol service JWTs for selected built-in routes. */ serviceAuth?: AtprotoServiceAuthConfig; /** Labels module configuration. When set, contrail subscribes to the * configured labelers, indexes their labels into a single `labels` table, * and hydrates `record.labels` onto `listRecords` / `getRecord` / profile * responses gated by the caller's `atproto-accept-labelers` header. */ labels?: LabelsConfig; /** Constellation-backed reverse-follower lookup (default: enabled). * When a DID is first seen producing a discoverable record, contrail * queries Constellation for follow records pointing at that DID and * ingests synthesized rows for any follower already in our identities * table. Lets newcomers immediately appear in existing users' feeds. */ constellation?: ConstellationConfig | false; /** Network overrides for private-network or test deployments. * All subfields default to current public-internet behavior; * omitting `networkOverrides` entirely preserves current behavior. * * SECURITY: `resolver` and `slingshotUrl` are taken at face value and are * NOT validated against the SSRF guard — the consumer is trusted to * configure them. Only the PDS URL returned downstream is validated, * and only `additionalAllowedHosts` widens that PDS validator. There is * no "disable SSRF" flag. */ networkOverrides?: { /** DID document resolver used during the DID-doc PDS fallback. When * unset, contrail constructs a default `CompositeDidDocumentResolver` * with PLC + Web methods pointing at the upstream PLC directory. * Pass a custom resolver to point at a private PLC mirror, inject a * custom fetch (mTLS, retry, instrumentation), or swap in an * alternative DID method composition. */ resolver?: _atcute_identity_resolver.DidDocumentResolver; /** Slingshot identity resolver URL override. Trusted; not SSRF-checked. * Default: https://slingshot.microcosm.blue/xrpc/com.bad-example.identity.resolveMiniDoc */ slingshotUrl?: string; /** Hostnames (DNS names or IP literals) to allow past the default SSRF * guard when validating a resolved PDS URL. * For listed hostnames, the non-HTTPS + private-CIDR checks are skipped. * For all other hostnames, the default validator runs unchanged. * Match semantics: exact hostname, case-insensitive (entries are * lowercased on comparison; `URL.hostname` is already lowercased), * port-agnostic. * Example: ["pds.dev.svc.cluster.local"]. */ additionalAllowedHosts?: string[]; }; /** Optional background database maintenance. All off by default. */ maintenance?: MaintenanceConfig; } interface MaintenanceConfig { /** Periodically refresh the SQLite query planner's statistics so * multi-predicate queries pick the selective index instead of the planner's * default heuristic (measured ~50x fewer rows read on a 2-predicate query). * Off by default — it's a DB write + CPU and shouldn't change behavior for * existing consumers unless enabled. `true` uses defaults; pass an object to * tune. No-op on Postgres, where autovacuum/autoanalyze handles this. */ optimize?: boolean | MaintenanceOptimizeConfig; } interface MaintenanceOptimizeConfig { /** Minimum gap between optimize runs (default: 24h). Planner stats change * slowly, so daily is plenty. */ intervalMs?: number; /** `PRAGMA analysis_limit` — bounds the work per run so it can't exceed * D1's per-query CPU budget and reset the shared DO (default: 400). */ analysisLimit?: number; } declare const DEFAULT_OPTIMIZE_INTERVAL_MS: number; declare const DEFAULT_ANALYSIS_LIMIT = 400; /** Whether the opt-in planner-stat maintenance is enabled. */ declare function optimizeEnabled(config: ContrailConfig): boolean; /** Resolved optimize interval (ms), falling back to the 24h default. */ declare function optimizeIntervalMs(config: ContrailConfig): number; /** Resolved `analysis_limit` for optimize, falling back to the default. */ declare function optimizeAnalysisLimit(config: ContrailConfig): number; interface ConstellationConfig { /** Override the default Constellation instance URL. */ url?: string; /** Sent as the User-Agent header per Constellation's request that * callers identify themselves. Defaults to `contrail/`. */ userAgent?: string; /** Set false to disable lookups while keeping the table around. */ enabled?: boolean; } declare const DEFAULT_CONSTELLATION_URL = "https://constellation.microcosm.blue"; interface ResolvedRelation { /** Short name of the child collection. */ collection: string; groupBy: string; groups: Record; } interface ResolvedMaps { queryable: Record>; relations: Record>; /** Reverse map: full record NSID → short name. */ nsidToShort: Record; } /** Config after resolveConfig() — has computed queryable/relation maps attached. */ interface ResolvedContrailConfig extends ContrailConfig { _resolved: ResolvedMaps; } /** * Resolve config: apply defaults, auto-add profile collections, compute queryable maps. */ declare function resolveConfig(config: ContrailConfig): ResolvedContrailConfig; declare function getFeedFollowShortNames(config: ContrailConfig): string[]; /** Alias for getFeedFollowShortNames. */ declare const getFeedFollowCollections: typeof getFeedFollowShortNames; /** * NSIDs whose ingest can mutate `feed_items`: feed *target* collections (a * create/update fans out to followers, a delete tears the item down) and feed * *follow* collections (a follow backfills the follower's feed, an unfollow * removes it). These are the only records that can push a feed over its cap, so * a tick that ingested none of them cannot have created prune work — callers use * this to skip the feed sweep on idle ticks. Returns an empty set when no feeds * are configured. */ declare function getFeedMutatingNsids(config: ContrailConfig): Set; interface RecordRow { uri: string; did: string; collection: string; rkey: string; cid: string | null; record: string | null; time_us: number; indexed_at: number; } interface MutationSource { /** Stable logical source identifier, for example `jetstream` or `pds-backfill`. */ id: string; /** Continuity epoch for opaque cursors. Missing on legacy adapters. */ epoch?: string | null; /** Source observation/event time, independent of record application time. */ time_us: number; /** Monotonic repository revision when the source provides one. */ revision: string | null; /** Source checkpoint or event position when the source provides one. */ cursor: string | null; } interface IngestEvent { uri: string; did: string; collection: string; rkey: string; operation: "create" | "update" | "delete"; cid: string | null; record: string | null; /** Record/application time used by queries and feeds. */ time_us: number; /** Local projection time. */ indexed_at: number; /** * Authoritative source ordering metadata. Optional only for compatibility * with callers that constructed IngestEvent objects before 0.13.1; source * adapters and createIngestEvent always populate it. */ source?: MutationSource; } declare function validateFieldName(field: string): string; /** Whether this configuration requires the optional transactional change log. */ declare function changesEnabled(config: ContrailConfig): boolean; /** Canonical phases for a consumer definition. */ declare function changeConsumerPhases(consumer: ChangeConsumerConfig): ProjectionPhase[]; /** Canonical collection/phase pairs whose changes must be retained. */ declare function changeLogCoverage(config: ContrailConfig): Array<{ collection: string; phase: ProjectionPhase; }>; /** Stable secret-free representation used by schema/config compatibility checks. */ declare function canonicalChangeDefinitions(config: ContrailConfig): string; declare function validateConfig(config: ContrailConfig): void; declare function getNestedValue(obj: any, path: string): any; declare function getRelationField(rel: RelationConfig): string; /** Total-count column name for a relation targeting the given short name. */ declare function countColumnName(childShortName: string): string; /** Grouped-count column name: `count__`. */ declare function groupedCountColumnName(childShortName: string, groupKey: string): string; /** Table name for a collection's records. */ declare function recordsTableName(shortName: string): string; /** All collection short names. */ declare function getCollectionShortNames(config: ContrailConfig): string[]; /** Alias: collection short names (same as getCollectionShortNames). */ declare const getCollectionNames: typeof getCollectionShortNames; /** All indexed record NSIDs (what Jetstream filters on). For NSID-keyed * collections (omitted `collection`), the map key is the NSID. */ declare function getCollectionNsids(config: ContrailConfig): string[]; declare function getDependentShortNames(config: ContrailConfig): string[]; declare function getDiscoverableShortNames(config: ContrailConfig): string[]; /** Aliases for readability elsewhere. These return short names (new semantic). */ declare const getDependentCollections: typeof getDependentShortNames; declare const getDiscoverableCollections: typeof getDiscoverableShortNames; /** Short names of collections the user declared with `discover !== false`, mapped to NSIDs. */ declare function getDiscoverableNsids(config: ContrailConfig): string[]; declare function getDependentNsids(config: ContrailConfig): string[]; /** Short name for a record NSID, if known. */ declare function shortNameForNsid(config: ContrailConfig, nsid: string): string | undefined; /** The config key a collection's rows are stored under: its short alias when * one exists, otherwise the NSID itself when the config is keyed directly by * NSID. Returns null when the collection is unknown. Use this wherever you need * the storage key (records insert, FTS, existing-record lookup). Unlike * {@link shortNameForNsid}, which only reports an alias and so returns * undefined for NSID-keyed configs. */ declare function resolveCollectionKey(config: ContrailConfig, nsid: string): string | null; /** Full NSID for a collection short name. For NSID-keyed collections (omitted * `collection`), the short name is itself the NSID. */ declare function nsidForShortName(config: ContrailConfig, short: string): string | undefined; /** The methods a collection should expose via XRPC. */ declare function getCollectionMethods(cfg: CollectionConfig): CollectionMethod[]; export { changesEnabled as $, type AtprotoServiceAuthMethod as A, type IngestValidationConfig as B, type ContrailConfig as C, type Database as D, type LabelRow as E, type FeedConfig as F, type LabelerCursorRow as G, type LabelerSource as H, type IngestEvent as I, type MaintenanceConfig as J, type MaintenanceOptimizeConfig as K, type Logger as L, type MutationSource as M, type PipelineQueryHandler as N, type OrderedSourceConfig as O, type ProjectionPhase as P, type ProfileConfig as Q, type RecordSource as R, type Statement as S, type QueryableField as T, type ResolvedMaps as U, type ResolvedRelation as V, buildFeedTargetCaps as W, buildFtsSchema as X, canonicalChangeDefinitions as Y, changeConsumerPhases as Z, changeLogCoverage as _, type RecordRow as a, countColumnName as a0, deriveShortName as a1, feedTargetMaxItems as a2, ftsQueryClause as a3, getCollectionMethods as a4, getCollectionNames as a5, getCollectionNsids as a6, getCollectionShortNames as a7, getDependentCollections as a8, getDependentNsids as a9, sqliteFtsContentExpression as aA, validateConfig as aB, validateFieldName as aC, getDependentShortNames as aa, getDialect as ab, getDiscoverableCollections as ac, getDiscoverableNsids as ad, getDiscoverableShortNames as ae, getFeedFollowCollections as af, getFeedFollowShortNames as ag, getFeedMutatingNsids as ah, getNestedValue as ai, getRelationField as aj, groupedCountColumnName as ak, jetstreamService as al, jetstreamUrlOption as am, normalizeFeedTarget as an, normalizeJetstreamService as ao, normalizeProfileConfig as ap, nsidForShortName as aq, optimizeAnalysisLimit as ar, optimizeEnabled as as, optimizeIntervalMs as at, postgresDialect as au, recordsTableName as av, resolveCollectionKey as aw, resolveConfig as ax, shortNameForNsid as ay, sqliteDialect as az, type ResolvedContrailConfig as b, type CollectionConfig as c, type SqlDialect as d, type RelationConfig as e, type ReferenceConfig as f, type LabelsConfig as g, type AtprotoServiceAuthConfig as h, type ChangeConsumerConfig as i, type ChangeConsumerInitialMode as j, type ChangeLogConfig as k, type CollectionMethod as l, type ConstellationConfig as m, type CustomQueryHandler as n, DEFAULT_ANALYSIS_LIMIT as o, DEFAULT_COLLECTION_METHODS as p, DEFAULT_CONSTELLATION_URL as q, DEFAULT_FEED_MAX_ITEMS as r, DEFAULT_FOLLOW_NSID as s, DEFAULT_FOLLOW_SHORT as t, DEFAULT_JETSTREAMS as u, DEFAULT_LABELS_MAX_PER_REQUEST as v, DEFAULT_OPTIMIZE_INTERVAL_MS as w, DEFAULT_PROFILES as x, DEFAULT_RELAYS as y, type FeedTargetConfig as z };