{"version":3,"sources":["../../src/list/source.ts"],"sourcesContent":["/** Read a matching source to its declared end; a transport cap is never a complete list. */\nexport async function readCompleteSource<T>({ readPage, getRowId, pageSize = 200, maxRows = Number.POSITIVE_INFINITY }: {\n  readPage: (page: number, pageSize: number) => Promise<{ rows: T[]; total: number }>;\n  getRowId: (row: T) => string;\n  pageSize?: number;\n  maxRows?: number;\n}): Promise<{ rows: T[]; total: number }> {\n  if(!Number.isSafeInteger(pageSize)||pageSize<1||(!(maxRows===Number.POSITIVE_INFINITY)&&(!Number.isSafeInteger(maxRows)||maxRows<0))) throw new Error(\"The complete-source read options are invalid.\");\n  const rows: T[] = [];\n  const ids = new Set<string>();\n  let total: number | undefined;\n  for (let page = 1; ; page++) {\n    const answer = await readPage(page, pageSize);\n    if (!Number.isSafeInteger(answer.total) || answer.total < 0 || (total !== undefined && answer.total !== total)) {\n      throw new Error(\"The list changed while loading. Refresh before grouping or summarizing it.\");\n    }\n    total = answer.total;\n    if(total>maxRows) throw new Error(`This list has ${total.toLocaleString()} matches. Narrow the filters to ${maxRows.toLocaleString()} or fewer before grouping locally.`);\n    for (const row of answer.rows) {\n      const id = getRowId(row);\n      if (ids.has(id)) throw new Error(\"The source repeated records before the list was complete.\");\n      ids.add(id); rows.push(row);\n    }\n    if (rows.length === total) return { rows, total };\n    if (rows.length > total || answer.rows.length !== pageSize) {\n      throw new Error(\"The source did not return its complete matching list.\");\n    }\n  }\n}\n\n/** Source summaries are single aggregate rows, validated before becoming KPI values. */\nexport const USAGE_SUMMARY_KEYS = [\"items\", \"runs\", \"successes\", \"failures\", \"cost\"] as const;\nexport interface SummaryRpcClient { rpc(name: string, args: object): unknown }\nconst record = (value: unknown): value is Record<string, unknown> => !!value && typeof value === \"object\" && !Array.isArray(value);\nexport async function readNumericSourceSummary<K extends string>(client: SummaryRpcClient, name: string, args: object, keys: readonly K[]): Promise<Record<K, number>> {\n  const response: unknown = await client.rpc(name, args);\n  if (!record(response)) throw new Error(\"The source did not return its summary.\");\n  if (response.error) throw Object.assign(new Error(record(response.error) && typeof response.error.message === \"string\" ? response.error.message : \"The source summary failed.\"), response.error);\n  const rows = response.data;\n  if (!Array.isArray(rows) || rows.length !== 1 || !record(rows[0])) throw new Error(\"The source did not return one complete summary.\");\n  const row = rows[0];\n  return Object.fromEntries(keys.map(key => {\n    const value = row[key];\n    const number = typeof value === \"number\" || (typeof value === \"string\" && value.trim() !== \"\") ? Number(value) : NaN;\n    if (!Number.isFinite(number)) throw new Error(`The source summary did not measure ${key}.`);\n    return [key, number];\n  })) as Record<K, number>;\n}\n\n/** The configured global ceiling has no organization or user overrides. */\nexport function tableGroupingLimit(value:unknown):number {\n  if((typeof value!==\"number\"&&typeof value!==\"string\")||!Number.isSafeInteger(Number(value))||Number(value)<1) throw new Error(\"The table grouping limit could not be read.\");\n  return Number(value);\n}\nconst groupingLimits=new WeakMap<SummaryRpcClient,{at:number;read:Promise<number>}>();\n/** Standalone hosts share a cached bucket read through the canonical knob-defaults protocol. */\nexport function readTableGroupingLimit(client:SummaryRpcClient):Promise<number>{\n  const held=groupingLimits.get(client);if(held&&Date.now()-held.at<60000)return held.read;\n  const key=\"lists.table_group_rows_ceiling\";\n  const read=(async()=>{\n    const {emptyKnobDefaults,knobDefaultsFromKeysAnswer}=await import(\"@ai-matrx/data/knobs\");\n    const response:unknown=await client.rpc(\"knob_defaults_for_keys\",{p_keys:[key],p_known_version:null});\n    if(!record(response))throw new Error(\"The table settings could not be read.\");\n    if(record(response.error)&&typeof response.error.message===\"string\")throw new Error(response.error.message);\n    if(response.error||!record(response.data))throw new Error(\"The table settings could not be read.\");\n    const answer=knobDefaultsFromKeysAnswer(emptyKnobDefaults(),null,response.data as Parameters<typeof knobDefaultsFromKeysAnswer>[2]);\n    return tableGroupingLimit(answer.defaults?.values[key]);\n  })();\n  groupingLimits.set(client,{at:Date.now(),read});\n  void read.catch(()=>{if(groupingLimits.get(client)?.read===read)groupingLimits.delete(client);});\n  return read;\n}\n"],"mappings":"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","names":[]}