UNPKG

@supabase-cache-helpers/postgrest-react-query

Version:

A collection of React Query utilities for working with Supabase.

615 lines (595 loc) 19 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/cache/use-delete-item.ts import { deleteItem } from "@supabase-cache-helpers/postgrest-core"; import { useQueryClient as useQueryClient3 } from "@tanstack/react-query"; import flatten from "flat"; // src/lib/use-postgrest-filter-cache.ts import { encodeObject, PostgrestFilter } from "@supabase-cache-helpers/postgrest-core"; import { useQueryClient } from "@tanstack/react-query"; var POSTGREST_FILTER_KEY_PREFIX = "postgrest-filter"; var usePostgrestFilterCache = () => { const queryClient = useQueryClient(); return (query, opts) => { const key = [ POSTGREST_FILTER_KEY_PREFIX, query, opts ? encodeObject(opts) : null ]; const cacheData = queryClient.getQueryData(key); if (cacheData instanceof PostgrestFilter) { return cacheData; } const filter = PostgrestFilter.fromQuery(query, opts); queryClient.setQueryData(key, filter); return filter; }; }; // src/lib/key.ts import { PostgrestParser, isPostgrestBuilder } from "@supabase-cache-helpers/postgrest-core"; var KEY_PREFIX = "postgrest"; var INFINITE_KEY_PREFIX = "page"; var encode = (key, isInfinite) => { var _a; if (!isPostgrestBuilder(key)) { throw new Error("Key is not a PostgrestBuilder"); } const parser = new PostgrestParser(key); return [ KEY_PREFIX, isInfinite ? INFINITE_KEY_PREFIX : "null", parser.schema, parser.table, parser.queryKey, (_a = parser.bodyKey) != null ? _a : "null", `count=${parser.count}`, `head=${parser.isHead}`, parser.orderByKey ]; }; var decode = (key) => { if (!Array.isArray(key)) return null; const [ prefix, infinitePrefix, schema, table, queryKey, bodyKey, count, head, orderByKey ] = key; if (prefix !== KEY_PREFIX) return null; const params = new URLSearchParams(queryKey); const limit = params.get("limit"); const offset = params.get("offset"); const countValue = count.replace("count=", ""); return { limit: limit ? Number(limit) : void 0, offset: offset ? Number(offset) : void 0, bodyKey, count: countValue === "null" ? null : countValue, isHead: head === "head=true", isInfinite: infinitePrefix === INFINITE_KEY_PREFIX, key, queryKey, schema, table, orderByKey }; }; // src/lib/use-queries-for-table-loader.ts import { useQueryClient as useQueryClient2 } from "@tanstack/react-query"; var useQueriesForTableLoader = (table) => { const queryClient = useQueryClient2(); const getPostgrestFilter = usePostgrestFilterCache(); return () => queryClient.getQueryCache().getAll().map((c) => c.queryKey).reduce( (prev, curr) => { const decodedKey = decode(curr); if ((decodedKey == null ? void 0 : decodedKey.table) === table) { prev.push(getPostgrestFilter(decodedKey.queryKey).params); } return prev; }, [] ); }; // src/cache/use-delete-item.ts function useDeleteItem(opts) { const queryClient = useQueryClient3(); const getPostgrestFilter = usePostgrestFilterCache(); return (input) => __async(this, null, function* () { return yield deleteItem( __spreadValues({ input: flatten(input) }, opts), { cacheKeys: queryClient.getQueryCache().getAll().map((c) => c.queryKey), getPostgrestFilter, revalidate: (key) => queryClient.invalidateQueries({ queryKey: key }), mutate: (key, fn) => { queryClient.setQueriesData({ queryKey: key }, fn); }, decode } ); }); } // src/cache/use-mutate-item.ts import { mutateItem } from "@supabase-cache-helpers/postgrest-core"; import { useQueryClient as useQueryClient4 } from "@tanstack/react-query"; import flatten2 from "flat"; function useMutateItem(opts) { const queryClient = useQueryClient4(); const getPostgrestFilter = usePostgrestFilterCache(); return (input, mutateFn) => __async(this, null, function* () { return yield mutateItem( __spreadValues({ input: flatten2(input), mutate: mutateFn }, opts), { cacheKeys: queryClient.getQueryCache().getAll().map((c) => c.queryKey), getPostgrestFilter, revalidate: (key) => queryClient.invalidateQueries({ queryKey: key }), mutate: (key, fn) => { queryClient.setQueriesData({ queryKey: key }, fn); }, decode } ); }); } // src/cache/use-upsert-item.ts import { upsertItem } from "@supabase-cache-helpers/postgrest-core"; import { useQueryClient as useQueryClient5 } from "@tanstack/react-query"; import flatten3 from "flat"; function useUpsertItem(opts) { const queryClient = useQueryClient5(); const getPostgrestFilter = usePostgrestFilterCache(); return (input) => __async(this, null, function* () { return yield upsertItem( __spreadValues({ input: flatten3(input) }, opts), { cacheKeys: queryClient.getQueryCache().getAll().map((c) => c.queryKey), getPostgrestFilter, revalidate: (key) => queryClient.invalidateQueries({ queryKey: key }), mutate: (key, fn) => { queryClient.setQueriesData({ queryKey: key }, fn); }, decode } ); }); } // src/mutate/use-delete-many-mutation.ts import { buildDeleteFetcher, getTable } from "@supabase-cache-helpers/postgrest-core"; import { useMutation } from "@tanstack/react-query"; function useDeleteManyMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader(getTable(qb)); const deleteItem2 = useDeleteItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: getTable(qb), schema: qb.schema })); return useMutation(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { const result = yield buildDeleteFetcher( qb, primaryKeys, __spreadValues({ query: query != null ? query : void 0, queriesForTable, disabled: opts == null ? void 0 : opts.disableAutoQuery }, opts) )(input); if (result) { for (const r of result) { deleteItem2(r.normalizedData); } } if (!result || result.every((r) => !r.userQueryData)) return null; return result.map((r) => r.userQueryData); }) }, opts)); } // src/mutate/use-delete-mutation.ts import { buildDeleteFetcher as buildDeleteFetcher2, getTable as getTable2 } from "@supabase-cache-helpers/postgrest-core"; import { useMutation as useMutation2 } from "@tanstack/react-query"; function useDeleteMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader(getTable2(qb)); const deleteItem2 = useDeleteItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: getTable2(qb), schema: qb.schema })); return useMutation2(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const r = yield buildDeleteFetcher2( qb, primaryKeys, __spreadValues({ query: query != null ? query : void 0, queriesForTable, disabled: opts == null ? void 0 : opts.disableAutoQuery }, opts) )([input]); if (!r) return null; const result = r[0]; if (result) { yield deleteItem2(result.normalizedData); } return (_a = result == null ? void 0 : result.userQueryData) != null ? _a : null; }) }, opts)); } // src/mutate/use-insert-mutation.ts import { buildInsertFetcher, getTable as getTable3 } from "@supabase-cache-helpers/postgrest-core"; import { useMutation as useMutation3 } from "@tanstack/react-query"; // src/mutate/get-user-response.ts function truthy(value) { return !!value; } var getUserResponse = (d) => { if (!d) return d; return d.map((r) => r.userQueryData).filter(truthy); }; // src/mutate/use-insert-mutation.ts function useInsertMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader(getTable3(qb)); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: getTable3(qb), schema: qb.schema })); return useMutation3(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const result = yield buildInsertFetcher( qb, __spreadValues({ query: query != null ? query : void 0, queriesForTable, disabled: opts == null ? void 0 : opts.disableAutoQuery }, opts) )(input); if (result) { yield Promise.all( result.map( (d) => __async(this, null, function* () { return yield upsertItem2(d.normalizedData); }) ) ); } return (_a = getUserResponse(result)) != null ? _a : null; }) }, opts)); } // src/mutate/use-update-mutation.ts import { buildUpdateFetcher, getTable as getTable4 } from "@supabase-cache-helpers/postgrest-core"; import { useMutation as useMutation4 } from "@tanstack/react-query"; function useUpdateMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader(getTable4(qb)); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: getTable4(qb), schema: qb.schema })); return useMutation4(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const result = yield buildUpdateFetcher( qb, primaryKeys, __spreadValues({ query: query != null ? query : void 0, queriesForTable, disabled: opts == null ? void 0 : opts.disableAutoQuery }, opts) )(input); if (result) { yield upsertItem2(result.normalizedData); } return (_a = result == null ? void 0 : result.userQueryData) != null ? _a : null; }) }, opts)); } // src/mutate/use-upsert-mutation.ts import { buildUpsertFetcher, getTable as getTable5 } from "@supabase-cache-helpers/postgrest-core"; import { useMutation as useMutation5 } from "@tanstack/react-query"; function useUpsertMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader(getTable5(qb)); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: getTable5(qb), schema: qb.schema })); return useMutation5(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const data = yield buildUpsertFetcher(qb, __spreadValues({ query: query != null ? query : void 0, queriesForTable, disabled: opts == null ? void 0 : opts.disableAutoQuery }, opts))(input); if (data) { yield Promise.all( data.map((d) => __async(this, null, function* () { return yield upsertItem2(d.normalizedData); })) ); } return (_a = getUserResponse(data)) != null ? _a : null; }) }, opts)); } // src/query/build-query-opts.ts import { isPostgrestBuilder as isPostgrestBuilder2, isPostgrestTransformBuilder } from "@supabase-cache-helpers/postgrest-core"; function buildQueryOpts(query, config) { return __spreadValues({ queryKey: encode(query, false), queryFn: (_0) => __async(this, [_0], function* ({ signal }) { if (isPostgrestTransformBuilder(query)) { query = query.abortSignal(signal); } if (isPostgrestBuilder2(query)) { query = query.throwOnError(); } return yield query; }) }, config); } // src/query/fetch.ts function fetchQuery(queryClient, query, config) { return __async(this, null, function* () { return yield queryClient.fetchQuery(buildQueryOpts(query, config)); }); } // src/query/prefetch.ts import { isPostgrestBuilder as isPostgrestBuilder3 } from "@supabase-cache-helpers/postgrest-core"; function prefetchQuery(queryClient, query, config) { return __async(this, null, function* () { yield queryClient.prefetchQuery( buildQueryOpts(query, config) ); }); } function fetchQueryInitialData(query) { return __async(this, null, function* () { if (!isPostgrestBuilder3(query)) { throw new Error("Query is not a PostgrestBuilder"); } return [encode(query, false), yield query.throwOnError()]; }); } // src/query/use-query.ts import { useQuery as useReactQuery } from "@tanstack/react-query"; function useQuery(query, config) { var _b; const _a = useReactQuery(buildQueryOpts(query, config)), { data } = _a, rest = __objRest(_a, ["data"]); return __spreadValues({ data: data == null ? void 0 : data.data, count: (_b = data == null ? void 0 : data.count) != null ? _b : null }, rest); } // src/subscribe/use-subscription-query.ts import { REALTIME_LISTEN_TYPES, REALTIME_POSTGRES_CHANGES_LISTEN_EVENT } from "@supabase/supabase-js"; import { buildNormalizedQuery, normalizeResponse } from "@supabase-cache-helpers/postgrest-core"; import { useEffect, useState } from "react"; function useSubscriptionQuery(client, channelName, filter, primaryKeys, query, opts) { const [status, setStatus] = useState(); const [channel, setChannel] = useState(); const queriesForTable = useQueriesForTableLoader(filter.table); const deleteItem2 = useDeleteItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: filter.table, schema: filter.schema })); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: filter.table, schema: filter.schema })); useEffect(() => { if (!client) return; const c = client.channel(channelName).on( REALTIME_LISTEN_TYPES.POSTGRES_CHANGES, filter, (payload) => __async(this, null, function* () { var _a; let data = (_a = payload.new) != null ? _a : payload.old; const selectQuery = buildNormalizedQuery({ queriesForTable, query }); if (payload.eventType !== REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.DELETE && selectQuery) { const qb = client.from(payload.table).select(selectQuery.selectQuery); for (const pk of primaryKeys) { qb.eq(pk.toString(), data[pk]); } const res = yield qb.single(); if (res.data) { data = normalizeResponse(selectQuery.groupedPaths, res.data); } } if (payload.eventType === REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.INSERT || payload.eventType === REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.UPDATE) { yield upsertItem2(data); } else if (payload.eventType === REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.DELETE) { yield deleteItem2(payload.old); } if (opts == null ? void 0 : opts.callback) { opts.callback(__spreadProps(__spreadValues({}, payload), { data })); } }) ).subscribe((status2) => setStatus(status2)); setChannel(c); return () => { if (c) c.unsubscribe(); }; }, []); return { channel, status }; } // src/subscribe/use-subscription.ts import { REALTIME_LISTEN_TYPES as REALTIME_LISTEN_TYPES2, REALTIME_POSTGRES_CHANGES_LISTEN_EVENT as REALTIME_POSTGRES_CHANGES_LISTEN_EVENT2 } from "@supabase/supabase-js"; import { useEffect as useEffect2, useState as useState2 } from "react"; function useSubscription(client, channelName, filter, primaryKeys, opts) { const [status, setStatus] = useState2(); const deleteItem2 = useDeleteItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: filter.table, schema: filter.schema })); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: filter.table, schema: filter.schema })); useEffect2(() => { if (!client) return; const c = client.channel(channelName).on( REALTIME_LISTEN_TYPES2.POSTGRES_CHANGES, filter, (payload) => __async(this, null, function* () { if (payload.eventType === REALTIME_POSTGRES_CHANGES_LISTEN_EVENT2.INSERT || payload.eventType === REALTIME_POSTGRES_CHANGES_LISTEN_EVENT2.UPDATE) { yield upsertItem2(payload.new); } else if (payload.eventType === REALTIME_POSTGRES_CHANGES_LISTEN_EVENT2.DELETE) { yield deleteItem2(payload.old); } if (opts == null ? void 0 : opts.callback) { opts.callback(__spreadValues({}, payload)); } }) ).subscribe((status2) => setStatus(status2)); return () => { if (c) c.unsubscribe(); }; }, []); return { status }; } export { INFINITE_KEY_PREFIX, KEY_PREFIX, POSTGREST_FILTER_KEY_PREFIX, buildQueryOpts, decode, encode, fetchQuery, fetchQueryInitialData, prefetchQuery, useDeleteItem, useDeleteManyMutation, useDeleteMutation, useInsertMutation, useMutateItem, usePostgrestFilterCache, useQueriesForTableLoader, useQuery, useSubscription, useSubscriptionQuery, useUpdateMutation, useUpsertItem, useUpsertMutation }; //# sourceMappingURL=index.mjs.map