@supabase-cache-helpers/postgrest-react-query
Version:
A collection of React Query utilities for working with Supabase.
615 lines (595 loc) • 19 kB
JavaScript
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