UNPKG

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

Version:

A collection of React Query utilities for working with Supabase.

627 lines (606 loc) 22.3 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; 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 __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 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/index.ts var src_exports = {}; __export(src_exports, { INFINITE_KEY_PREFIX: () => INFINITE_KEY_PREFIX, KEY_PREFIX: () => KEY_PREFIX, POSTGREST_FILTER_KEY_PREFIX: () => POSTGREST_FILTER_KEY_PREFIX, buildQueryOpts: () => buildQueryOpts, decode: () => decode, encode: () => encode, fetchQuery: () => fetchQuery, fetchQueryInitialData: () => fetchQueryInitialData, prefetchQuery: () => prefetchQuery, useDeleteItem: () => useDeleteItem, useDeleteManyMutation: () => useDeleteManyMutation, useDeleteMutation: () => useDeleteMutation, useInsertMutation: () => useInsertMutation, useMutateItem: () => useMutateItem, usePostgrestFilterCache: () => usePostgrestFilterCache, useQueriesForTableLoader: () => useQueriesForTableLoader, useQuery: () => useQuery, useSubscription: () => useSubscription, useSubscriptionQuery: () => useSubscriptionQuery, useUpdateMutation: () => useUpdateMutation, useUpsertItem: () => useUpsertItem, useUpsertMutation: () => useUpsertMutation }); module.exports = __toCommonJS(src_exports); // src/cache/use-delete-item.ts var import_postgrest_core3 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query3 = require("@tanstack/react-query"); var import_flat = __toESM(require("flat")); // src/lib/use-postgrest-filter-cache.ts var import_postgrest_core = require("@supabase-cache-helpers/postgrest-core"); var import_react_query = require("@tanstack/react-query"); var POSTGREST_FILTER_KEY_PREFIX = "postgrest-filter"; var usePostgrestFilterCache = () => { const queryClient = (0, import_react_query.useQueryClient)(); return (query, opts) => { const key = [ POSTGREST_FILTER_KEY_PREFIX, query, opts ? (0, import_postgrest_core.encodeObject)(opts) : null ]; const cacheData = queryClient.getQueryData(key); if (cacheData instanceof import_postgrest_core.PostgrestFilter) { return cacheData; } const filter = import_postgrest_core.PostgrestFilter.fromQuery(query, opts); queryClient.setQueryData(key, filter); return filter; }; }; // src/lib/key.ts var import_postgrest_core2 = require("@supabase-cache-helpers/postgrest-core"); var KEY_PREFIX = "postgrest"; var INFINITE_KEY_PREFIX = "page"; var encode = (key, isInfinite) => { var _a; if (!(0, import_postgrest_core2.isPostgrestBuilder)(key)) { throw new Error("Key is not a PostgrestBuilder"); } const parser = new import_postgrest_core2.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 var import_react_query2 = require("@tanstack/react-query"); var useQueriesForTableLoader = (table) => { const queryClient = (0, import_react_query2.useQueryClient)(); 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 = (0, import_react_query3.useQueryClient)(); const getPostgrestFilter = usePostgrestFilterCache(); return (input) => __async(this, null, function* () { return yield (0, import_postgrest_core3.deleteItem)( __spreadValues({ input: (0, import_flat.default)(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 var import_postgrest_core4 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query4 = require("@tanstack/react-query"); var import_flat2 = __toESM(require("flat")); function useMutateItem(opts) { const queryClient = (0, import_react_query4.useQueryClient)(); const getPostgrestFilter = usePostgrestFilterCache(); return (input, mutateFn) => __async(this, null, function* () { return yield (0, import_postgrest_core4.mutateItem)( __spreadValues({ input: (0, import_flat2.default)(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 var import_postgrest_core5 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query5 = require("@tanstack/react-query"); var import_flat3 = __toESM(require("flat")); function useUpsertItem(opts) { const queryClient = (0, import_react_query5.useQueryClient)(); const getPostgrestFilter = usePostgrestFilterCache(); return (input) => __async(this, null, function* () { return yield (0, import_postgrest_core5.upsertItem)( __spreadValues({ input: (0, import_flat3.default)(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 var import_postgrest_core6 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query6 = require("@tanstack/react-query"); function useDeleteManyMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader((0, import_postgrest_core6.getTable)(qb)); const deleteItem2 = useDeleteItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: (0, import_postgrest_core6.getTable)(qb), schema: qb.schema })); return (0, import_react_query6.useMutation)(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { const result = yield (0, import_postgrest_core6.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 var import_postgrest_core7 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query7 = require("@tanstack/react-query"); function useDeleteMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader((0, import_postgrest_core7.getTable)(qb)); const deleteItem2 = useDeleteItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: (0, import_postgrest_core7.getTable)(qb), schema: qb.schema })); return (0, import_react_query7.useMutation)(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const r = yield (0, import_postgrest_core7.buildDeleteFetcher)( 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 var import_postgrest_core8 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query8 = require("@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((0, import_postgrest_core8.getTable)(qb)); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: (0, import_postgrest_core8.getTable)(qb), schema: qb.schema })); return (0, import_react_query8.useMutation)(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const result = yield (0, import_postgrest_core8.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 var import_postgrest_core9 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query9 = require("@tanstack/react-query"); function useUpdateMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader((0, import_postgrest_core9.getTable)(qb)); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: (0, import_postgrest_core9.getTable)(qb), schema: qb.schema })); return (0, import_react_query9.useMutation)(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const result = yield (0, import_postgrest_core9.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 var import_postgrest_core10 = require("@supabase-cache-helpers/postgrest-core"); var import_react_query10 = require("@tanstack/react-query"); function useUpsertMutation(qb, primaryKeys, query, opts) { const queriesForTable = useQueriesForTableLoader((0, import_postgrest_core10.getTable)(qb)); const upsertItem2 = useUpsertItem(__spreadProps(__spreadValues({}, opts), { primaryKeys, table: (0, import_postgrest_core10.getTable)(qb), schema: qb.schema })); return (0, import_react_query10.useMutation)(__spreadValues({ mutationFn: (input) => __async(this, null, function* () { var _a; const data = yield (0, import_postgrest_core10.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 var import_postgrest_core11 = require("@supabase-cache-helpers/postgrest-core"); function buildQueryOpts(query, config) { return __spreadValues({ queryKey: encode(query, false), queryFn: (_0) => __async(this, [_0], function* ({ signal }) { if ((0, import_postgrest_core11.isPostgrestTransformBuilder)(query)) { query = query.abortSignal(signal); } if ((0, import_postgrest_core11.isPostgrestBuilder)(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 var import_postgrest_core12 = require("@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 (!(0, import_postgrest_core12.isPostgrestBuilder)(query)) { throw new Error("Query is not a PostgrestBuilder"); } return [encode(query, false), yield query.throwOnError()]; }); } // src/query/use-query.ts var import_react_query11 = require("@tanstack/react-query"); function useQuery(query, config) { var _b; const _a = (0, import_react_query11.useQuery)(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 var import_supabase_js = require("@supabase/supabase-js"); var import_postgrest_core13 = require("@supabase-cache-helpers/postgrest-core"); var import_react = require("react"); function useSubscriptionQuery(client, channelName, filter, primaryKeys, query, opts) { const [status, setStatus] = (0, import_react.useState)(); const [channel, setChannel] = (0, import_react.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 })); (0, import_react.useEffect)(() => { if (!client) return; const c = client.channel(channelName).on( import_supabase_js.REALTIME_LISTEN_TYPES.POSTGRES_CHANGES, filter, (payload) => __async(this, null, function* () { var _a; let data = (_a = payload.new) != null ? _a : payload.old; const selectQuery = (0, import_postgrest_core13.buildNormalizedQuery)({ queriesForTable, query }); if (payload.eventType !== import_supabase_js.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 = (0, import_postgrest_core13.normalizeResponse)(selectQuery.groupedPaths, res.data); } } if (payload.eventType === import_supabase_js.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.INSERT || payload.eventType === import_supabase_js.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.UPDATE) { yield upsertItem2(data); } else if (payload.eventType === import_supabase_js.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 var import_supabase_js2 = require("@supabase/supabase-js"); var import_react2 = require("react"); function useSubscription(client, channelName, filter, primaryKeys, opts) { const [status, setStatus] = (0, import_react2.useState)(); 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 })); (0, import_react2.useEffect)(() => { if (!client) return; const c = client.channel(channelName).on( import_supabase_js2.REALTIME_LISTEN_TYPES.POSTGRES_CHANGES, filter, (payload) => __async(this, null, function* () { if (payload.eventType === import_supabase_js2.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.INSERT || payload.eventType === import_supabase_js2.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.UPDATE) { yield upsertItem2(payload.new); } else if (payload.eventType === import_supabase_js2.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT.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 }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { 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.js.map