UNPKG

groqd-playground

Version:

Groqd Playground is a plugin for Sanity Studio for testing [groqd](https://formidable.com/open-source/groqd/) queries, featuring:

759 lines (735 loc) 28.2 kB
import { __async, __spreadProps, __spreadValues } from "./chunk-JXPB73SY.mjs"; // src/PlaygroundWrapper.tsx import * as React6 from "react"; import { ToastProvider } from "@sanity/ui"; // src/components/Playground.tsx import * as React5 from "react"; import { useClient } from "sanity"; import { Box as Box5, Button as Button3, Card as Card2, Code, Flex as Flex2, Grid, Label as Label3, Select, Spinner, Stack as Stack4, Text as Text2, Tooltip as Tooltip2 } from "@sanity/ui"; import { z } from "zod"; import * as q from "groqd"; import has from "lodash.has"; import Split from "@uiw/react-split"; import { PlayIcon, ResetIcon } from "@sanity/icons"; // src/util/useDatasets.ts import * as React from "react"; var useDatasets = (client) => { const [datasets, setDatasets] = React.useState([]); React.useEffect(() => { const datasets$ = client.observable.datasets.list().subscribe({ next: (result) => setDatasets(result.map((ds) => ds.name)) }); return () => datasets$.unsubscribe(); }, []); return datasets; }; // src/consts.ts var STORAGE_KEYS = { DATASET: "__groqd_playground_dataset", API_VERSION: "__groqd_playground_api_version", CODE: "__groqd_playground_code", EDITOR_WIDTH: "__groqd_playground_editor_width" }; var API_VERSIONS = ["v1", "vX", "v2021-03-25", "v2021-10-21"]; var DEFAULT_API_VERSION = API_VERSIONS.at(-1); // src/components/ShareUrlField.tsx import * as React3 from "react"; import { Box, Button, Card, Flex, Label, Stack, Text, TextInput, Tooltip } from "@sanity/ui"; import { CopyIcon } from "@sanity/icons"; // src/util/copyDataToClipboard.ts import * as React2 from "react"; import { useToast } from "@sanity/ui"; var useCopyDataAndNotify = (message) => { const toast = useToast(); return React2.useCallback( (url2) => { navigator.clipboard.writeText(url2).then(() => { toast.push({ title: message }); }); }, [message] ); }; // src/components/ShareUrlField.tsx var ShareUrlField = ({ title, url: url2, column = 4, notificationMessage = "Copied URL to clipboard!" }) => { const copyUrl = useCopyDataAndNotify(notificationMessage); const handleCopyUrl = () => copyUrl(url2); return /* @__PURE__ */ React3.createElement(Box, { padding: 1, flex: 1, column }, /* @__PURE__ */ React3.createElement(Stack, null, /* @__PURE__ */ React3.createElement(Card, { paddingY: 2 }, /* @__PURE__ */ React3.createElement(Label, { muted: true }, title)), /* @__PURE__ */ React3.createElement(Flex, { flex: 1, gap: 1 }, /* @__PURE__ */ React3.createElement(Box, { flex: 1 }, /* @__PURE__ */ React3.createElement(TextInput, { readOnly: true, type: "url", value: url2 })), /* @__PURE__ */ React3.createElement( Tooltip, { content: /* @__PURE__ */ React3.createElement(Box, { padding: 2 }, /* @__PURE__ */ React3.createElement(Text, null, "Copy to clipboard")) }, /* @__PURE__ */ React3.createElement( Button, { "aria-label": "Copy to clipboard", type: "button", mode: "ghost", icon: CopyIcon, onClick: handleCopyUrl } ) )))); }; // src/util/messaging.ts var emitReset = (iframe, target) => { var _a2; (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage( JSON.stringify({ event: "RESET_CODE" }), target ); }; var emitInit = (source, target, payload) => { source.postMessage(JSON.stringify(__spreadValues({ event: "INIT" }, payload)), { targetOrigin: target }); }; // src/components/JSONExplorer.tsx import * as React4 from "react"; import { Box as Box3, Button as Button2, Stack as Stack3 } from "@sanity/ui"; // src/components/JSONExplorer.styled.tsx import styled from "styled-components"; import { Box as Box2, Stack as Stack2 } from "@sanity/ui"; var Root = styled(Box2)` font-family: Menlo, monospace; font-size: 0.9em; position: relative; height: 100%; --border-radius: 4px; --error-bg-color: #ffe5ea; --item-hover-color: #e7e7e7; @media (prefers-color-scheme: dark) { --error-bg-color: #470417; --item-hover-color: #505050; } `; var Label2 = styled.span` color: #9d1fcd; @media (prefers-color-scheme: dark) { color: #d05afc; } `; var Key = styled.span` color: #1e61cd; @media (prefers-color-scheme: dark) { color: #5998fc; } `; var Value = styled.span` color: #967e1c; @media (prefers-color-scheme: dark) { color: #dbb931; } `; var LineItem = styled(Box2)` padding-left: ${({ depth }) => depth * DEPTH_SC}px; border-radius: var(--border-radius); cursor: ${({ pointer }) => pointer ? "pointer" : "initial"}; background-color: ${({ hasError }) => hasError ? "var(--error-bg-color)" : "initial"}; &:hover { background-color: ${({ hasError }) => hasError ? void 0 : "var(--item-hover-color)"}; } `; var CollapsibleContainer = styled(Stack2)` border-radius: var(--border-radius); background-color: ${({ hasError }) => hasError ? "var(--error-bg-color)" : "initial"}; `; var ErrorMessageText = styled.div` font-weight: 400; `; var DEPTH_SC = 15; // src/components/JSONExplorer.tsx import { CopyIcon as CopyIcon2 } from "@sanity/icons"; // ../../shared/util/jsonExplorerUtils.ts var formatPrimitiveData = (data) => { if (typeof data === "string") return `"${data}"`; if (data instanceof Date) return `(Date) ${data}`; return String(data); }; var isObject = (data) => typeof data === "object" && data !== null && !Array.isArray(data) && !(data instanceof Date); var addToPath = (existingPath, newSegment) => existingPath ? `${existingPath}.${newSegment}` : newSegment; // src/components/JSONExplorer.tsx var JSONExplorer = (props) => { const copyUrl = useCopyDataAndNotify("Copied JSON to clipboard!"); const handleCopy = () => { try { copyUrl(JSON.stringify(props.data, null, 2)); } catch (e) { } }; return /* @__PURE__ */ React4.createElement(Root, { flex: 1 }, /* @__PURE__ */ React4.createElement( Box3, { padding: 3, style: { position: "absolute", inset: 0 }, overflow: "auto" }, /* @__PURE__ */ React4.createElement(JSONExplorerDisplay, __spreadValues({}, props)) ), /* @__PURE__ */ React4.createElement(Box3, { style: { position: "absolute", bottom: 0, right: 0 }, padding: 3 }, /* @__PURE__ */ React4.createElement( Button2, { "aria-label": "Copy to clipboard", type: "button", mode: "ghost", icon: CopyIcon2, text: "Copy to clipboard", onClick: handleCopy } ))); }; var JSONExplorerDisplay = ({ data, prefix, highlightedPaths, currentPath = "" }) => { const prefixDisplay = prefix !== void 0 ? /* @__PURE__ */ React4.createElement(Key, null, prefix, ": ") : null; const errorMessage = highlightedPaths && highlightedPaths.get(currentPath); const depth = currentPath === "" ? 0 : (currentPath == null ? void 0 : currentPath.split(".").length) || 0; if (Array.isArray(data)) { return /* @__PURE__ */ React4.createElement( Collapsible, { depth, title: /* @__PURE__ */ React4.createElement(React4.Fragment, null, prefixDisplay, /* @__PURE__ */ React4.createElement(Label2, null, "[...] ", data.length, " items")), errorMessage, id: `json-item-${currentPath}` }, /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, data.map((dat, i) => /* @__PURE__ */ React4.createElement( JSONExplorerDisplay, { data: dat, key: i, prefix: String(i), currentPath: addToPath(currentPath, String(i)), highlightedPaths } ))) ); } if (isObject(data)) { return /* @__PURE__ */ React4.createElement( Collapsible, { depth, title: /* @__PURE__ */ React4.createElement(React4.Fragment, null, prefixDisplay, /* @__PURE__ */ React4.createElement(Label2, null, `{...}`, " ", Object.keys(data).length, " properties")), errorMessage, id: `json-item-${currentPath}` }, /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, Object.entries(data).map(([key, dat]) => /* @__PURE__ */ React4.createElement( JSONExplorerDisplay, { data: dat, key, prefix: key, currentPath: addToPath(currentPath, key), highlightedPaths } ))) ); } return /* @__PURE__ */ React4.createElement( LineItem, { paddingY: 1, depth, hasError: !!errorMessage, id: `json-item-${currentPath}` }, /* @__PURE__ */ React4.createElement(Stack3, { space: 1 }, errorMessage && /* @__PURE__ */ React4.createElement(ErrorMessageText, null, errorMessage), /* @__PURE__ */ React4.createElement("div", null, prefixDisplay, /* @__PURE__ */ React4.createElement(Value, null, formatPrimitiveData(data)), " ")) ); }; var Collapsible = ({ title, depth, children, errorMessage, id }) => { const [isExpanded, setIsExpanded] = React4.useState(true); return /* @__PURE__ */ React4.createElement(CollapsibleContainer, { space: 2, id, hasError: !!errorMessage }, /* @__PURE__ */ React4.createElement( LineItem, { paddingY: 1, depth, onClick: () => setIsExpanded((v) => !v), pointer: true }, /* @__PURE__ */ React4.createElement(Stack3, { space: 1 }, errorMessage && /* @__PURE__ */ React4.createElement(ErrorMessageText, null, errorMessage), /* @__PURE__ */ React4.createElement(Box3, null, title)) ), /* @__PURE__ */ React4.createElement("div", { style: { height: isExpanded ? "auto" : 0, overflow: "hidden" } }, children)); }; // src/components/Playground.styled.tsx import styled2 from "styled-components"; import { Box as Box4 } from "@sanity/ui"; var ErrorLineItem = styled2(Box4)` border-radius: 4px; cursor: pointer; &:hover { background-color: #e7e7e7; } @media (prefers-color-scheme: dark) { &:hover { background-color: #505050; } } `; var CopyQueryButton = styled2.button` all: unset; cursor: pointer; &:focus { box-shadow: inset 0 0 0 1px var(--card-border-color), 0 0 0 1px #fff, 0 0 0 3px var(--card-focus-ring-color); border-radius: 0.1875rem; } `; // ../../shared/util/formatErrorPath.ts var formatErrorPath = (path) => path.split(".").reduce((acc, el) => { if (!NumReg.test(el)) { return `${acc}.${el}`; } return `${acc}[${el}]`; }, ""); var NumReg = /\d+/; // src/components/Playground.tsx function GroqdPlayground({ tool }) { var _a2; const [ { query, params, parsedResponse, fetchParseError, rawResponse, activeDataset, activeAPIVersion, queryUrl, isFetching, rawExecutionTime, errorPaths }, dispatch ] = React5.useReducer(reducer, null, () => { var _a3, _b; const activeDataset2 = localStorage.getItem(STORAGE_KEYS.DATASET) || ((_a3 = tool.options) == null ? void 0 : _a3.defaultDataset) || "production"; const activeAPIVersion2 = localStorage.getItem(STORAGE_KEYS.API_VERSION) || ((_b = tool.options) == null ? void 0 : _b.defaultApiVersion) || DEFAULT_API_VERSION; return { query: q.q(""), activeDataset: activeDataset2, activeAPIVersion: activeAPIVersion2, isFetching: false }; }); const iframeRef = React5.useRef(null); const editorContainer = React5.useRef(null); const editorInitialWidth = React5.useMemo( () => +(localStorage.getItem(STORAGE_KEYS.EDITOR_WIDTH) || 0) || EDITOR_INITIAL_WIDTH, [] ); const copyShareUrl = useCopyDataAndNotify("Copied share URL to clipboard!"); const copyQueryUrl = useCopyDataAndNotify("Copied Query to clipboard!"); const windowHref = window.location.href; const _client = useClient({ apiVersion: ((_a2 = tool.options) == null ? void 0 : _a2.defaultApiVersion) || "v2021-10-21" }); const client = React5.useMemo( () => _client.withConfig({ dataset: activeDataset, apiVersion: activeAPIVersion }), [_client, activeDataset, activeAPIVersion] ); const datasets = useDatasets(_client); const generateQueryUrl = (query2, params2) => { const searchParams = new URLSearchParams(); searchParams.append("query", query2.query); if (params2) { for (const [key, value] of Object.entries(params2)) searchParams.append(key, String(value)); } return client.getUrl( client.getDataUrl("query", "?" + searchParams.toString()) ); }; React5.useEffect(() => { if (datasets[0] && !datasets.includes(activeDataset)) handleDatasetChange(datasets[0]); }, [datasets]); const runQuery = React5.useMemo( () => q.makeSafeQueryRunner( (query2, params2) => new Promise((resolve, reject) => { client.observable.fetch(query2, params2, { filterResponse: false }).subscribe({ next: (res) => { dispatch({ type: "RAW_RESPONSE_RECEIVED", payload: { rawResponse: res.result, execTime: res.ms } }); resolve(res.result); }, error: (err) => { reject(err); } }); }) ), [client] ); const handleRun = (query2, params2) => __async(this, null, function* () { dispatch({ type: "MAKE_FETCH_REQUEST", payload: { queryUrl: generateQueryUrl(query2, params2) } }); try { const data = yield runQuery(query2, params2); dispatch({ type: "FETCH_RESPONSE_PARSED", payload: { parsedResponse: data } }); } catch (err) { let errorPaths2; if (err instanceof q.GroqdParseError) { errorPaths2 = /* @__PURE__ */ new Map(); for (const e of err.zodError.errors) { if (e.message === "Required" && !has(err.rawResponse, e.path)) { errorPaths2.set( e.path.slice(0, -1).map((v) => String(v)).join("."), `Field "${e.path.at(-1)}" is Required` ); } else { errorPaths2.set(e.path.map((v) => String(v)).join("."), e.message); } } } dispatch({ type: "FETCH_PARSE_FAILURE", payload: { fetchParseError: err, errorPaths: errorPaths2 } }); } }); React5.useEffect(() => { const handleMessage = (message) => { if (message.origin !== EDITOR_ORIGIN) return; try { const payload = messageSchema.parse(JSON.parse(message.data)); if (payload.event === "READY") { const storedCode = new URL(window.location.href).searchParams.get("code") || localStorage.getItem(STORAGE_KEYS.CODE); message.source && emitInit(message.source, EDITOR_ORIGIN, { code: storedCode || void 0, origin: window.location.origin }); } else if (payload.event === "INPUT") { localStorage.setItem(STORAGE_KEYS.CODE, payload.compressedRawCode); setQP("code", payload.compressedRawCode); if (payload.requestShareCopy) { copyShareUrl(window.location.href); } let playgroundRunQueryCount = 0; const libs = { groqd: q, playground: { runQuery: (query2, params2) => { playgroundRunQueryCount++; if (playgroundRunQueryCount > 1) return; try { if (query2 instanceof q.BaseQuery) { dispatch({ type: "INPUT_EVAL_SUCCESS", payload: { query: query2, params: params2 } }); if (payload.requestImmediateFetch) { handleRun(query2, params2); } } } catch (e) { } } } }; const scope = { exports: {}, require: (name) => libs[name] }; const keys = Object.keys(scope); new Function(...keys, payload.code)( ...keys.map((key) => scope[key]) ); } else if (payload.event === "ERROR") { console.error(payload.message); } } catch (e) { } }; window.addEventListener("message", handleMessage); return () => { window.removeEventListener("message", handleMessage); }; }, []); const handleDatasetChange = (datasetName) => { dispatch({ type: "SET_ACTIVE_DATASET", payload: { dataset: datasetName } }); }; const handleAPIVersionChange = (apiVersion) => { dispatch({ type: "SET_ACTIVE_API_VERSION", payload: { apiVersion } }); }; const handleReset = () => { iframeRef.current && emitReset(iframeRef.current, EDITOR_ORIGIN); }; const handleCopyQuery = () => query.query && copyQueryUrl(query.query); const handleEditorResize = () => { const container = editorContainer.current; if (!container) return; localStorage.setItem( STORAGE_KEYS.EDITOR_WIDTH, String(container.clientWidth) ); }; const responseView = (() => { if (isFetching) { return /* @__PURE__ */ React5.createElement(Flex2, { justify: "center", flex: 1, align: "center" }, /* @__PURE__ */ React5.createElement(Spinner, { muted: true })); } const execTimeDisplay = rawExecutionTime && /* @__PURE__ */ React5.createElement( Tooltip2, { placement: "right-end", content: /* @__PURE__ */ React5.createElement(Box5, { padding: 2 }, /* @__PURE__ */ React5.createElement(Text2, null, "Raw execution time of query")) }, /* @__PURE__ */ React5.createElement("span", null, " (", rawExecutionTime, "ms)") ); if (fetchParseError || (errorPaths == null ? void 0 : errorPaths.size)) { let errorView = null; const scrollToError = (path) => { const lineEl = document.getElementById(`json-item-${path}`); if (lineEl instanceof HTMLElement) lineEl.scrollIntoView({ behavior: "smooth", block: "start" }); }; if (errorPaths) { errorView = /* @__PURE__ */ React5.createElement(Stack4, { space: 2, flex: 1, paddingX: 3, paddingY: 1 }, /* @__PURE__ */ React5.createElement(Box5, { marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text2, { weight: "semibold", size: 1 }, "Error parsing:")), [...errorPaths.entries()].map(([path, message]) => /* @__PURE__ */ React5.createElement( ErrorLineItem, { key: path, onClick: () => scrollToError(path), padding: 1 }, /* @__PURE__ */ React5.createElement(Text2, { size: 2 }, "`result", formatErrorPath(path), "`: ", message) ))); } else if (fetchParseError instanceof Error) { errorView = /* @__PURE__ */ React5.createElement("pre", null, fetchParseError.message); } else { errorView = /* @__PURE__ */ React5.createElement("span", null, "Something went wrong..."); } return /* @__PURE__ */ React5.createElement(Flex2, { flex: 1, direction: "column" }, /* @__PURE__ */ React5.createElement(Split, { mode: "vertical" }, /* @__PURE__ */ React5.createElement(Flex2, { direction: "column", style: { maxHeight: 400 } }, /* @__PURE__ */ React5.createElement(Box5, { marginY: 3, paddingX: 3 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "\u2757Error")), /* @__PURE__ */ React5.createElement(Box5, { flex: 1, overflow: "auto" }, errorView)), /* @__PURE__ */ React5.createElement(Flex2, { flex: 1, direction: "column" }, /* @__PURE__ */ React5.createElement(Box5, { paddingX: 3, marginY: 3 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "Raw Response ", execTimeDisplay)), /* @__PURE__ */ React5.createElement(Box5, { flex: 1, style: { height: "100%" } }, /* @__PURE__ */ React5.createElement( JSONExplorer, { data: rawResponse, highlightedPaths: errorPaths } ))))); } return /* @__PURE__ */ React5.createElement(Flex2, { flex: 1, direction: "column", style: { maxHeight: "100%" } }, /* @__PURE__ */ React5.createElement(Box5, { padding: 3 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "Query Response ", execTimeDisplay)), parsedResponse ? /* @__PURE__ */ React5.createElement(JSONExplorer, { data: parsedResponse }) : null); })(); return /* @__PURE__ */ React5.createElement(Flex2, { style: { height: "100%" }, direction: "column" }, /* @__PURE__ */ React5.createElement(Card2, { paddingX: 3, paddingY: 2, borderBottom: true }, /* @__PURE__ */ React5.createElement(Grid, { columns: [6, 6, 12] }, /* @__PURE__ */ React5.createElement(Box5, { padding: 1, column: 2 }, /* @__PURE__ */ React5.createElement(Stack4, null, /* @__PURE__ */ React5.createElement(Card2, { paddingY: 2 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "Dataset")), /* @__PURE__ */ React5.createElement( Select, { value: activeDataset, onChange: (e) => handleDatasetChange(e.currentTarget.value) }, datasets.map((ds) => /* @__PURE__ */ React5.createElement("option", { key: ds }, ds)) ))), /* @__PURE__ */ React5.createElement(Box5, { padding: 1, column: 2 }, /* @__PURE__ */ React5.createElement(Stack4, null, /* @__PURE__ */ React5.createElement(Card2, { paddingY: 2 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "API Version")), /* @__PURE__ */ React5.createElement( Select, { value: activeAPIVersion, onChange: (e) => handleAPIVersionChange(e.currentTarget.value) }, API_VERSIONS.map((v) => /* @__PURE__ */ React5.createElement("option", { key: v }, v)) ))), /* @__PURE__ */ React5.createElement( ShareUrlField, { url: windowHref, title: "Share URL", column: queryUrl ? 4 : 8, notificationMessage: "Copied share URL to clipboard!" } ), queryUrl && /* @__PURE__ */ React5.createElement( ShareUrlField, { url: queryUrl, title: "Raw Query URL", notificationMessage: "Copied raw query URL to clipboard!" } ))), /* @__PURE__ */ React5.createElement(Box5, { flex: 1 }, /* @__PURE__ */ React5.createElement( Split, { style: { width: "100%", height: "100%", overflow: "hidden" }, onDragEnd: handleEditorResize }, /* @__PURE__ */ React5.createElement( "div", { style: { width: editorInitialWidth, minWidth: 200, height: "100%", display: "flex", flexDirection: "column" }, ref: editorContainer }, /* @__PURE__ */ React5.createElement("div", { style: { flex: 1, position: "relative" } }, /* @__PURE__ */ React5.createElement( "iframe", { src: EDITOR_URL, width: "100%", height: "100%", style: { border: "none" }, ref: iframeRef } ), /* @__PURE__ */ React5.createElement("div", { style: { position: "absolute", bottom: 12, left: 12 } }, /* @__PURE__ */ React5.createElement( Button3, { icon: ResetIcon, text: "Reset", mode: "ghost", onClick: handleReset } ))), /* @__PURE__ */ React5.createElement(Card2, { paddingTop: 3, paddingBottom: 3, borderTop: true }, /* @__PURE__ */ React5.createElement(Stack4, { space: 3 }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Box5, { paddingX: 3, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "Query", " ", query.query && /* @__PURE__ */ React5.createElement(CopyQueryButton, { onClick: handleCopyQuery, tabIndex: 0 }, "(Copy to clipboard)"))), /* @__PURE__ */ React5.createElement(Flex2, { padding: 3, paddingBottom: 4, overflow: "auto" }, /* @__PURE__ */ React5.createElement(Code, { language: "text" }, query.query), /* @__PURE__ */ React5.createElement(Box5, { width: 3 }))), params && Object.keys(params).length > 0 ? /* @__PURE__ */ React5.createElement(Box5, { paddingX: 3 }, /* @__PURE__ */ React5.createElement(Box5, { marginBottom: 3 }, /* @__PURE__ */ React5.createElement(Label3, { muted: true }, "Params")), /* @__PURE__ */ React5.createElement(Stack4, { space: 3, marginLeft: 3 }, Object.entries(params).map(([key, value]) => /* @__PURE__ */ React5.createElement(Text2, { key, size: 2, muted: true }, "$", key, ": ", value)))) : null)), /* @__PURE__ */ React5.createElement(Card2, { padding: 3, borderTop: true }, /* @__PURE__ */ React5.createElement( Button3, { tone: "primary", icon: PlayIcon, text: "Fetch", fontSize: [2], padding: [3], style: { width: "100%" }, onClick: () => handleRun(query, params), disabled: !query.query } )) ), /* @__PURE__ */ React5.createElement( Box5, { style: { width: `calc(100% - ${editorInitialWidth}px)`, minWidth: 100, display: "flex", flexDirection: "column" } }, /* @__PURE__ */ React5.createElement(Flex2, { flex: 1, direction: "column", overflow: "hidden" }, responseView) ) ))); } var _a; var EDITOR_URL = typeof process !== "undefined" && ((_a = process == null ? void 0 : process.env) == null ? void 0 : _a.SANITY_STUDIO_GROQD_PLAYGROUND_ENV) === "development" ? "http://localhost:3069" : "https://unpkg.com/groqd-playground-editor@0.0.6/build/index.html"; var EDITOR_ORIGIN = new URL(EDITOR_URL).origin; var reducer = (state, action) => { switch (action.type) { case "INPUT_EVAL_SUCCESS": return __spreadProps(__spreadValues({}, state), { query: action.payload.query, params: action.payload.params, inputParseError: void 0 }); case "INPUT_PARSE_FAILURE": return __spreadProps(__spreadValues({}, state), { inputParseError: action.payload.inputParseError }); case "MAKE_FETCH_REQUEST": return __spreadProps(__spreadValues({}, state), { isFetching: true, queryUrl: action.payload.queryUrl }); case "RAW_RESPONSE_RECEIVED": return __spreadProps(__spreadValues({}, state), { isFetching: false, rawResponse: action.payload.rawResponse, rawExecutionTime: action.payload.execTime }); case "FETCH_RESPONSE_PARSED": return __spreadProps(__spreadValues({}, state), { parsedResponse: action.payload.parsedResponse, fetchParseError: void 0, errorPaths: void 0 }); case "FETCH_PARSE_FAILURE": return __spreadProps(__spreadValues({}, state), { isFetching: false, fetchParseError: action.payload.fetchParseError, errorPaths: action.payload.errorPaths }); case "SET_ACTIVE_API_VERSION": localStorage.setItem(STORAGE_KEYS.API_VERSION, action.payload.apiVersion); return __spreadProps(__spreadValues({}, state), { activeAPIVersion: action.payload.apiVersion }); case "SET_ACTIVE_DATASET": localStorage.setItem(STORAGE_KEYS.DATASET, action.payload.dataset); return __spreadProps(__spreadValues({}, state), { activeDataset: action.payload.dataset }); default: return state; } }; var EDITOR_INITIAL_WIDTH = 500; var readySchema = z.object({ event: z.literal("READY") }); var inputSchema = z.object({ event: z.literal("INPUT"), compressedRawCode: z.string(), code: z.string(), requestImmediateFetch: z.boolean().optional().default(false), requestShareCopy: z.boolean().optional().default(false) }); var errorSchema = z.object({ event: z.literal("ERROR"), message: z.string() }); var messageSchema = z.union([inputSchema, errorSchema, readySchema]); var url = new URL(window.location.href); var setQP = (key, value) => { url.searchParams.set(key, value); window.history.replaceState(null, "", url); }; // src/PlaygroundWrapper.tsx function GroqdPlaygroundWrapper(props) { return /* @__PURE__ */ React6.createElement(ToastProvider, null, /* @__PURE__ */ React6.createElement(GroqdPlayground, __spreadValues({}, props))); } export { GroqdPlaygroundWrapper as default }; //# sourceMappingURL=PlaygroundWrapper-HYDTOGJO.mjs.map