{"version":3,"sources":["../src/index.react-server.ts","../src/query/prefetch.ts","../src/lib/constants.ts","../src/lib/create-key-getter.ts","../src/lib/parse-order-by.ts","../src/lib/encode.ts","../src/lib/middleware.ts","../src/lib/use-postgrest-filter-cache.ts","../src/lib/use-queries-for-table-loader.ts"],"sourcesContent":["// Server only flag in case other RSC compatible exports are added here later\nimport 'server-only';\n\nexport * from './query/prefetch';\n","import {\n  type AnyPostgrestResponse,\n  PostgrestParser,\n  isPostgrestBuilder,\n  offsetPaginationFetcher,\n  offsetPaginationHasMoreFetcher,\n} from '@supabase-cache-helpers/postgrest-core';\nimport type {\n  PostgrestMaybeSingleResponse,\n  PostgrestResponse,\n  PostgrestSingleResponse,\n  PostgrestTransformBuilder,\n} from '@supabase/postgrest-js';\nimport { GenericSchema } from '@supabase/postgrest-js/dist/cjs/types';\n\nimport { encode } from '../lib';\n\nfunction fetchQueryFallbackData<Result>(\n  query: PromiseLike<PostgrestSingleResponse<Result>>,\n): Promise<[string, PostgrestSingleResponse<Result>]>;\n\nfunction fetchQueryFallbackData<Result>(\n  query: PromiseLike<PostgrestMaybeSingleResponse<Result>>,\n): Promise<[string, PostgrestMaybeSingleResponse<Result>]>;\n\nfunction fetchQueryFallbackData<Result>(\n  query: PromiseLike<PostgrestResponse<Result>>,\n): Promise<[string, PostgrestResponse<Result>]>;\n\nasync function fetchQueryFallbackData<Result>(\n  query: PromiseLike<AnyPostgrestResponse<Result>>,\n): Promise<[string, AnyPostgrestResponse<Result>]> {\n  if (!isPostgrestBuilder<Result>(query)) {\n    throw new Error('Query is not a PostgrestBuilder');\n  }\n\n  return [\n    encode(new PostgrestParser<Result>(query), false),\n    await query.throwOnError(),\n  ];\n}\n\nasync function fetchOffsetPaginationHasMoreFallbackData<\n  Schema extends GenericSchema,\n  Table extends Record<string, unknown>,\n  Result extends Record<string, unknown>,\n  RelationName = unknown,\n  Relationships = unknown,\n>(\n  query: PostgrestTransformBuilder<\n    Schema,\n    Table,\n    Result[],\n    RelationName,\n    Relationships\n  >,\n  pageSize: number,\n): Promise<\n  [\n    string,\n    [\n      {\n        data: Result[];\n        hasMore: boolean;\n      },\n    ],\n  ]\n> {\n  return [\n    encode(new PostgrestParser<Result[]>(query.range(0, pageSize)), true),\n    [\n      await offsetPaginationHasMoreFetcher(query, {\n        offset: 0,\n        limit: pageSize,\n        pageSize,\n      }),\n    ],\n  ];\n}\n\nconst fetchOffsetPaginationFallbackData = async <\n  Schema extends GenericSchema,\n  Table extends Record<string, unknown>,\n  Result extends Record<string, unknown>,\n  RelationName = unknown,\n  Relationships = unknown,\n>(\n  query: PostgrestTransformBuilder<\n    Schema,\n    Table,\n    Result[],\n    RelationName,\n    Relationships\n  >,\n  pageSize: number,\n): Promise<[string, [Result[]]]> => {\n  return [\n    encode(new PostgrestParser<Result[]>(query.range(0, pageSize)), true),\n    [\n      await offsetPaginationFetcher(query, {\n        offset: 0,\n        limit: pageSize,\n      }),\n    ],\n  ];\n};\n\nexport {\n  fetchQueryFallbackData,\n  fetchOffsetPaginationHasMoreFallbackData,\n  fetchOffsetPaginationFallbackData,\n};\n","export const KEY_PREFIX = 'postgrest';\nexport const POSTGREST_FILTER_KEY_PREFIX = 'postgrest-filter';\nexport const KEY_SEPARATOR = '$';\nexport const INFINITE_PREFIX = '$inf$';\nexport const INFINITE_KEY_PREFIX = 'page';\n","import {\n  type PostgrestHasMorePaginationResponse,\n  type PostgrestPaginationResponse,\n  get,\n  isPlainObject,\n  isPostgrestHasMorePaginationResponse,\n  isPostgrestPaginationResponse,\n} from '@supabase-cache-helpers/postgrest-core';\nimport type { PostgrestTransformBuilder } from '@supabase/postgrest-js';\nimport { GenericSchema } from '@supabase/postgrest-js/dist/cjs/types';\nimport { parseOrderBy } from './parse-order-by';\n\nexport const createOffsetKeyGetter = <\n  Schema extends GenericSchema,\n  Table extends Record<string, unknown>,\n  Result,\n>(\n  queryFactory: (() => PostgrestTransformBuilder<Schema, Table, Result>) | null,\n  {\n    pageSize,\n    rpcArgs,\n  }: {\n    pageSize: number;\n    rpcArgs?: { limit: string; offset: string };\n  },\n) => {\n  if (!queryFactory) return () => null;\n  return (\n    pageIndex: number,\n    previousPageData: (\n      | PostgrestHasMorePaginationResponse<Result>\n      | PostgrestPaginationResponse<Result>\n    )[],\n  ) => {\n    if (\n      previousPageData &&\n      ((isPostgrestHasMorePaginationResponse(previousPageData) &&\n        !previousPageData.data.length) ||\n        (isPostgrestPaginationResponse(previousPageData) &&\n          !previousPageData.length))\n    ) {\n      return null;\n    }\n    const cursor = pageIndex * pageSize;\n\n    const query = queryFactory();\n\n    if (rpcArgs) {\n      if (query['method'] === 'GET') {\n        query['url'].searchParams.set(rpcArgs.limit, String(pageSize));\n        query['url'].searchParams.set(rpcArgs.offset, String(cursor));\n      } else {\n        query['body'] = {\n          ...(isPlainObject(query['body']) ? query['body'] : {}),\n          [rpcArgs.limit]: pageSize,\n          [rpcArgs.offset]: cursor,\n        };\n      }\n\n      return query;\n    }\n\n    return query.range(cursor, cursor + pageSize - 1);\n  };\n};\n\nexport const createCursorKeyGetter = <\n  Schema extends GenericSchema,\n  Table extends Record<string, unknown>,\n  Result,\n>(\n  queryFactory: (() => PostgrestTransformBuilder<Schema, Table, Result>) | null,\n  {\n    orderBy,\n    uqOrderBy: uqColumn,\n    rpcArgs,\n  }: {\n    orderBy: string;\n    uqOrderBy?: string;\n    rpcArgs?: { orderBy: string; uqOrderBy?: string };\n  },\n) => {\n  if (!queryFactory) return () => null;\n\n  return (\n    _pageIndex: number,\n    previousPageData: (\n      | PostgrestHasMorePaginationResponse<Result>\n      | PostgrestPaginationResponse<Result>\n    )[],\n  ) => {\n    // Return null if we've reached the end of the data\n    if (previousPageData && isEmptyPreviousPage(previousPageData)) {\n      return null;\n    }\n\n    const query = queryFactory();\n\n    // If this is the first page, return the original query\n    if (!previousPageData) return query;\n\n    // Extract the last values for cursor-based pagination\n    const lastItem = getLastItem(previousPageData);\n\n    if (!lastItem) return query;\n\n    const lastValueOrderBy = get(lastItem, orderBy);\n    if (!lastValueOrderBy) return query;\n\n    const lastValueUqColumn = uqColumn ? get(lastItem, uqColumn) : null;\n\n    if (rpcArgs) {\n      if (query['method'] === 'GET') {\n        if (lastValueOrderBy) {\n          query['url'].searchParams.set(rpcArgs.orderBy, lastValueOrderBy);\n        }\n        if (lastValueUqColumn && rpcArgs.uqOrderBy) {\n          query['url'].searchParams.set(rpcArgs.uqOrderBy, lastValueUqColumn);\n        }\n      } else {\n        query['body'] = {\n          ...(isPlainObject(query['body']) ? query['body'] : {}),\n          [rpcArgs.orderBy]: lastValueOrderBy,\n          ...(lastValueUqColumn && rpcArgs.uqOrderBy\n            ? { [rpcArgs.uqOrderBy]: lastValueUqColumn }\n            : {}),\n        };\n      }\n\n      return query;\n    }\n\n    const { orderBy: mainOrderBy, uqOrderBy } = parseOrderBy(\n      query['url'].searchParams,\n      { orderByPath: orderBy, uqOrderByPath: uqColumn },\n    );\n\n    // Apply cursor filters\n    if (uqColumn && uqOrderBy && lastValueOrderBy && lastValueUqColumn) {\n      const operator = mainOrderBy.ascending ? 'gt' : 'lt';\n      const uqOperator = uqOrderBy.ascending ? 'gt' : 'lt';\n\n      query['url'].searchParams.append(\n        'or',\n        `(${orderBy}.${operator}.${lastValueOrderBy},and(${orderBy}.eq.${lastValueOrderBy},${uqColumn}.${uqOperator}.${lastValueUqColumn}))`,\n      );\n    } else if (lastValueOrderBy) {\n      const operator = mainOrderBy.ascending ? 'gt' : 'lt';\n      query['url'].searchParams.append(\n        orderBy,\n        `${operator}.${lastValueOrderBy}`,\n      );\n    }\n\n    return query;\n  };\n};\n\n// Helper functions\nfunction isEmptyPreviousPage<Result>(\n  previousPageData: (\n    | PostgrestHasMorePaginationResponse<Result>\n    | PostgrestPaginationResponse<Result>\n  )[],\n): boolean {\n  return (\n    (isPostgrestHasMorePaginationResponse(previousPageData) &&\n      !previousPageData.data.length) ||\n    (isPostgrestPaginationResponse(previousPageData) &&\n      !previousPageData.length)\n  );\n}\n\nfunction getLastItem<Result>(\n  data: (\n    | PostgrestHasMorePaginationResponse<Result>\n    | PostgrestPaginationResponse<Result>\n  )[],\n): Result | null {\n  if (isPostgrestHasMorePaginationResponse(data)) {\n    return data.data.length\n      ? (data.data[data.data.length - 1] as Result)\n      : null;\n  } else if (isPostgrestPaginationResponse(data)) {\n    return data.length ? (data[data.length - 1] as Result) : null;\n  }\n  return null;\n}\n","import { parseOrderBy as core } from '@supabase-cache-helpers/postgrest-core';\n\nexport function parseOrderBy(\n  searchParams: URLSearchParams,\n  {\n    orderByPath,\n    uqOrderByPath,\n  }: { orderByPath: string; uqOrderByPath?: string },\n) {\n  const orderByDef = core(searchParams);\n  const orderBy = orderByDef.find((o) => o.column === orderByPath);\n\n  if (!orderBy) {\n    throw new Error(`No ordering key found for path ${orderByPath}`);\n  }\n\n  const uqOrderBy = uqOrderByPath\n    ? orderByDef.find((o) => o.column === uqOrderByPath)\n    : null;\n\n  return {\n    orderBy,\n    uqOrderBy,\n  };\n}\n","import type { PostgrestParser } from '@supabase-cache-helpers/postgrest-core';\n\nimport { INFINITE_KEY_PREFIX, KEY_PREFIX, KEY_SEPARATOR } from './constants';\n\nexport const encode = <Result>(\n  parser: PostgrestParser<Result>,\n  isInfinite: boolean,\n) => {\n  return [\n    KEY_PREFIX,\n    isInfinite ? INFINITE_KEY_PREFIX : 'null',\n    parser.schema,\n    parser.table,\n    parser.queryKey,\n    parser.bodyKey ?? 'null',\n    `count=${parser.count}`,\n    `head=${parser.isHead}`,\n    parser.orderByKey,\n  ].join(KEY_SEPARATOR);\n};\n","import {\n  PostgrestParser,\n  isPostgrestBuilder,\n} from '@supabase-cache-helpers/postgrest-core';\nimport type {\n  SWRInfiniteConfiguration,\n  SWRInfiniteFetcher,\n  SWRInfiniteHook,\n  SWRInfiniteKeyLoader,\n} from 'swr/infinite';\n\nimport { encode } from './encode';\n\nexport const infiniteMiddleware = <Result>(\n  useSWRInfiniteNext: SWRInfiniteHook,\n) => {\n  return (\n    keyFn: SWRInfiniteKeyLoader,\n    fetcher: SWRInfiniteFetcher,\n    config: SWRInfiniteConfiguration,\n  ) => {\n    return useSWRInfiniteNext(\n      (index, previousPageData) => {\n        // todo use type guard\n        const query = keyFn(index, previousPageData);\n        if (!query) return null;\n        if (!isPostgrestBuilder<Result>(query)) {\n          throw new Error('Key is not a PostgrestBuilder');\n        }\n\n        return encode(new PostgrestParser<Result>(query), true);\n      },\n      typeof fetcher === 'function' ? (query) => fetcher(query) : fetcher,\n      config,\n    );\n  };\n};\n","import {\n  PostgrestFilter,\n  type PostgrestQueryParserOptions,\n  encodeObject,\n} from '@supabase-cache-helpers/postgrest-core';\nimport { useSWRConfig } from 'swr';\n\nimport { KEY_SEPARATOR, POSTGREST_FILTER_KEY_PREFIX } from './constants';\n\nexport const usePostgrestFilterCache = <\n  R extends Record<string, unknown>,\n>() => {\n  const { cache } = useSWRConfig();\n\n  return (query: string, opts?: PostgrestQueryParserOptions) => {\n    const key = [\n      POSTGREST_FILTER_KEY_PREFIX,\n      query,\n      opts ? encodeObject(opts) : null,\n    ]\n      .filter(Boolean)\n      .join(KEY_SEPARATOR);\n    const cacheData = cache.get(key);\n    if (cacheData && cacheData.data instanceof PostgrestFilter) {\n      return cacheData.data;\n    }\n    const filter = PostgrestFilter.fromQuery(query, opts);\n    cache.set(key, { data: filter });\n    return filter as PostgrestFilter<R>;\n  };\n};\n","import type { BuildNormalizedQueryOps } from '@supabase-cache-helpers/postgrest-core';\nimport { useSWRConfig } from 'swr';\n\nimport { decode } from './decode';\nimport { usePostgrestFilterCache } from './use-postgrest-filter-cache';\n\nexport const useQueriesForTableLoader = (table: string) => {\n  const { cache } = useSWRConfig();\n  const getPostgrestFilter = usePostgrestFilterCache();\n\n  return () =>\n    Array.from(cache.keys()).reduce<\n      ReturnType<BuildNormalizedQueryOps['queriesForTable']>\n    >((prev, curr) => {\n      const decodedKey = decode(curr);\n      if (decodedKey?.table === table) {\n        prev.push(getPostgrestFilter(decodedKey.queryKey).params);\n      }\n      return prev;\n    }, []);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,yBAAO;;;ACDP,IAAAA,yBAMO;;;ACNA,IAAM,aAAa;AAEnB,IAAM,gBAAgB;AAEtB,IAAM,sBAAsB;;;ACJnC,IAAAC,yBAOO;;;ACPP,4BAAqC;;;ACI9B,IAAM,SAAS,CACpB,QACA,eACG;AAPL;AAQE,SAAO;AAAA,IACL;AAAA,IACA,aAAa,sBAAsB;AAAA,IACnC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,KACP,YAAO,YAAP,YAAkB;AAAA,IAClB,SAAS,OAAO,KAAK;AAAA,IACrB,QAAQ,OAAO,MAAM;AAAA,IACrB,OAAO;AAAA,EACT,EAAE,KAAK,aAAa;AACtB;;;ACnBA,IAAAC,yBAGO;;;ACHP,IAAAC,yBAIO;AACP,iBAA6B;;;ACJ7B,IAAAC,cAA6B;;;AP4B7B,SAAe,uBACb,OACiD;AAAA;AACjD,QAAI,KAAC,2CAA2B,KAAK,GAAG;AACtC,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,WAAO;AAAA,MACL,OAAO,IAAI,uCAAwB,KAAK,GAAG,KAAK;AAAA,MAChD,MAAM,MAAM,aAAa;AAAA,IAC3B;AAAA,EACF;AAAA;AAEA,SAAe,yCAOb,OAOA,UAWA;AAAA;AACA,WAAO;AAAA,MACL,OAAO,IAAI,uCAA0B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI;AAAA,MACpE;AAAA,QACE,UAAM,uDAA+B,OAAO;AAAA,UAC1C,QAAQ;AAAA,UACR,OAAO;AAAA,UACP;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAEA,IAAM,oCAAoC,CAOxC,OAOA,aACkC;AAClC,SAAO;AAAA,IACL,OAAO,IAAI,uCAA0B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI;AAAA,IACpE;AAAA,MACE,UAAM,gDAAwB,OAAO;AAAA,QACnC,QAAQ;AAAA,QACR,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["import_postgrest_core","import_postgrest_core","import_postgrest_core","import_postgrest_core","import_swr"]}