{"version":3,"file":"cursor.cjs","sources":["../../../src/utils/cursor.ts"],"sourcesContent":["import {\n  and,\n  eq,\n  gt,\n  gte,\n  isNull,\n  isUndefined,\n  lt,\n  not,\n  or,\n} from '../query/builder/functions.js'\nimport { Value } from '../query/ir.js'\nimport type { BasicExpression, OrderBy, OrderByClause } from '../query/ir.js'\n\nfunction isNullish(\n  expression: OrderByClause[`expression`],\n): BasicExpression<boolean> {\n  return or(isNull(expression), isUndefined(expression))\n}\n\nfunction followsBoundary(\n  clause: OrderByClause,\n  value: unknown,\n): BasicExpression<boolean> {\n  const nullish = isNullish(clause.expression)\n  if (value == null) {\n    return clause.compareOptions.nulls === `first`\n      ? not(nullish)\n      : new Value(false)\n  }\n\n  const operator = clause.compareOptions.direction === `asc` ? gt : lt\n  const comparison = operator(clause.expression, new Value(value))\n  return clause.compareOptions.nulls === `last`\n    ? or(comparison, nullish)\n    : comparison\n}\n\n/** Build a single-column cursor; multi-column queries use prefix loading. */\nexport function buildCursor(\n  orderBy: OrderBy,\n  values: Array<unknown>,\n): BasicExpression<boolean> | undefined {\n  if (values.length === 0) return undefined\n  if (orderBy.length !== 1 || values.length !== 1) {\n    throw new Error(`Only single-column cursors are supported`)\n  }\n  return followsBoundary(orderBy[0]!, values[0])\n}\n\n/** Build the equality range that closes the first ordered boundary term. */\nexport function buildCursorCurrent(\n  orderBy: OrderBy,\n  values: ReadonlyArray<unknown>,\n): BasicExpression<boolean> | undefined {\n  const { expression } = orderBy[0] ?? {}\n  if (!expression || values.length === 0) return undefined\n  const value = values[0]\n  if (value == null) return isNullish(expression)\n  if (value instanceof Date) {\n    if (!Number.isFinite(value.getTime())) return undefined\n    return and(\n      gte(expression, new Value(value)),\n      lt(expression, new Value(new Date(value.getTime() + 1))),\n    )\n  }\n  if (typeof value === `object`) return undefined\n  return eq(expression, new Value(value))\n}\n\n/**\n * Whether the public predicate IR can express this boundary's comparison.\n * Unsupported values must use an unbounded fetch rather than a provider order\n * that may differ from the local comparator.\n */\nexport function canExpressCursorOrder(\n  orderBy: OrderBy,\n  values: ReadonlyArray<unknown>,\n): boolean {\n  if (orderBy.length !== 1 || values.length !== 1) return false\n  const value = values[0]\n  if (value == null) return false\n  if (value instanceof Date) return Number.isFinite(value.getTime())\n  if (typeof value === `string`) {\n    return orderBy[0]!.compareOptions.stringSort === `lexical`\n  }\n  return (\n    (typeof value === `number` && Number.isFinite(value)) ||\n    typeof value === `bigint` ||\n    typeof value === `boolean`\n  )\n}\n"],"names":["or","isNull","isUndefined","not","Value","gt","lt","and","gte","eq"],"mappings":";;;;AAcA,SAAS,UACP,YAC0B;AAC1B,SAAOA,UAAAA,GAAGC,UAAAA,OAAO,UAAU,GAAGC,UAAAA,YAAY,UAAU,CAAC;AACvD;AAEA,SAAS,gBACP,QACA,OAC0B;AAC1B,QAAM,UAAU,UAAU,OAAO,UAAU;AAC3C,MAAI,SAAS,MAAM;AACjB,WAAO,OAAO,eAAe,UAAU,UACnCC,UAAAA,IAAI,OAAO,IACX,IAAIC,GAAAA,MAAM,KAAK;AAAA,EACrB;AAEA,QAAM,WAAW,OAAO,eAAe,cAAc,QAAQC,UAAAA,KAAKC,UAAAA;AAClE,QAAM,aAAa,SAAS,OAAO,YAAY,IAAIF,GAAAA,MAAM,KAAK,CAAC;AAC/D,SAAO,OAAO,eAAe,UAAU,SACnCJ,aAAG,YAAY,OAAO,IACtB;AACN;AAGO,SAAS,YACd,SACA,QACsC;AACtC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,MAAI,QAAQ,WAAW,KAAK,OAAO,WAAW,GAAG;AAC/C,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,SAAO,gBAAgB,QAAQ,CAAC,GAAI,OAAO,CAAC,CAAC;AAC/C;AAGO,SAAS,mBACd,SACA,QACsC;AACtC,QAAM,EAAE,WAAA,IAAe,QAAQ,CAAC,KAAK,CAAA;AACrC,MAAI,CAAC,cAAc,OAAO,WAAW,EAAG,QAAO;AAC/C,QAAM,QAAQ,OAAO,CAAC;AACtB,MAAI,SAAS,KAAM,QAAO,UAAU,UAAU;AAC9C,MAAI,iBAAiB,MAAM;AACzB,QAAI,CAAC,OAAO,SAAS,MAAM,QAAA,CAAS,EAAG,QAAO;AAC9C,WAAOO,UAAAA;AAAAA,MACLC,UAAAA,IAAI,YAAY,IAAIJ,GAAAA,MAAM,KAAK,CAAC;AAAA,MAChCE,aAAG,YAAY,IAAIF,SAAM,IAAI,KAAK,MAAM,YAAY,CAAC,CAAC,CAAC;AAAA,IAAA;AAAA,EAE3D;AACA,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAOK,UAAAA,GAAG,YAAY,IAAIL,GAAAA,MAAM,KAAK,CAAC;AACxC;AAOO,SAAS,sBACd,SACA,QACS;AACT,MAAI,QAAQ,WAAW,KAAK,OAAO,WAAW,EAAG,QAAO;AACxD,QAAM,QAAQ,OAAO,CAAC;AACtB,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,iBAAiB,KAAM,QAAO,OAAO,SAAS,MAAM,SAAS;AACjE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,QAAQ,CAAC,EAAG,eAAe,eAAe;AAAA,EACnD;AACA,SACG,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KACnD,OAAO,UAAU,YACjB,OAAO,UAAU;AAErB;;;;"}