next-sanity
Version:
Sanity.io toolkit for Next.js
116 lines (115 loc) • 5.02 kB
JavaScript
import { t as isCorsOriginError } from "./isCorsOriginError.js";
import { n as defaultApiHost, t as cacheTagPrefix } from "./constants.js";
import { useRouter } from "next/navigation";
import { jsx } from "react/jsx-runtime";
import { createClient } from "@sanity/client";
import { startTransition, useEffect, useEffectEvent, useMemo, useState } from "react";
function RefreshOnInterval(props) {
const router = useRouter();
useEffect(() => {
const interval = setInterval(() => startTransition(() => router.refresh()), props.interval);
return () => clearInterval(interval);
}, [router, props.interval]);
return null;
}
RefreshOnInterval.displayName = "RefreshOnInterval";
function SanityLive(props) {
const { config, includeDrafts = false, requestTag, waitFor, action, onError = handleError, onWelcome = handleWelcome, onReconnect = handleReconnect, onRestart = "refresh", onGoAway = handleGoaway } = props;
const { projectId, dataset, apiHost = defaultApiHost, apiVersion, useProjectHostname = true, token, requestTagPrefix } = config;
const actionContext = {
includeDrafts,
waitFor
};
const client = useMemo(() => createClient({
projectId,
dataset,
apiHost,
apiVersion,
useProjectHostname,
ignoreBrowserTokenWarning: true,
token,
useCdn: false,
requestTagPrefix
}), [
apiHost,
apiVersion,
dataset,
projectId,
requestTagPrefix,
token,
useProjectHostname
]);
const [refreshOnInterval, setRefreshOnInterval] = useState(false);
const [error, setError] = useState();
if (error !== void 0) throw error;
const handleErrorEvent = useEffectEvent((error) => {
if (onError === "throw") setError(error);
else onError(error, actionContext);
});
const router = useRouter();
const handleLiveEvent = useEffectEvent((event) => {
switch (event.type) {
case "welcome":
startTransition(() => setRefreshOnInterval(false));
if (onWelcome) startTransition(() => onWelcome(event, actionContext));
break;
case "message":
startTransition(() => action === "refresh" ? router.refresh() : action(event.tags.map((tag) => `${cacheTagPrefix}${tag}`)).then((result) => {
if (result === "refresh") startTransition(() => router.refresh());
}));
break;
case "reconnect":
if (onReconnect) startTransition(() => onReconnect(event, actionContext));
break;
case "restart":
startTransition(() => setRefreshOnInterval(false));
if (onRestart) startTransition(() => onRestart === "refresh" ? router.refresh() : Promise.resolve(onRestart(event, actionContext)).then((result) => {
if (result === "refresh") startTransition(() => router.refresh());
}));
break;
case "goaway":
if (onGoAway) startTransition(() => onGoAway(event, actionContext, (interval) => startTransition(() => setRefreshOnInterval(interval))));
else if (!onGoAway) handleErrorEvent(new Error(`Sanity Live connection closed, automatic revalidation is disabled, the server gave this reason: ${event.reason}`, { cause: event }));
break;
default:
handleErrorEvent(new Error("Unknown live event type", { cause: event }));
break;
}
});
useEffect(() => {
const subscription = client.live.events({
includeDrafts,
tag: requestTag,
waitFor
}).subscribe({
next: handleLiveEvent,
error: handleErrorEvent
});
return () => subscription.unsubscribe();
}, [
client.live,
requestTag,
includeDrafts,
waitFor
]);
if (refreshOnInterval && Number.isFinite(refreshOnInterval) && refreshOnInterval > 0) return /* @__PURE__ */ jsx(RefreshOnInterval, { interval: refreshOnInterval });
return null;
}
SanityLive.displayName = "SanityLiveClientComponent";
const handleError = (error, _context) => {
if (isCorsOriginError(error)) console.warn(`Sanity Live is unable to connect to the Sanity API as the current origin - ${window.origin} - is not in the list of allowed CORS origins for this Sanity Project.`, error.addOriginUrl && `Add it here:`, error.addOriginUrl?.toString());
else console.error(error);
};
const handleWelcome = (_, { includeDrafts, waitFor }) => {
console.info(`<SanityLive${includeDrafts ? " includeDrafts" : ""}> is connected and listening for live events to ${includeDrafts ? "all content including drafts and version documents in content releases" : "published content"}.${waitFor === "function" ? " Events will be delayed until after a Sanity Function has processed them." : ""}`);
};
const handleReconnect = (_, { includeDrafts }) => {
console.error(`<SanityLive${includeDrafts ? " includeDrafts" : ""}> is attempting to reconnect`);
};
const handleGoaway = (event, { includeDrafts }, setLongPollingInterval) => {
const interval = 3e4;
console.warn(`<SanityLive${includeDrafts ? " includeDrafts" : ""}> connection is closed after receiving a 'goaway' event, the server gave this reason:`, JSON.stringify(event.reason), `Content will now be refreshed every ${interval / 1e3} seconds`);
setLongPollingInterval(interval);
};
export { SanityLive as default };
//# sourceMappingURL=SanityLive.js.map