{"version":3,"sources":["../src/index.ts","../src/annotations.ts","../src/errors.ts","../src/values.ts","../src/client.ts","../src/filter.ts"],"sourcesContent":["//! `@duckedup/nidus` — the JavaScript/TypeScript client for nidus.\n//\n// A zero-dependency, cross-runtime remote client over the `nidus serve` HTTP API.\n// Point a {@link NidusClient} at a local or remote server, then upsert and search.\n\nexport { NidusClient } from \"./client.js\";\nexport type { FetchLike, NidusClientOptions } from \"./client.js\";\nexport { NidusError } from \"./errors.js\";\nexport { f } from \"./filter.js\";\nexport { decodeAttrs, decodeValue, encodeAttrs, encodeValue, v } from \"./values.js\";\nexport type {\n  AggregateOptions,\n  Aggregation,\n  AnnInfo,\n  AnnotationOptions,\n  Annotations,\n  AttrInput,\n  ClauseScore,\n  Expansion,\n  ClusterStatus,\n  CodeFileHit,\n  CodeSearchOptions,\n  CodeSymbolHit,\n  Compiled,\n  Decay,\n  DecodedRecord,\n  DecodedValue,\n  Expand,\n  Filter,\n  FilterIndexField,\n  Footprint,\n  Fragment,\n  FtsCombine,\n  FtsField,\n  Highlight,\n  HighlightOptions,\n  Hit,\n  HybridQuerySpelling,\n  HybridSearchBase,\n  HybridSearchOptions,\n  LegScore,\n  LimitPer,\n  ListOptions,\n  NidusRecord,\n  OrderBy,\n  PlanCandidates,\n  PlanNarrowing,\n  PlanTimings,\n  Predicate,\n  ProjectionOptions,\n  QueryAnswer,\n  QueryPath,\n  QueryPlan,\n  RankBy,\n  RankingOptions,\n  Readiness,\n  RecallOptions,\n  RecordInput,\n  RememberOptions,\n  RememberResult,\n  RerankOptions,\n  Rollup,\n  SearchOptions,\n  SimilarSearchOptions,\n  Stats,\n  StoreVersions,\n  Suggestion,\n  Suggestions,\n  SuggestOptions,\n  TextClause,\n  TextQuerySpelling,\n  TextSearchBase,\n  TextSearchOptions,\n  Value,\n} from \"./types.js\";\n","//! Decoding a hit's optional annotations — the opt-in \"why did this match\".\n//\n// One rule here is JS's alone. The server reports a highlight span as a **UTF-8 byte**\n// range into the fragment text, but a JS string is indexed in UTF-16 code units, so\n// `text.slice(...span)` on a raw span is wrong for any non-ASCII excerpt. Converted here,\n// once, so a caller's obvious slice is the right one.\n\nimport type { Annotations, Fragment, Highlight } from \"./types.js\";\n\n/** A fragment as it arrives: `spans` are UTF-8 byte offsets into `text`. */\ninterface WireFragment {\n  text: string;\n  spans: [number, number][];\n}\n\ninterface WireHighlight {\n  field: string;\n  fragments: WireFragment[];\n}\n\n/** A hit's annotations as they arrive, before the span offsets are converted. */\nexport interface WireAnnotations {\n  vector?: { rank: number; score: number };\n  text?: { rank: number; score: number };\n  clauses?: {\n    field: string;\n    score: number;\n    expansion?: { matched: number; scored: number };\n  }[];\n  highlights?: WireHighlight[];\n}\n\n/**\n * Decode a hit's annotations, converting every highlight span to JS string indices. The\n * parts the server omitted stay omitted rather than becoming empty arrays.\n */\nexport function decodeAnnotations(a: WireAnnotations): Annotations {\n  const out: Annotations = {};\n  if (a.vector) out.vector = a.vector;\n  if (a.text) out.text = a.text;\n  if (a.clauses) out.clauses = a.clauses;\n  if (a.highlights) out.highlights = a.highlights.map(decodeHighlight);\n  return out;\n}\n\nfunction decodeHighlight(h: WireHighlight): Highlight {\n  return { field: h.field, fragments: h.fragments.map(decodeFragment) };\n}\n\nfunction decodeFragment(fr: WireFragment): Fragment {\n  return { text: fr.text, spans: toStringIndices(fr.text, fr.spans) };\n}\n\n/**\n * Convert UTF-8 byte ranges into `text` to JS string indices (UTF-16 code units), so\n * `text.slice(...span)` yields the matched term. An all-ASCII excerpt needs no conversion\n * and is the common case, so it is detected before any table is built.\n */\nexport function toStringIndices(\n  text: string,\n  spans: [number, number][],\n): [number, number][] {\n  if (spans.length === 0 || isAscii(text)) return spans;\n  const index = byteToUnit(text);\n  const at = (b: number): number =>\n    index[Math.min(Math.max(b, 0), index.length - 1)]!;\n  return spans.map(([start, end]): [number, number] => [at(start), at(end)]);\n}\n\n/** One entry per byte of `text` (plus its end), holding that byte's UTF-16 index. */\nfunction byteToUnit(text: string): number[] {\n  const index: number[] = [];\n  let unit = 0;\n  // A byte *inside* a codepoint maps to that codepoint's start. Spans land on token\n  // boundaries, so this only keeps a malformed offset from landing mid-surrogate.\n  for (const ch of text) {\n    for (let n = utf8Len(ch.codePointAt(0)!); n > 0; n--) index.push(unit);\n    unit += ch.length;\n  }\n  index.push(unit);\n  return index;\n}\n\nfunction utf8Len(codePoint: number): number {\n  if (codePoint < 0x80) return 1;\n  if (codePoint < 0x800) return 2;\n  return codePoint < 0x10000 ? 3 : 4;\n}\n\n/** True when every code unit is ASCII, i.e. byte offsets already *are* string indices. */\nfunction isAscii(text: string): boolean {\n  for (let i = 0; i < text.length; i++) {\n    if (text.charCodeAt(i) > 0x7f) return false;\n  }\n  return true;\n}\n","//! Error type carrying the HTTP status the server reported.\n//\n// The server replies to a failed request with `{ \"error\": <message> }` and a\n// meaningful status (`src/server/mod.rs#classify`): 400 dimension mismatch,\n// 403 read-only store, 409 writer-lock conflict, 507 capacity/OOM, 500 otherwise.\n// Callers branch on `.status` to tell a client fault from a server fault.\n\n/** An error returned by a `nidus` server, or a transport failure reaching it. */\nexport class NidusError extends Error {\n  /** The HTTP status code, or `0` for a transport/timeout failure (no response). */\n  readonly status: number;\n\n  constructor(message: string, status: number) {\n    super(message);\n    this.name = \"NidusError\";\n    this.status = status;\n  }\n\n  /** A malformed request the server rejected (HTTP 400). */\n  get isBadRequest(): boolean {\n    return this.status === 400;\n  }\n  /** The store is read-only (HTTP 403). */\n  get isReadOnly(): boolean {\n    return this.status === 403;\n  }\n  /** The writer lock is held by another process (HTTP 409). */\n  get isLocked(): boolean {\n    return this.status === 409;\n  }\n  /** Out of capacity: `max_vector_bytes` exceeded or OOM (HTTP 507). */\n  get isOutOfCapacity(): boolean {\n    return this.status === 507;\n  }\n}\n","//! Ergonomic constructors and decoders for the externally-tagged `Value` wire type.\n//\n// Callers should never hand-write `{ Str: \"x\" }`. Use `v.str(\"x\")`, `v.int(5)`,\n// etc., or just pass plain JS values into `attrs` — `encodeValue` normalizes them.\n//\n// One rule is JS's alone. The store's `Int` and `Float` are separate types compared\n// same-type only, but JS has one `number` and `1.0 === 1`, so `Number.isInteger` has to\n// decide. A whole-numbered measurement therefore lands as an `Int` in whichever records\n// it came out round, and a `Float` range filter then skips exactly those: write such a\n// field with `v.float`. Go and Python have the types JS lacks and decide from them.\n\nimport type { AttrInput, DecodedValue, Value } from \"./types.js\";\n\n/** Every tag this SDK version knows, in the order `decodeValue` tries them. */\nconst TAGS = [\"Str\", \"Int\", \"Bool\", \"List\", \"Float\", \"DateTime\"] as const;\n\n/**\n * Value constructors mirroring the `Value` variants. `v.int` requires a safe\n * integer and `v.float` a finite number — `NaN`/`Infinity` have no JSON spelling,\n * and `JSON.stringify` would quietly write `null`.\n */\nexport const v = {\n  str: (s: string): Value => ({ Str: s }),\n  int: (n: number): Value => {\n    if (!Number.isInteger(n)) {\n      throw new TypeError(`v.int expects an integer, got ${n}`);\n    }\n    return { Int: n };\n  },\n  float: (n: number): Value => {\n    if (typeof n !== \"number\" || !Number.isFinite(n)) {\n      throw new TypeError(`v.float expects a finite number, got ${n}`);\n    }\n    return { Float: n };\n  },\n  bool: (b: boolean): Value => ({ Bool: b }),\n  list: (items: string[]): Value => ({ List: items }),\n  /**\n   * A UTC instant, from a `Date` or a raw epoch-millisecond count. Milliseconds is\n   * the wire type, so there is no sub-millisecond precision and no timezone.\n   */\n  datetime: (when: Date | number): Value => {\n    const ms = when instanceof Date ? when.getTime() : when;\n    if (!Number.isSafeInteger(ms)) {\n      throw new TypeError(\n        `v.datetime expects a valid Date or epoch ms, got ${when}`,\n      );\n    }\n    return { DateTime: ms };\n  },\n  /** The explicit `Null` value — set-but-empty, distinct from an absent key. */\n  nil: (): Value => \"Null\",\n} as const;\n\n/** True if `x` is already a wire-tagged {@link Value}. */\nfunction isValue(x: unknown): x is Value {\n  if (x === \"Null\") return true;\n  if (typeof x !== \"object\" || x === null) return false;\n  return TAGS.some((tag) => tag in x);\n}\n\n/**\n * Normalize a caller-supplied {@link AttrInput} into the wire {@link Value} shape.\n * Plain scalars map by type; an already-tagged `Value` passes through unchanged.\n * Throws on a non-finite number, an invalid `Date`, or a non-string list element.\n */\nexport function encodeValue(input: AttrInput): Value {\n  if (isValue(input)) return input;\n  if (input === null) return \"Null\";\n  switch (typeof input) {\n    case \"string\":\n      return { Str: input };\n    case \"boolean\":\n      return { Bool: input };\n    case \"number\":\n      return Number.isInteger(input) ? v.int(input) : v.float(input);\n    case \"object\":\n      // Date before the array check: both are objects, only one is a list.\n      if (input instanceof Date) return v.datetime(input);\n      if (Array.isArray(input)) {\n        if (!input.every((e) => typeof e === \"string\")) {\n          throw new TypeError(\"a List attribute must contain only strings\");\n        }\n        return { List: input };\n      }\n    // falls through\n    default:\n      throw new TypeError(`cannot encode attribute value: ${String(input)}`);\n  }\n}\n\n/** Normalize a whole `attrs` map of {@link AttrInput} into wire {@link Value}s. */\nexport function encodeAttrs(\n  attrs: Record<string, AttrInput>,\n): Record<string, Value> {\n  const out: Record<string, Value> = {};\n  for (const [k, val] of Object.entries(attrs)) {\n    out[k] = encodeValue(val);\n  }\n  return out;\n}\n\n/** Decode a wire {@link Value} back to a plain JS value. */\nexport function decodeValue(value: Value): DecodedValue {\n  if (value === \"Null\") return null;\n  if (\"Str\" in value) return value.Str;\n  if (\"Int\" in value) return value.Int;\n  if (\"Bool\" in value) return value.Bool;\n  if (\"List\" in value) return value.List;\n  if (\"Float\" in value) return value.Float;\n  // A Date, not the raw number: a number would demote every instant to an Int\n  // when a decoded attrs map is written back.\n  if (\"DateTime\" in value) return new Date(value.DateTime);\n  // Unknown tag (forward-compat): hand it back untouched.\n  return value as unknown as DecodedValue;\n}\n\n/** Decode a whole wire `attrs` map back to plain JS values. */\nexport function decodeAttrs(\n  attrs: Record<string, Value>,\n): Record<string, DecodedValue> {\n  const out: Record<string, DecodedValue> = {};\n  for (const [k, val] of Object.entries(attrs)) {\n    out[k] = decodeValue(val);\n  }\n  return out;\n}\n","//! `NidusClient` — a remote client over the `nidus serve` HTTP API.\n//\n// One method per endpoint (`src/server/mod.rs`). \"Local vs remote\" is just the\n// base URL: point at a local `nidus serve` or any reachable host. Built on the\n// platform-global `fetch`, so it runs unchanged on Node 18+, Deno, Bun, Cloudflare\n// Workers, and browsers — with no runtime dependencies.\n\nimport { decodeAnnotations, type WireAnnotations } from \"./annotations.js\";\nimport { NidusError } from \"./errors.js\";\nimport type {\n  AggregateOptions,\n  Aggregation,\n  BatchSearchOptions,\n  ClusterStatus,\n  CodeFileHit,\n  CodeSearchOptions,\n  Compiled,\n  DecodedRecord,\n  Expand,\n  Filter,\n  FilterIndexField,\n  FtsField,\n  HighlightOptions,\n  Hit,\n  HybridSearchOptions,\n  ListOptions,\n  NidusRecord,\n  PlanCandidates,\n  PlanNarrowing,\n  PlanTimings,\n  QueryAnswer,\n  QueryPlan,\n  RankBy,\n  Readiness,\n  RecallOptions,\n  RecordInput,\n  RememberOptions,\n  RememberResult,\n  RerankOptions,\n  Rollup,\n  SearchOptions,\n  SimilarSearchOptions,\n  Stats,\n  StoreVersions,\n  Suggestions,\n  SuggestOptions,\n  TextSearchOptions,\n  Value,\n} from \"./types.js\";\nimport { decodeAttrs, decodeValue, encodeAttrs } from \"./values.js\";\n\n/** Minimal `fetch` signature the client needs — satisfied by the platform global. */\nexport type FetchLike = (\n  input: string,\n  init?: RequestInit,\n) => Promise<Response>;\n\n/** Construction options for {@link NidusClient}. */\nexport interface NidusClientOptions {\n  /** Base URL of the server, e.g. `http://127.0.0.1:7700`. Trailing slash optional. */\n  baseUrl: string;\n  /** Bearer token, when the server was started with `--token`. */\n  token?: string;\n  /** Override the `fetch` implementation (defaults to `globalThis.fetch`). */\n  fetch?: FetchLike;\n  /** Per-request timeout in milliseconds. Omit (or `0`) to disable. */\n  timeoutMs?: number;\n  /** Extra headers sent on every request. */\n  headers?: Record<string, string>;\n  /**\n   * Address a single namespace on a server started with `--namespaced` (nidus-pcpc.2):\n   * every request is sent as `/ns/{namespace}/...` instead of flat. Omit against a\n   * single-store server; every path is produced byte-for-byte as it was before this\n   * option existed.\n   */\n  namespace?: string;\n}\n\nexport class NidusClient {\n  private readonly baseUrl: string;\n  private readonly token?: string;\n  private readonly doFetch: FetchLike;\n  private readonly timeoutMs: number;\n  private readonly extraHeaders: Record<string, string>;\n  private readonly namespace?: string;\n\n  constructor(options: NidusClientOptions) {\n    if (!options.baseUrl) {\n      throw new TypeError(\"NidusClient requires a baseUrl\");\n    }\n    this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n    this.token = options.token;\n    this.timeoutMs = options.timeoutMs ?? 0;\n    this.extraHeaders = options.headers ?? {};\n    this.namespace = options.namespace;\n    const f = options.fetch ?? globalThis.fetch;\n    if (typeof f !== \"function\") {\n      throw new TypeError(\n        \"no fetch available; pass options.fetch (Node < 18, or a custom runtime)\",\n      );\n    }\n    // Bind so a passed `globalThis.fetch` keeps its `this`.\n    this.doFetch = f === globalThis.fetch ? f.bind(globalThis) : f;\n  }\n\n  // ── Admin / introspection ─────────────────────────────────────────────────\n\n  /** Liveness check. Returns `true` when the server answers `/health`. */\n  async health(): Promise<boolean> {\n    try {\n      const res = await this.raw(\"GET\", \"/health\");\n      return res.ok;\n    } catch {\n      return false;\n    }\n  }\n\n  /** Store-wide introspection: dimension, distance, ANN config, collections, footprint. */\n  stats(): Promise<Stats> {\n    return this.request<Stats>(\"GET\", \"/stats\");\n  }\n\n  /**\n   * Readiness: whether this instance can serve. A `503` is the negative answer, not an\n   * error, so a poll loop branches on `ready` instead of catching. Other failures throw.\n   */\n  async ready(): Promise<Readiness> {\n    const res = await this.raw(\"GET\", \"/ready\");\n    const text = await res.text();\n    if (res.status === 503) return { ready: false, reason: extractError(text, 503) };\n    if (!res.ok) throw new NidusError(extractError(text, res.status), res.status);\n    return JSON.parse(text) as Readiness;\n  }\n\n  /** Cluster role, writer-handle state, fencing token, commit counter, staleness. */\n  cluster(): Promise<ClusterStatus> {\n    return this.request<ClusterStatus>(\"GET\", \"/cluster\");\n  }\n\n  /** The readable commit points and this instance's pin, if any. */\n  versions(): Promise<StoreVersions> {\n    return this.request<StoreVersions>(\"GET\", \"/versions\");\n  }\n\n  /** List every collection name. */\n  collections(): Promise<string[]> {\n    return this.request<string[]>(\"GET\", \"/collections\");\n  }\n\n  /** Create a collection. Idempotent on the server side. */\n  async createCollection(name: string): Promise<void> {\n    await this.request(\"POST\", `/collections/${enc(name)}`, {});\n  }\n\n  /** Drop a collection and all its records. */\n  async dropCollection(name: string): Promise<void> {\n    await this.request(\"DELETE\", `/collections/${enc(name)}`);\n  }\n\n  /** Every alias and the concrete collection it resolves to. */\n  aliases(): Promise<Record<string, string>> {\n    return this.request<Record<string, string>>(\"GET\", \"/aliases\");\n  }\n\n  /** Create or repoint an alias. The target must already exist; aliases never chain. */\n  async setAlias(name: string, target: string): Promise<void> {\n    await this.request(\"PUT\", `/aliases/${enc(name)}`, { target });\n  }\n\n  /** Remove an alias. Deletes no records. */\n  async dropAlias(name: string): Promise<void> {\n    await this.request(\"DELETE\", `/aliases/${enc(name)}`);\n  }\n\n  /** Read a collection's free-form string metadata. */\n  getMeta(name: string): Promise<Record<string, string>> {\n    return this.request<Record<string, string>>(\n      \"GET\",\n      `/collections/${enc(name)}/meta`,\n    );\n  }\n\n  /** Replace a collection's free-form string metadata. */\n  async setMeta(name: string, meta: Record<string, string>): Promise<void> {\n    await this.request(\"PUT\", `/collections/${enc(name)}/meta`, meta);\n  }\n\n  // ── Data ──────────────────────────────────────────────────────────────────\n\n  /**\n   * Insert or replace records (idempotent on `id` within the collection).\n   * `attrs` accept plain JS values or `v.*` helpers; they are normalized for you.\n   * Returns the number of records upserted.\n   */\n  async upsert(name: string, records: RecordInput[]): Promise<number> {\n    const wire: NidusRecord[] = records.map((r) => ({\n      id: r.id,\n      ...(r.vector !== undefined ? { vector: r.vector } : {}),\n      ...(r.vectors !== undefined ? { vectors: r.vectors } : {}),\n      attrs: encodeAttrs(r.attrs),\n    }));\n    const res = await this.request<{ upserted: number }>(\n      \"POST\",\n      `/collections/${enc(name)}/upsert`,\n      { records: wire },\n    );\n    return res.upserted;\n  }\n\n  /** Delete records by id. Returns the number deleted. */\n  async delete(name: string, opts: { ids: string[] }): Promise<number> {\n    const res = await this.request<{ deleted: number }>(\n      \"POST\",\n      `/collections/${enc(name)}/delete`,\n      { ids: opts.ids },\n    );\n    return res.deleted;\n  }\n\n  /** Delete every record matching `filter`. Returns the number deleted. */\n  async deleteWhere(name: string, filter: Filter): Promise<number> {\n    const res = await this.request<{ deleted: number }>(\n      \"POST\",\n      `/collections/${enc(name)}/delete`,\n      { filter },\n    );\n    return res.deleted;\n  }\n\n  /** Fetch every record in a collection (attrs decoded to plain JS values). */\n  async records(name: string): Promise<DecodedRecord[]> {\n    const recs = await this.request<NidusRecord[]>(\n      \"GET\",\n      `/collections/${enc(name)}/records`,\n    );\n    return recs.map((r) => ({\n      id: r.id,\n      ...(r.vector !== undefined ? { vector: r.vector } : {}),\n      ...(r.vectors !== undefined ? { vectors: r.vectors } : {}),\n      attrs: decodeAttrs(r.attrs),\n    }));\n  }\n\n  /**\n   * Declare the full-text-indexed attribute fields for a collection. A bare string\n   * takes the server's BM25/analyzer defaults; an {@link FtsField} object tunes `k1`,\n   * `b`, and the analyzer for that field alone.\n   */\n  async setFtsSchema(\n    name: string,\n    fields: (string | FtsField)[],\n  ): Promise<void> {\n    await this.request(\"POST\", `/collections/${enc(name)}/fts-schema`, {\n      fields: fields.map(encodeFtsField),\n    });\n  }\n\n  /**\n   * Declare which attribute fields are indexed for the text predicates (`Fuzzy`,\n   * `ContainsAllTokens`, `ContainsAnyToken`, `ContainsTokenSequence`, `Regex`). Fields\n   * already written are indexed as part of applying the declaration.\n   *\n   * This changes how fast those predicates run, never what they return: the index\n   * proposes candidate documents and the predicate itself still decides. The cost is\n   * paid at write time and in memory. Pass an empty array to drop the declaration.\n   */\n  async setFilterIndex(\n    name: string,\n    fields: (string | FilterIndexField)[],\n  ): Promise<void> {\n    await this.request(\"POST\", `/collections/${enc(name)}/filter-index`, {\n      fields: fields.map(encodeFilterIndexField),\n    });\n  }\n\n  /**\n   * Declare the named-vector fields a collection accepts on upsert and search, beyond\n   * the reserved `\"default\"` vector (nidus-85t). Upserting an undeclared name is a\n   * `400` naming it; mirrors {@link NidusClient.setFtsSchema}'s declare-then-use shape.\n   */\n  async setVectorNames(name: string, names: string[]): Promise<void> {\n    await this.request(\"POST\", `/collections/${enc(name)}/vector-names`, { names });\n  }\n\n  // ── Search ──────────────────────────────────────────────────────────────\n\n  /** Vector (cosine) nearest-neighbour search. Empty `scope` searches all collections. */\n  search(opts: SearchOptions): Promise<Hit[]> {\n    return this.searchRequest(\"/search\", {\n      query: opts.query,\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      min_score: opts.minScore,\n      filter: opts.filter ?? [],\n      exact: opts.exact,\n      include_attributes: opts.includeAttributes,\n      exclude_attributes: opts.excludeAttributes,\n      rank_by: encodeRankBy(opts.rankBy),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n      expand: encodeExpand(opts.expand),\n      rerank: encodeRerank(opts.rerank),\n      names: opts.names,\n      name_weights: opts.nameWeights,\n      pool: opts.pool,\n    });\n  }\n\n  /** Like {@link NidusClient.search}, but also reports the scan strategy the server took. */\n  searchWithPlan(\n    opts: SearchOptions,\n  ): Promise<{ hits: Hit[]; plan: QueryPlan }> {\n    return this.searchRequestWithPlan(\"/search\", {\n      query: opts.query,\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      min_score: opts.minScore,\n      filter: opts.filter ?? [],\n      exact: opts.exact,\n      include_attributes: opts.includeAttributes,\n      exclude_attributes: opts.excludeAttributes,\n      rank_by: encodeRankBy(opts.rankBy),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n      expand: encodeExpand(opts.expand),\n      rerank: encodeRerank(opts.rerank),\n      names: opts.names,\n      name_weights: opts.nameWeights,\n      pool: opts.pool,\n    });\n  }\n\n  /** Records most like an existing one. The source record itself is never returned. */\n  searchSimilar(opts: SimilarSearchOptions): Promise<Hit[]> {\n    return this.searchRequest(\"/search/similar\", {\n      collection: opts.collection,\n      id: opts.id,\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      min_score: opts.minScore,\n      filter: opts.filter ?? [],\n      exact: opts.exact,\n      include_attributes: opts.includeAttributes,\n      exclude_attributes: opts.excludeAttributes,\n      rank_by: encodeRankBy(opts.rankBy),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n      expand: encodeExpand(opts.expand),\n    });\n  }\n\n  /** Like {@link NidusClient.searchSimilar}, but also reports the scan strategy taken. */\n  searchSimilarWithPlan(\n    opts: SimilarSearchOptions,\n  ): Promise<{ hits: Hit[]; plan: QueryPlan }> {\n    return this.searchRequestWithPlan(\"/search/similar\", {\n      collection: opts.collection,\n      id: opts.id,\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      min_score: opts.minScore,\n      filter: opts.filter ?? [],\n      exact: opts.exact,\n      include_attributes: opts.includeAttributes,\n      exclude_attributes: opts.excludeAttributes,\n      rank_by: encodeRankBy(opts.rankBy),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n      expand: encodeExpand(opts.expand),\n    });\n  }\n\n  /**\n   * BM25 full-text search over one indexed field, or over a `clauses` list folded by\n   * `combine` (`\"Sum\"` unless said otherwise). Naming the fields both ways is a `400`.\n   */\n  textSearch(opts: TextSearchOptions): Promise<Hit[]> {\n    return this.searchRequest(\"/text-search\", {\n      ...(opts.clauses\n        ? { clauses: opts.clauses, combine: opts.combine }\n        : { field: opts.field, query: opts.query, prefix: opts.prefix }),\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      min_score: opts.minScore,\n      filter: opts.filter ?? [],\n      explain: opts.explain,\n      highlight: encodeHighlight(opts.highlight),\n      include_attributes: opts.includeAttributes,\n      exclude_attributes: opts.excludeAttributes,\n      rank_by: encodeRankBy(opts.rankBy),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n      expand: encodeExpand(opts.expand),\n      rerank: encodeRerank(opts.rerank),\n    });\n  }\n\n  /**\n   * AST-aware source and docs search over one corpus (the `code` feature, `POST\n   * /code-search`): a text query grouped by file, each with the symbols it matched.\n   * `vector` picks vector-vs-BM25; omitted, it defers to the store the same way\n   * {@link NidusClient.textSearch} never has to (that route is BM25-only).\n   */\n  async codeSearch(opts: CodeSearchOptions): Promise<CodeFileHit[]> {\n    const res = await this.request<RawCodeSearchResponse>(\n      \"POST\",\n      \"/code-search\",\n      prune({\n        collection: opts.collection,\n        query: opts.query,\n        limit: opts.limit,\n        filter: opts.filter ?? [],\n        vector: opts.vector,\n      }),\n    );\n    return res.files.map((f) => ({\n      path: f.path,\n      language: f.language,\n      symbols: f.symbols.map((s) => ({\n        symbol: s.symbol,\n        kind: s.kind,\n        startLine: s.start_line,\n        endLine: s.end_line,\n        score: s.score,\n      })),\n    }));\n  }\n\n  /**\n   * Ranked term completions for a partial word, for an autocomplete dropdown. Ranked by\n   * document frequency (commonest first), which is the opposite of how a prefix clause\n   * ranks documents. Completions are real spellings: the prefix is folded, not stemmed.\n   *\n   * The `df` counts only documents passing `filter` and carrying every word already typed\n   * before the final token, so a permission-scoped dropdown is expressible and \"quick br\"\n   * completes against the documents that also say \"quick\".\n   */\n  suggest(opts: SuggestOptions): Promise<Suggestions> {\n    return this.request<Suggestions>(\n      \"POST\",\n      \"/suggest\",\n      prune({\n        scope: opts.scope ?? [],\n        field: opts.field,\n        prefix: opts.prefix,\n        limit: opts.limit,\n        filter: opts.filter ?? [],\n        fuzzy: opts.fuzzy,\n      }),\n    );\n  }\n\n  /**\n   * Hybrid search: fuse a vector query and a BM25 text query via RRF. The text leg takes\n   * the same single-field / `clauses` choice as {@link NidusClient.textSearch}.\n   */\n  hybridSearch(opts: HybridSearchOptions): Promise<Hit[]> {\n    return this.searchRequest(\"/hybrid-search\", {\n      vector: opts.vector,\n      ...(opts.clauses\n        ? { clauses: opts.clauses, combine: opts.combine }\n        : { field: opts.field, text: opts.text, prefix: opts.prefix }),\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      filter: opts.filter ?? [],\n      rrf_k: opts.rrfK,\n      candidates: opts.candidates,\n      explain: opts.explain,\n      highlight: encodeHighlight(opts.highlight),\n      vector_weight: opts.vectorWeight,\n      text_weight: opts.textWeight,\n      expand: encodeExpand(opts.expand),\n      rerank: encodeRerank(opts.rerank),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n    });\n  }\n\n  /** Like {@link NidusClient.hybridSearch}, but also reports the scan strategy taken. */\n  hybridSearchWithPlan(\n    opts: HybridSearchOptions,\n  ): Promise<{ hits: Hit[]; plan: QueryPlan }> {\n    return this.searchRequestWithPlan(\"/hybrid-search\", {\n      vector: opts.vector,\n      ...(opts.clauses\n        ? { clauses: opts.clauses, combine: opts.combine }\n        : { field: opts.field, text: opts.text, prefix: opts.prefix }),\n      scope: opts.scope ?? [],\n      top_k: opts.topK,\n      offset: opts.offset,\n      filter: opts.filter ?? [],\n      rrf_k: opts.rrfK,\n      candidates: opts.candidates,\n      explain: opts.explain,\n      highlight: encodeHighlight(opts.highlight),\n      vector_weight: opts.vectorWeight,\n      text_weight: opts.textWeight,\n      expand: encodeExpand(opts.expand),\n      rerank: encodeRerank(opts.rerank),\n      limit_per: opts.limitPer,\n      diversity: opts.diversity,\n    });\n  }\n\n  /** Metadata-only listing (no vector), paginated by `offset`/`limit`. */\n  list(opts: ListOptions = {}): Promise<Hit[]> {\n    return this.searchRequest(\"/list\", {\n      scope: opts.scope ?? [],\n      offset: opts.offset,\n      limit: opts.limit,\n      filter: opts.filter ?? [],\n      include_attributes: opts.includeAttributes,\n      exclude_attributes: opts.excludeAttributes,\n      order_by: opts.orderBy,\n    });\n  }\n\n  /**\n   * Count the records matching a filter and sum the named attributes. Answered from the\n   * in-RAM index alone — no record is built and no vector is read.\n   */\n  async aggregate(opts: AggregateOptions = {}): Promise<Aggregation> {\n    const res = await this.request<RawAggregation>(\n      \"POST\",\n      \"/aggregate\",\n      prune({\n        scope: opts.scope ?? [],\n        filter: opts.filter ?? [],\n        sum: opts.sum ?? [],\n        group_by: opts.groupBy,\n      }),\n    );\n    // Every sum is an `Int` or a `Float`, both of which decode to a JS number.\n    return {\n      count: res.count,\n      sums: decodeAttrs(res.sums) as Record<string, number>,\n      // Kept absent, not `undefined`, so an ungrouped answer is the shape it always was.\n      ...(res.groups\n        ? {\n            groups: res.groups.map((g) => ({\n              value: g.value === null ? null : decodeValue(g.value),\n              count: g.count,\n              sums: decodeAttrs(g.sums) as Record<string, number>,\n            })),\n          }\n        : {}),\n      ...(res.groups_truncated ? { groupsTruncated: true } : {}),\n    };\n  }\n\n  // ── SQL (SPEC §7.12) ────────────────────────────────────────────────────\n\n  /**\n   * Compile and run a `SELECT ...` script against `POST /query` (SPEC §7.12). A single\n   * statement decodes to its own answer (hits, `{hits, plan}`, or an {@link Aggregation});\n   * a `;`-separated script answers one {@link QueryAnswer} per statement, in request order.\n   * A parse error rejects with the server's message verbatim (byte offset and §7 section).\n   */\n  async query(sql: string): Promise<QueryAnswer | QueryAnswer[]> {\n    const raw = await this.request<unknown>(\"POST\", \"/query\", { sql });\n    if (Array.isArray(raw) && raw.length > 0 && !this.isHitShaped(raw[0])) {\n      return raw.map((a) => this.decodeQueryAnswer(a));\n    }\n    return this.decodeQueryAnswer(raw);\n  }\n\n  /**\n   * Compile a `SELECT ...` script without running it: the typed value(s) the matching\n   * `Store` method would receive. Always an array, one entry per `;`-separated statement.\n   */\n  async compile(sql: string): Promise<Compiled[]> {\n    const raw = await this.request<unknown>(\"POST\", \"/query\", {\n      sql,\n      compile_only: true,\n    });\n    return Array.isArray(raw) ? (raw as Compiled[]) : [raw as Compiled];\n  }\n\n  /** A wire hit's shape, distinguishing a bare hits-answer from a batch of answers. */\n  private isHitShaped(x: unknown): x is RawHit {\n    return (\n      typeof x === \"object\" &&\n      x !== null &&\n      !Array.isArray(x) &&\n      typeof (x as { id?: unknown }).id === \"string\"\n    );\n  }\n\n  /** Decode one statement's `/query` answer: hits (bare or `{hits, plan}`), or an aggregation. */\n  private decodeQueryAnswer(raw: unknown): QueryAnswer {\n    if (Array.isArray(raw)) {\n      return raw.map((h) => this.decodeHit(h as RawHit));\n    }\n    const obj = raw as Record<string, unknown>;\n    if (\"count\" in obj) {\n      return {\n        count: obj.count as number,\n        sums: decodeAttrs(obj.sums as Record<string, Value>) as Record<string, number>,\n        ...(obj.groups\n          ? {\n              groups: (obj.groups as NonNullable<RawAggregation[\"groups\"]>).map((g) => ({\n                value: g.value === null ? null : decodeValue(g.value),\n                count: g.count,\n                sums: decodeAttrs(g.sums) as Record<string, number>,\n              })),\n            }\n          : {}),\n        ...(obj.groups_truncated ? { groupsTruncated: true } : {}),\n      };\n    }\n    return {\n      hits: (obj.hits as RawHit[]).map((h) => this.decodeHit(h)),\n      plan: decodeQueryPlan(obj.plan as RawQueryPlan),\n    };\n  }\n\n  /**\n   * Answer several vector queries in one round-trip (16 max). Returns one ranking per\n   * query in request order, or — with `opts.fuse` — a single array holding the one fused\n   * ranking, so the return shape is uniform either way.\n   *\n   * The server validates the whole batch before running any leg, so a malformed query\n   * fails the call rather than returning a partial answer that cannot be told apart.\n   */\n  async batchSearch(opts: BatchSearchOptions): Promise<Hit[][]> {\n    const body = prune({\n      queries: opts.queries.map((q) => ({\n        query: q.query,\n        scope: q.scope ?? [],\n        top_k: q.topK,\n        offset: q.offset,\n        min_score: q.minScore,\n        filter: q.filter ?? [],\n        exact: q.exact,\n        include_attributes: q.includeAttributes,\n        exclude_attributes: q.excludeAttributes,\n        rank_by: encodeRankBy(q.rankBy),\n        limit_per: q.limitPer,\n        diversity: q.diversity,\n        expand: encodeExpand(q.expand),\n      })),\n      fuse: opts.fuse\n        ? prune({\n            rrf_k: opts.fuse.rrfK,\n            weights: opts.fuse.weights,\n            top_k: opts.fuse.topK,\n          })\n        : undefined,\n    });\n    const res = await this.request<RawBatchSearch>(\n      \"POST\",\n      \"/search/batch\",\n      body,\n    );\n    return (res.fused ? [res.fused] : (res.results ?? [])).map((hits) =>\n      hits.map((h) => this.decodeHit(h)),\n    );\n  }\n\n  // ── Memory (text-native) ──────────────────────────────────────────────────\n  //\n  // Available only when `nidus serve` was started with an embedder\n  // (`--embed-provider …`); otherwise these answer `400`. The server embeds the\n  // text/query — the client only sends strings.\n\n  /**\n   * Embed `text` and upsert it under `id` in `collection` (idempotent on `id`).\n   * With `opts.mode === \"summarize\"` the server summarizes first, embeds the\n   * summary, and stamps a `nidus.summary` attr (requires the server to have a\n   * summarizer). The raw text is always stored under `nidus.text`. `opts.attrs` accept plain JS values or `v.*`\n   * helpers; they are normalized for you.\n   *\n   * Read `id` off the result rather than assuming the one you passed:\n   * `opts.dedupeThreshold` can redirect the write onto a near-duplicate.\n   */\n  async remember(\n    collection: string,\n    id: string,\n    text: string,\n    opts: RememberOptions = {},\n  ): Promise<RememberResult> {\n    const res = await this.request<Partial<RememberResult> | undefined>(\n      \"POST\",\n      `/collections/${enc(collection)}/remember`,\n      prune({\n        id,\n        text,\n        mode: opts.mode,\n        attrs: opts.attrs ? encodeAttrs(opts.attrs) : undefined,\n        ttl_seconds: opts.ttlSeconds,\n        dedupe_threshold: opts.dedupeThreshold,\n      }),\n    );\n    // A server predating the echoed fields answers `{ok, upserted}`; falling back to the\n    // requested id keeps that case honest instead of reporting `undefined` as the target.\n    return {\n      id: res?.id ?? id,\n      upserted: res?.upserted ?? 0,\n      deduped: res?.deduped ?? false,\n    };\n  }\n\n  /**\n   * Embed `query` and vector-search `collection`, best-first (attrs decoded to\n   * plain JS values). Refused with a cross-model guard if the collection was\n   * written with a different embedder than the server's.\n   */\n  recall(\n    collection: string,\n    query: string,\n    opts: RecallOptions = {},\n  ): Promise<Hit[]> {\n    return this.searchRequest(`/collections/${enc(collection)}/recall`, {\n      query,\n      top_k: opts.topK,\n      min_score: opts.minScore,\n      filter: opts.filter ?? [],\n      diversity: opts.diversity,\n      rollup: encodeRollup(opts.rollup),\n      rerank: encodeRerank(opts.rerank),\n      reinforce: opts.reinforce,\n      extend_ttl_seconds: opts.extendTtlSeconds,\n      rank_by: encodeRankBy(opts.rankBy),\n    });\n  }\n\n  // ── Maintenance ───────────────────────────────────────────────────────────\n\n  /** Force a durability flush. */\n  async flush(): Promise<void> {\n    await this.request(\"POST\", \"/flush\", {});\n  }\n\n  /** Compact the store (reclaim space from deleted/overwritten rows). */\n  async compact(): Promise<void> {\n    await this.request(\"POST\", \"/compact\", {});\n  }\n\n  /** Adopt a writer's newer committed state. Returns whether anything was adopted. */\n  async refresh(): Promise<boolean> {\n    const res = await this.request<{ adopted: boolean }>(\"POST\", \"/refresh\", {});\n    return res.adopted;\n  }\n\n  // ── Internals ─────────────────────────────────────────────────────────────\n\n  /** Run a search-family request and decode the resulting hits' attrs. */\n  private async searchRequest(\n    path: string,\n    body: Record<string, unknown>,\n  ): Promise<Hit[]> {\n    const hits = await this.request<RawHit[]>(\"POST\", path, prune(body));\n    return hits.map((h) => this.decodeHit(h));\n  }\n\n  /** Like {@link NidusClient.searchRequest}, asking for `plan: true` and decoding it too. */\n  private async searchRequestWithPlan(\n    path: string,\n    body: Record<string, unknown>,\n  ): Promise<{ hits: Hit[]; plan: QueryPlan }> {\n    const res = await this.request<{ hits: RawHit[]; plan: RawQueryPlan }>(\n      \"POST\",\n      path,\n      prune({ ...body, plan: true }),\n    );\n    return {\n      hits: res.hits.map((h) => this.decodeHit(h)),\n      plan: decodeQueryPlan(res.plan),\n    };\n  }\n\n  /** One wire hit into a {@link Hit}. Shared so every search surface decodes identically. */\n  private decodeHit(h: RawHit): Hit {\n    return {\n      collection: h.collection,\n      id: h.id,\n      score: h.score,\n      attrs: decodeAttrs(h.attrs),\n      // Kept absent, not `undefined`, so an unannotated hit is the shape it always was.\n      ...(h.annotations\n        ? { annotations: decodeAnnotations(h.annotations) }\n        : {}),\n      ...(h.context !== undefined ? { context: h.context } : {}),\n    };\n  }\n\n  /** Issue a request and parse a JSON body, mapping a non-2xx to {@link NidusError}. */\n  private async request<T>(\n    method: string,\n    path: string,\n    body?: unknown,\n  ): Promise<T> {\n    const res = await this.raw(method, path, body);\n    const text = await res.text();\n    if (!res.ok) {\n      throw new NidusError(extractError(text, res.status), res.status);\n    }\n    return (text ? JSON.parse(text) : undefined) as T;\n  }\n\n  /**\n   * Prefix `path` with `/ns/{namespace}` when the client was constructed with one\n   * (nidus-pcpc.2), so every call builds its path the same way it always did and the\n   * namespace is applied in this one place. No namespace configured means no prefix:\n   * today's flat paths, byte for byte.\n   */\n  private namespaced(path: string): string {\n    return this.namespace ? `/ns/${enc(this.namespace)}${path}` : path;\n  }\n\n  /** The bare transport: headers, auth, timeout, and transport-error mapping. */\n  private async raw(\n    method: string,\n    path: string,\n    body?: unknown,\n  ): Promise<Response> {\n    const headers: Record<string, string> = { ...this.extraHeaders };\n    if (this.token) headers.authorization = `Bearer ${this.token}`;\n    let payload: string | undefined;\n    if (body !== undefined) {\n      headers[\"content-type\"] = \"application/json\";\n      payload = JSON.stringify(body);\n    }\n\n    const controller = this.timeoutMs > 0 ? new AbortController() : undefined;\n    const timer =\n      controller && this.timeoutMs > 0\n        ? setTimeout(() => controller.abort(), this.timeoutMs)\n        : undefined;\n    try {\n      return await this.doFetch(`${this.baseUrl}${this.namespaced(path)}`, {\n        method,\n        headers,\n        body: payload,\n        signal: controller?.signal,\n      });\n    } catch (err) {\n      const reason =\n        (controller?.signal.aborted ?? false)\n          ? `request to ${path} timed out after ${this.timeoutMs}ms`\n          : `request to ${path} failed: ${(err as Error).message}`;\n      throw new NidusError(reason, 0);\n    } finally {\n      if (timer) clearTimeout(timer);\n    }\n  }\n}\n\n/** A hit as it arrives on the wire, before attrs are decoded. */\ninterface RawHit {\n  collection: string;\n  id: string;\n  score: number;\n  attrs: Record<string, Value>;\n  annotations?: WireAnnotations;\n  context?: string;\n}\n\n/** A `QueryPlan` as it arrives on the wire (snake_case), before camelCasing. */\ninterface RawQueryPlan {\n  path: string;\n  rows_scanned?: number;\n  candidates?: {\n    surfaced: number;\n    survived: number;\n    dropped_out_of_scope: number;\n    dropped_stale: number;\n    dropped_filtered: number;\n    dropped_min_score: number;\n  };\n  narrowing: { state: PlanNarrowing[\"state\"]; candidates?: number };\n  timings: {\n    narrow_us?: number;\n    gather_us?: number;\n    walk_us?: number;\n    resolve_us?: number;\n    first_pass_us?: number;\n    rescore_us?: number;\n    score_us?: number;\n    total_us: number;\n  };\n}\n\n/** Wire `QueryPlan` into its camelCase {@link QueryPlan} shape. */\nfunction decodeQueryPlan(p: RawQueryPlan): QueryPlan {\n  const candidates: PlanCandidates | undefined = p.candidates\n    ? {\n        surfaced: p.candidates.surfaced,\n        survived: p.candidates.survived,\n        droppedOutOfScope: p.candidates.dropped_out_of_scope,\n        droppedStale: p.candidates.dropped_stale,\n        droppedFiltered: p.candidates.dropped_filtered,\n        droppedMinScore: p.candidates.dropped_min_score,\n      }\n    : undefined;\n  const t = p.timings;\n  const timings: PlanTimings = {\n    ...(t.narrow_us !== undefined ? { narrowUs: t.narrow_us } : {}),\n    ...(t.gather_us !== undefined ? { gatherUs: t.gather_us } : {}),\n    ...(t.walk_us !== undefined ? { walkUs: t.walk_us } : {}),\n    ...(t.resolve_us !== undefined ? { resolveUs: t.resolve_us } : {}),\n    ...(t.first_pass_us !== undefined ? { firstPassUs: t.first_pass_us } : {}),\n    ...(t.rescore_us !== undefined ? { rescoreUs: t.rescore_us } : {}),\n    ...(t.score_us !== undefined ? { scoreUs: t.score_us } : {}),\n    totalUs: t.total_us,\n  };\n  return {\n    path: p.path,\n    ...(p.rows_scanned !== undefined ? { rowsScanned: p.rows_scanned } : {}),\n    ...(candidates ? { candidates } : {}),\n    narrowing: {\n      state: p.narrowing.state,\n      ...(p.narrowing.candidates !== undefined\n        ? { candidates: p.narrowing.candidates }\n        : {}),\n    },\n    timings,\n  };\n}\n\n/** An `/aggregate` response, whose sums arrive as tagged {@link Value}s. */\ninterface RawAggregation {\n  count: number;\n  sums: Record<string, Value>;\n  groups?: {\n    value: Value | null;\n    count: number;\n    sums: Record<string, Value>;\n  }[];\n  groups_truncated?: boolean;\n}\n\n/** A `/search/batch` response: exactly one of the two fields is present. */\ninterface RawBatchSearch {\n  results?: RawHit[][];\n  fused?: RawHit[];\n}\n\n/** A `/code-search` response as it arrives on the wire (snake_case), before camelCasing. */\ninterface RawCodeSearchResponse {\n  files: {\n    path: string;\n    language: string | null;\n    symbols: {\n      symbol: string | null;\n      kind: string | null;\n      start_line: number | null;\n      end_line: number | null;\n      score: number;\n    }[];\n  }[];\n}\n\n/** Encode `rankBy` to its externally-tagged wire form, dropping the knobs left unset. */\n/** camelCase → the wire's snake_case, omitting the object entirely when unset. */\nfunction encodeExpand(e: Expand | undefined): unknown {\n  if (!e) return undefined;\n  return prune({\n    radius: e.radius,\n    parent_field: e.parentField,\n    index_field: e.indexField,\n    text_field: e.textField,\n  });\n}\n\nfunction encodeRollup(r: Rollup | undefined): unknown {\n  if (!r) return undefined;\n  return prune({ per_parent: r.perParent, neighbours: r.neighbours });\n}\n\nfunction encodeRankBy(rank: RankBy | undefined): unknown {\n  if (!rank) return undefined;\n  const d = rank.decay;\n  return {\n    Decay: prune({\n      field: d.field,\n      origin: d.origin instanceof Date ? d.origin.getTime() : d.origin,\n      scale: d.scale,\n      decay: d.decay,\n      lambda: d.lambda,\n      missing: d.missing,\n      count_field: d.countField,\n      count_scale: d.countScale,\n      count_lambda: d.countLambda,\n    }),\n  };\n}\n\n/** Encode `highlight`: `true` is the empty object the server reads as \"all defaults\". */\nfunction encodeHighlight(h: boolean | HighlightOptions | undefined): unknown {\n  if (h === undefined || h === false) return undefined;\n  if (h === true) return {};\n  return prune({\n    max_fragments: h.maxFragments,\n    fragment_chars: h.fragmentChars,\n  });\n}\n\n/** Encode `rerank`. Undefined sub-fields drop out at `JSON.stringify`, not here. */\nfunction encodeRerank(r: RerankOptions | undefined): unknown {\n  if (r === undefined) return undefined;\n  return { query: r.query, overscan: r.overscan, text_attr: r.textAttr };\n}\n\n/** Path-segment encode a collection name (allows slashes/spaces in names). */\nfunction enc(name: string): string {\n  return encodeURIComponent(name);\n}\n\n/**\n * Encode one `setFtsSchema` field. A string passes through as the server's bare-name\n * form; an object becomes the snake_case body, pruned so an unset knob keeps the\n * server's default rather than being sent as `undefined`.\n */\nfunction encodeFtsField(f: string | FtsField): unknown {\n  if (typeof f === \"string\") return f;\n  return prune({\n    field: f.field,\n    k1: f.k1,\n    b: f.b,\n    language: f.language,\n    ascii_folding: f.asciiFolding,\n    max_token_len: f.maxTokenLen,\n  });\n}\n\n/**\n * Encode one `setFilterIndex` field, on the same bare-name-or-object rule as\n * {@link encodeFtsField}. Pruning matters here: the server defaults both structures to\n * `true`, so sending an explicit `undefined` would be indistinguishable from `false`.\n */\nfunction encodeFilterIndexField(f: string | FilterIndexField): unknown {\n  if (typeof f === \"string\") return f;\n  return prune({\n    field: f.field,\n    tokens: f.tokens,\n    trigrams: f.trigrams,\n  });\n}\n\n/** Drop `undefined` fields so server `#[serde(default)]`s apply instead. */\nfunction prune(body: Record<string, unknown>): Record<string, unknown> {\n  const out: Record<string, unknown> = {};\n  for (const [k, val] of Object.entries(body)) {\n    if (val !== undefined) out[k] = val;\n  }\n  return out;\n}\n\n/** Pull the `{ \"error\": … }` message out of a failed response, or fall back. */\nfunction extractError(text: string, status: number): string {\n  try {\n    const parsed = JSON.parse(text);\n    if (parsed && typeof parsed.error === \"string\") return parsed.error;\n  } catch {\n    // not JSON — fall through\n  }\n  return text || `HTTP ${status}`;\n}\n","//! Filter builder producing the bare predicate-array wire shape.\n//\n// A `Filter` is AND-combined predicates; on the wire it is a plain array. Each\n// predicate is a *positive assertion about a present attribute* — an absent key\n// matches nothing, including the negative predicates (`ne`/`notIn`) and ranges.\n// Comparisons are same-type only (Int↔Int numeric, Float↔Float by IEEE, Str↔Str\n// lexical, Bool↔Bool, DateTime↔DateTime as instants), so an operand's encoded type\n// has to match the attribute's: `ge(\"score\", v.float(2))`, not `ge(\"score\", 2)`.\n\nimport type { AttrInput, Filter, Predicate, Value } from \"./types.js\";\nimport { encodeValue } from \"./values.js\";\n\n/**\n * Predicate constructors. Each accepts a plain JS value (auto-normalized) or an\n * explicit `v.*` {@link Value}. Combine results into a {@link Filter} array, or\n * use {@link f.and} for readability.\n */\nexport const f = {\n  /** `attrs[key] === value`. */\n  eq: (key: string, value: AttrInput): Predicate => ({\n    Eq: [key, encodeValue(value)],\n  }),\n  /** `attrs[key]` is present and `!== value`. */\n  ne: (key: string, value: AttrInput): Predicate => ({\n    Ne: [key, encodeValue(value)],\n  }),\n  /** `attrs[key]` is a `Str` matching the glob pattern (`*`, `?`, `[..]`). */\n  glob: (key: string, pattern: string): Predicate => ({ Glob: [key, pattern] }),\n  /**\n   * {@link f.glob}, ignoring **ASCII** case on both sides — `\"Src/*\"` matches\n   * `\"src/main.rs\"`. Non-ASCII is not folded (`É` does not match `é`).\n   */\n  iglob: (key: string, pattern: string): Predicate => ({\n    IGlob: [key, pattern],\n  }),\n  /** `attrs[key]` equals one of `values`. */\n  in: (key: string, values: AttrInput[]): Predicate => ({\n    In: [key, values.map(encodeValue)],\n  }),\n  /** `attrs[key]` is present and equals none of `values`. */\n  notIn: (key: string, values: AttrInput[]): Predicate => ({\n    NotIn: [key, values.map(encodeValue)],\n  }),\n  /** `attrs[key] < value` (same-type, orderable). */\n  lt: (key: string, value: AttrInput): Predicate => ({\n    Lt: [key, encodeValue(value)],\n  }),\n  /** `attrs[key] <= value` (same-type, orderable). */\n  le: (key: string, value: AttrInput): Predicate => ({\n    Le: [key, encodeValue(value)],\n  }),\n  /** `attrs[key] > value` (same-type, orderable). */\n  gt: (key: string, value: AttrInput): Predicate => ({\n    Gt: [key, encodeValue(value)],\n  }),\n  /** `attrs[key] >= value` (same-type, orderable). */\n  ge: (key: string, value: AttrInput): Predicate => ({\n    Ge: [key, encodeValue(value)],\n  }),\n  /** `attrs[key]` is a `List` containing `value` (whole-element, not substring). */\n  contains: (key: string, value: AttrInput): Predicate => ({\n    Contains: [key, encodeValue(value)],\n  }),\n  /** `attrs[key]` is a present `List` not containing `value`. */\n  notContains: (key: string, value: AttrInput): Predicate => ({\n    NotContains: [key, encodeValue(value)],\n  }),\n  /** `attrs[key]` is a `List` sharing at least one element with `values`. */\n  containsAny: (key: string, values: AttrInput[]): Predicate => ({\n    ContainsAny: [key, values.map(encodeValue)],\n  }),\n  /** Every sub-predicate holds. `all()` is `true`. */\n  all: (...preds: Predicate[]): Predicate => ({ All: preds }),\n  /** At least one sub-predicate holds. `any()` is `false`. */\n  any: (...preds: Predicate[]): Predicate => ({ Any: preds }),\n  /**\n   * The sub-predicate does not hold. Differs from {@link f.ne} on an absent key:\n   * `not(eq(k, v))` matches a record with no `k`, `ne(k, v)` does not.\n   */\n  not: (pred: Predicate): Predicate => ({ Not: pred }),\n  /**\n   * `attrs[key]` is within `maxEdits` Levenshtein edits of `text`, ASCII-case-folded on\n   * both sides; a `List` matches if any element does. The only three-element predicate.\n   * A `maxEdits` above 8 is refused by the server, not clamped.\n   */\n  fuzzy: (key: string, text: string, maxEdits: number): Predicate => ({\n    Fuzzy: [key, text, maxEdits],\n  }),\n  /**\n   * Every token of `text` appears among `attrs[key]`'s tokens, in any order. Tokens are\n   * ASCII-case-folded runs of alphanumerics; a `List` matches if any single element does.\n   */\n  containsAllTokens: (key: string, text: string): Predicate => ({\n    ContainsAllTokens: [key, text],\n  }),\n  /** At least one token of `text` appears among `attrs[key]`'s tokens. Empty never matches. */\n  containsAnyToken: (key: string, text: string): Predicate => ({\n    ContainsAnyToken: [key, text],\n  }),\n  /** `text`'s tokens appear consecutively and in order — a phrase match. */\n  containsTokenSequence: (key: string, text: string): Predicate => ({\n    ContainsTokenSequence: [key, text],\n  }),\n  /**\n   * `attrs[key]` matches the regular expression, **anchored at both ends** like\n   * {@link f.glob} — `.*` opts back into a substring search, and `(?i)` into case folding.\n   * The syntax is Rust's `regex`, not JS's: no backreferences and no lookaround.\n   */\n  regex: (key: string, pattern: string): Predicate => ({ Regex: [key, pattern] }),\n  /** Collect predicates into a {@link Filter} (purely sugar — they already AND). */\n  and: (...preds: Predicate[]): Filter => preds,\n} as const;\n\n// Aliases for the comparison operators, for callers who prefer them.\nexport type { Filter, Predicate, Value };\n"],"mappings":"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","names":["f"]}