@upstash/react-redis-browser 0.1.2-canary-6 → 0.1.2-canary-8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +4 -0
- package/dist/index.js +88 -54
- package/dist/index.mjs +88 -54
- package/package.json +1 -1
package/dist/index.css
CHANGED
package/dist/index.js
CHANGED
|
@@ -222,6 +222,20 @@ var _iconsreact = require('@tabler/icons-react');
|
|
|
222
222
|
|
|
223
223
|
var _reactresizablepanels = require('react-resizable-panels');
|
|
224
224
|
|
|
225
|
+
// src/components/ui/toaster.tsx
|
|
226
|
+
var _reactportal = require('@radix-ui/react-portal');
|
|
227
|
+
|
|
228
|
+
// src/lib/portal-root.ts
|
|
229
|
+
var root;
|
|
230
|
+
if (typeof document !== "undefined") {
|
|
231
|
+
const id = "react-redis-browser-portal-root";
|
|
232
|
+
root = _nullishCoalesce(document.querySelector(`#${id}`), () => ( document.createElement("div")));
|
|
233
|
+
root.classList.add("ups-db");
|
|
234
|
+
root.id = "react-redis-browser-portal-root";
|
|
235
|
+
document.body.append(root);
|
|
236
|
+
}
|
|
237
|
+
var portalRoot = root;
|
|
238
|
+
|
|
225
239
|
// src/components/ui/toast.tsx
|
|
226
240
|
|
|
227
241
|
var _reacticons = require('@radix-ui/react-icons');
|
|
@@ -2874,7 +2888,7 @@ ToastDescription.displayName = ToastPrimitives.Description.displayName;
|
|
|
2874
2888
|
|
|
2875
2889
|
function Toaster() {
|
|
2876
2890
|
const { toasts } = useToast();
|
|
2877
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, ToastProvider, { children: [
|
|
2891
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactportal.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, ToastProvider, { children: [
|
|
2878
2892
|
toasts.map(({ id, title, description, action, ...props }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Toast, { ...props, children: [
|
|
2879
2893
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid gap-1", children: [
|
|
2880
2894
|
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ToastTitle, { children: title }),
|
|
@@ -2884,7 +2898,7 @@ function Toaster() {
|
|
|
2884
2898
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ToastClose, {})
|
|
2885
2899
|
] }, id)),
|
|
2886
2900
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ToastViewport, {})
|
|
2887
|
-
] });
|
|
2901
|
+
] }) });
|
|
2888
2902
|
}
|
|
2889
2903
|
|
|
2890
2904
|
// src/components/databrowser/hooks/use-keys.tsx
|
|
@@ -3037,7 +3051,7 @@ var KeysProvider = ({ children }) => {
|
|
|
3037
3051
|
queryKey: [FETCH_KEYS_QUERY_KEY, search],
|
|
3038
3052
|
initialPageParam: 0,
|
|
3039
3053
|
queryFn: async ({ pageParam: page }) => {
|
|
3040
|
-
if (pageRef.current
|
|
3054
|
+
if (pageRef.current >= page) resetCache();
|
|
3041
3055
|
pageRef.current = page;
|
|
3042
3056
|
return await fetchKeys();
|
|
3043
3057
|
},
|
|
@@ -3174,41 +3188,42 @@ var useAddKey = () => {
|
|
|
3174
3188
|
const { redis } = useDatabrowser();
|
|
3175
3189
|
const mutation = _reactquery.useMutation.call(void 0, {
|
|
3176
3190
|
mutationFn: async ({ key, type }) => {
|
|
3191
|
+
if (await redis.exists(key)) throw new Error(`Key "${key}" already exists`);
|
|
3177
3192
|
switch (type) {
|
|
3178
3193
|
case "set": {
|
|
3179
|
-
redis.sadd(key, "value");
|
|
3194
|
+
await redis.sadd(key, "value");
|
|
3180
3195
|
break;
|
|
3181
3196
|
}
|
|
3182
3197
|
case "zset": {
|
|
3183
|
-
redis.zadd(key, {
|
|
3198
|
+
await redis.zadd(key, {
|
|
3184
3199
|
member: "value",
|
|
3185
3200
|
score: 0
|
|
3186
3201
|
});
|
|
3187
3202
|
break;
|
|
3188
3203
|
}
|
|
3189
3204
|
case "hash": {
|
|
3190
|
-
redis.hset(key, {
|
|
3205
|
+
await redis.hset(key, {
|
|
3191
3206
|
field: "field",
|
|
3192
3207
|
value: "value"
|
|
3193
3208
|
});
|
|
3194
3209
|
break;
|
|
3195
3210
|
}
|
|
3196
3211
|
case "list": {
|
|
3197
|
-
redis.lpush(key, "value");
|
|
3212
|
+
await redis.lpush(key, "value");
|
|
3198
3213
|
break;
|
|
3199
3214
|
}
|
|
3200
3215
|
case "stream": {
|
|
3201
|
-
redis.xadd(key, "*", {
|
|
3216
|
+
await redis.xadd(key, "*", {
|
|
3202
3217
|
foo: "bar"
|
|
3203
3218
|
});
|
|
3204
3219
|
break;
|
|
3205
3220
|
}
|
|
3206
3221
|
case "string": {
|
|
3207
|
-
redis.set(key, "value");
|
|
3222
|
+
await redis.set(key, "value");
|
|
3208
3223
|
break;
|
|
3209
3224
|
}
|
|
3210
3225
|
case "json": {
|
|
3211
|
-
redis.json.set(key, "$", {
|
|
3226
|
+
await redis.json.set(key, "$", {
|
|
3212
3227
|
foo: "bar"
|
|
3213
3228
|
});
|
|
3214
3229
|
break;
|
|
@@ -3577,19 +3592,6 @@ var _reactcontextmenu = require('@radix-ui/react-context-menu'); var ContextMenu
|
|
|
3577
3592
|
|
|
3578
3593
|
|
|
3579
3594
|
|
|
3580
|
-
// src/lib/portal-root.ts
|
|
3581
|
-
var root;
|
|
3582
|
-
if (typeof document !== "undefined") {
|
|
3583
|
-
const id = "react-redis-browser-portal-root";
|
|
3584
|
-
root = _nullishCoalesce(document.querySelector(`#${id}`), () => ( document.createElement("div")));
|
|
3585
|
-
root.classList.add("ups-db");
|
|
3586
|
-
root.id = "react-redis-browser-portal-root";
|
|
3587
|
-
document.body.append(root);
|
|
3588
|
-
}
|
|
3589
|
-
var portalRoot = root;
|
|
3590
|
-
|
|
3591
|
-
// src/components/ui/context-menu.tsx
|
|
3592
|
-
|
|
3593
3595
|
var ContextMenu = ContextMenuPrimitive.Root;
|
|
3594
3596
|
var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
3595
3597
|
var ContextMenuSubTrigger = React4.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
@@ -4270,7 +4272,7 @@ var Spinner = ({
|
|
|
4270
4272
|
strokeWidth: "2",
|
|
4271
4273
|
strokeLinecap: "round",
|
|
4272
4274
|
strokeLinejoin: "round",
|
|
4273
|
-
className: "
|
|
4275
|
+
className: cn("h-4 w-4 animate-spin", isLoadingText ? "ml-2" : ""),
|
|
4274
4276
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
4275
4277
|
}
|
|
4276
4278
|
)
|
|
@@ -4567,7 +4569,14 @@ function KeyActions({ dataKey, content }) {
|
|
|
4567
4569
|
children: "Copy content"
|
|
4568
4570
|
}
|
|
4569
4571
|
),
|
|
4570
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4572
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4573
|
+
DeleteAlertDialog,
|
|
4574
|
+
{
|
|
4575
|
+
deletionType: "key",
|
|
4576
|
+
onDeleteConfirm: async () => await deleteKey(dataKey),
|
|
4577
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" })
|
|
4578
|
+
}
|
|
4579
|
+
)
|
|
4571
4580
|
] })
|
|
4572
4581
|
] });
|
|
4573
4582
|
}
|
|
@@ -4615,7 +4624,7 @@ var TooltipContent = React11.forwardRef(({ className, sideOffset = 4, ...props }
|
|
|
4615
4624
|
ref,
|
|
4616
4625
|
sideOffset,
|
|
4617
4626
|
className: cn(
|
|
4618
|
-
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
|
4627
|
+
"z-50 overflow-hidden rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:bg-zinc-50 dark:text-zinc-900",
|
|
4619
4628
|
className
|
|
4620
4629
|
),
|
|
4621
4630
|
...props
|
|
@@ -4701,7 +4710,8 @@ var CustomEditor = ({
|
|
|
4701
4710
|
value,
|
|
4702
4711
|
onChange,
|
|
4703
4712
|
height,
|
|
4704
|
-
showCopyButton
|
|
4713
|
+
showCopyButton,
|
|
4714
|
+
readOnly
|
|
4705
4715
|
}) => {
|
|
4706
4716
|
const monaco = _react2.useMonaco.call(void 0, );
|
|
4707
4717
|
const editorRef = _react.useRef.call(void 0, );
|
|
@@ -4732,6 +4742,7 @@ var CustomEditor = ({
|
|
|
4732
4742
|
},
|
|
4733
4743
|
defaultLanguage: language,
|
|
4734
4744
|
options: {
|
|
4745
|
+
readOnly,
|
|
4735
4746
|
wordWrap: "on",
|
|
4736
4747
|
overviewRulerBorder: false,
|
|
4737
4748
|
overviewRulerLanes: 0,
|
|
@@ -4777,7 +4788,8 @@ var useField = ({
|
|
|
4777
4788
|
name,
|
|
4778
4789
|
form,
|
|
4779
4790
|
height,
|
|
4780
|
-
showCopyButton
|
|
4791
|
+
showCopyButton,
|
|
4792
|
+
readOnly
|
|
4781
4793
|
}) => {
|
|
4782
4794
|
const { field, fieldState } = _reacthookform.useController.call(void 0, {
|
|
4783
4795
|
name,
|
|
@@ -4815,7 +4827,8 @@ var useField = ({
|
|
|
4815
4827
|
value: field.value,
|
|
4816
4828
|
onChange: field.onChange,
|
|
4817
4829
|
height,
|
|
4818
|
-
showCopyButton
|
|
4830
|
+
showCopyButton,
|
|
4831
|
+
readOnly
|
|
4819
4832
|
}
|
|
4820
4833
|
) })
|
|
4821
4834
|
};
|
|
@@ -4866,8 +4879,24 @@ var ListEditForm = ({
|
|
|
4866
4879
|
});
|
|
4867
4880
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacthookform.FormProvider, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit, className: "flex flex-col gap-2", children: [
|
|
4868
4881
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex grow flex-col gap-2", children: [
|
|
4869
|
-
type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4870
|
-
|
|
4882
|
+
type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4883
|
+
FormItem,
|
|
4884
|
+
{
|
|
4885
|
+
readOnly: type === "stream",
|
|
4886
|
+
name: "key",
|
|
4887
|
+
height: type === "set" ? 250 : 100,
|
|
4888
|
+
label: keyLabel
|
|
4889
|
+
}
|
|
4890
|
+
),
|
|
4891
|
+
type === "zset" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4892
|
+
FormItem,
|
|
4893
|
+
{
|
|
4894
|
+
readOnly: type === "stream",
|
|
4895
|
+
name: "value",
|
|
4896
|
+
height: type === "list" ? 250 : 100,
|
|
4897
|
+
label: valueLabel
|
|
4898
|
+
}
|
|
4899
|
+
)
|
|
4871
4900
|
] }),
|
|
4872
4901
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-2", children: [
|
|
4873
4902
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -4920,14 +4949,16 @@ var NumberFormItem = ({ name, label }) => {
|
|
|
4920
4949
|
var FormItem = ({
|
|
4921
4950
|
name,
|
|
4922
4951
|
label,
|
|
4923
|
-
height
|
|
4952
|
+
height,
|
|
4953
|
+
readOnly
|
|
4924
4954
|
}) => {
|
|
4925
4955
|
const form = _reacthookform.useFormContext.call(void 0, );
|
|
4926
4956
|
const { editor, selector } = useField({
|
|
4927
4957
|
name,
|
|
4928
4958
|
form,
|
|
4929
4959
|
height,
|
|
4930
|
-
showCopyButton: true
|
|
4960
|
+
showCopyButton: true,
|
|
4961
|
+
readOnly
|
|
4931
4962
|
});
|
|
4932
4963
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1", children: [
|
|
4933
4964
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 text-xs", children: [
|
|
@@ -5090,10 +5121,14 @@ var EditorDisplayForm = ({
|
|
|
5090
5121
|
|
|
5091
5122
|
var DataDisplay = () => {
|
|
5092
5123
|
const { selectedKey } = useDatabrowserStore();
|
|
5124
|
+
const { query } = useKeys();
|
|
5093
5125
|
const type = useKeyType(selectedKey);
|
|
5094
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full rounded-xl border p-1
|
|
5126
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full rounded-xl border bg-white p-1", children: !selectedKey ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", {}) : !type ? query.isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-gray-500", children: "Loading..." }) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: type === "string" || type === "json" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EditorDisplay, { dataKey: selectedKey, type }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListDisplay, { dataKey: selectedKey, type }) }) });
|
|
5095
5127
|
};
|
|
5096
5128
|
|
|
5129
|
+
// src/components/databrowser/components/sidebar/index.tsx
|
|
5130
|
+
|
|
5131
|
+
|
|
5097
5132
|
// src/components/databrowser/components/add-key-modal.tsx
|
|
5098
5133
|
|
|
5099
5134
|
var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog);
|
|
@@ -5214,23 +5249,16 @@ function AddKeyModal() {
|
|
|
5214
5249
|
}
|
|
5215
5250
|
});
|
|
5216
5251
|
const onSubmit = handleSubmit(async ({ key, type }) => {
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
}, 100);
|
|
5228
|
-
} catch (error) {
|
|
5229
|
-
toast({
|
|
5230
|
-
description: error instanceof Error ? error.message : "An error occurred",
|
|
5231
|
-
variant: "destructive"
|
|
5232
|
-
});
|
|
5233
|
-
}
|
|
5252
|
+
await addKey({ key, type });
|
|
5253
|
+
setSelectedKey(key);
|
|
5254
|
+
setOpen(false);
|
|
5255
|
+
setTimeout(() => {
|
|
5256
|
+
_optionalChain([window, 'access', _32 => _32.document, 'access', _33 => _33.querySelector, 'call', _34 => _34(`[data-key="${key}"]`), 'optionalAccess', _35 => _35.scrollIntoView, 'call', _36 => _36({
|
|
5257
|
+
behavior: "smooth",
|
|
5258
|
+
block: "start",
|
|
5259
|
+
inline: "nearest"
|
|
5260
|
+
})]);
|
|
5261
|
+
}, 100);
|
|
5234
5262
|
});
|
|
5235
5263
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
5236
5264
|
Dialog,
|
|
@@ -5472,12 +5500,15 @@ function DataTypeSelector() {
|
|
|
5472
5500
|
// src/components/databrowser/components/sidebar/index.tsx
|
|
5473
5501
|
|
|
5474
5502
|
function Sidebar() {
|
|
5475
|
-
const { keys, query } = useKeys();
|
|
5476
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col gap-2 rounded-xl border p-1
|
|
5503
|
+
const { keys, query, refetch } = useKeys();
|
|
5504
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col gap-2 rounded-xl border bg-white p-1", children: [
|
|
5477
5505
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rounded-lg bg-zinc-100 px-3 py-2", children: [
|
|
5478
5506
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 items-center justify-between pl-1", children: [
|
|
5479
5507
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, DisplayDbSize, {}),
|
|
5480
|
-
/* @__PURE__ */ _jsxruntime.
|
|
5508
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-1", children: [
|
|
5509
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { className: "h-7 w-7 px-0", onClick: refetch, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: query.isFetching, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconRefresh, { size: 16 }) }) }),
|
|
5510
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, AddKeyModal, {})
|
|
5511
|
+
] })
|
|
5481
5512
|
] }),
|
|
5482
5513
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 items-center", children: [
|
|
5483
5514
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataTypeSelector, {}),
|
|
@@ -5492,6 +5523,9 @@ function Sidebar() {
|
|
|
5492
5523
|
|
|
5493
5524
|
var RedisBrowser = ({ token, url }) => {
|
|
5494
5525
|
const credentials = _react.useMemo.call(void 0, () => ({ token, url }), [token, url]);
|
|
5526
|
+
_react.useEffect.call(void 0, () => {
|
|
5527
|
+
queryClient.resetQueries();
|
|
5528
|
+
}, [credentials.url]);
|
|
5495
5529
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactquery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacttooltip.TooltipProvider, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DatabrowserProvider, { redisCredentials: credentials, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeysProvider, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "ups-db", style: { height: "100%" }, children: [
|
|
5496
5530
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
5497
5531
|
_reactresizablepanels.PanelGroup,
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/databrowser/index.tsx
|
|
2
|
-
import { useMemo as useMemo6 } from "react";
|
|
2
|
+
import { useEffect as useEffect9, useMemo as useMemo6 } from "react";
|
|
3
3
|
|
|
4
4
|
// src/store.tsx
|
|
5
5
|
import { createContext, useContext, useMemo, useState as useState2 } from "react";
|
|
@@ -222,6 +222,20 @@ import { IconDotsVertical as IconDotsVertical2 } from "@tabler/icons-react";
|
|
|
222
222
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
223
223
|
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
|
|
224
224
|
|
|
225
|
+
// src/components/ui/toaster.tsx
|
|
226
|
+
import { Portal } from "@radix-ui/react-portal";
|
|
227
|
+
|
|
228
|
+
// src/lib/portal-root.ts
|
|
229
|
+
var root;
|
|
230
|
+
if (typeof document !== "undefined") {
|
|
231
|
+
const id = "react-redis-browser-portal-root";
|
|
232
|
+
root = document.querySelector(`#${id}`) ?? document.createElement("div");
|
|
233
|
+
root.classList.add("ups-db");
|
|
234
|
+
root.id = "react-redis-browser-portal-root";
|
|
235
|
+
document.body.append(root);
|
|
236
|
+
}
|
|
237
|
+
var portalRoot = root;
|
|
238
|
+
|
|
225
239
|
// src/components/ui/toast.tsx
|
|
226
240
|
import * as React2 from "react";
|
|
227
241
|
import { Cross2Icon } from "@radix-ui/react-icons";
|
|
@@ -2874,7 +2888,7 @@ ToastDescription.displayName = ToastPrimitives.Description.displayName;
|
|
|
2874
2888
|
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
2875
2889
|
function Toaster() {
|
|
2876
2890
|
const { toasts } = useToast();
|
|
2877
|
-
return /* @__PURE__ */ jsxs(ToastProvider, { children: [
|
|
2891
|
+
return /* @__PURE__ */ jsx3(Portal, { container: portalRoot, children: /* @__PURE__ */ jsxs(ToastProvider, { children: [
|
|
2878
2892
|
toasts.map(({ id, title, description, action, ...props }) => /* @__PURE__ */ jsxs(Toast, { ...props, children: [
|
|
2879
2893
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-1", children: [
|
|
2880
2894
|
title && /* @__PURE__ */ jsx3(ToastTitle, { children: title }),
|
|
@@ -2884,7 +2898,7 @@ function Toaster() {
|
|
|
2884
2898
|
/* @__PURE__ */ jsx3(ToastClose, {})
|
|
2885
2899
|
] }, id)),
|
|
2886
2900
|
/* @__PURE__ */ jsx3(ToastViewport, {})
|
|
2887
|
-
] });
|
|
2901
|
+
] }) });
|
|
2888
2902
|
}
|
|
2889
2903
|
|
|
2890
2904
|
// src/components/databrowser/hooks/use-keys.tsx
|
|
@@ -3037,7 +3051,7 @@ var KeysProvider = ({ children }) => {
|
|
|
3037
3051
|
queryKey: [FETCH_KEYS_QUERY_KEY, search],
|
|
3038
3052
|
initialPageParam: 0,
|
|
3039
3053
|
queryFn: async ({ pageParam: page }) => {
|
|
3040
|
-
if (pageRef.current
|
|
3054
|
+
if (pageRef.current >= page) resetCache();
|
|
3041
3055
|
pageRef.current = page;
|
|
3042
3056
|
return await fetchKeys();
|
|
3043
3057
|
},
|
|
@@ -3174,41 +3188,42 @@ var useAddKey = () => {
|
|
|
3174
3188
|
const { redis } = useDatabrowser();
|
|
3175
3189
|
const mutation = useMutation({
|
|
3176
3190
|
mutationFn: async ({ key, type }) => {
|
|
3191
|
+
if (await redis.exists(key)) throw new Error(`Key "${key}" already exists`);
|
|
3177
3192
|
switch (type) {
|
|
3178
3193
|
case "set": {
|
|
3179
|
-
redis.sadd(key, "value");
|
|
3194
|
+
await redis.sadd(key, "value");
|
|
3180
3195
|
break;
|
|
3181
3196
|
}
|
|
3182
3197
|
case "zset": {
|
|
3183
|
-
redis.zadd(key, {
|
|
3198
|
+
await redis.zadd(key, {
|
|
3184
3199
|
member: "value",
|
|
3185
3200
|
score: 0
|
|
3186
3201
|
});
|
|
3187
3202
|
break;
|
|
3188
3203
|
}
|
|
3189
3204
|
case "hash": {
|
|
3190
|
-
redis.hset(key, {
|
|
3205
|
+
await redis.hset(key, {
|
|
3191
3206
|
field: "field",
|
|
3192
3207
|
value: "value"
|
|
3193
3208
|
});
|
|
3194
3209
|
break;
|
|
3195
3210
|
}
|
|
3196
3211
|
case "list": {
|
|
3197
|
-
redis.lpush(key, "value");
|
|
3212
|
+
await redis.lpush(key, "value");
|
|
3198
3213
|
break;
|
|
3199
3214
|
}
|
|
3200
3215
|
case "stream": {
|
|
3201
|
-
redis.xadd(key, "*", {
|
|
3216
|
+
await redis.xadd(key, "*", {
|
|
3202
3217
|
foo: "bar"
|
|
3203
3218
|
});
|
|
3204
3219
|
break;
|
|
3205
3220
|
}
|
|
3206
3221
|
case "string": {
|
|
3207
|
-
redis.set(key, "value");
|
|
3222
|
+
await redis.set(key, "value");
|
|
3208
3223
|
break;
|
|
3209
3224
|
}
|
|
3210
3225
|
case "json": {
|
|
3211
|
-
redis.json.set(key, "$", {
|
|
3226
|
+
await redis.json.set(key, "$", {
|
|
3212
3227
|
foo: "bar"
|
|
3213
3228
|
});
|
|
3214
3229
|
break;
|
|
@@ -3576,19 +3591,6 @@ import { ContextMenuSeparator as ContextMenuSeparator2 } from "@radix-ui/react-c
|
|
|
3576
3591
|
import * as React4 from "react";
|
|
3577
3592
|
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
|
3578
3593
|
import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons";
|
|
3579
|
-
|
|
3580
|
-
// src/lib/portal-root.ts
|
|
3581
|
-
var root;
|
|
3582
|
-
if (typeof document !== "undefined") {
|
|
3583
|
-
const id = "react-redis-browser-portal-root";
|
|
3584
|
-
root = document.querySelector(`#${id}`) ?? document.createElement("div");
|
|
3585
|
-
root.classList.add("ups-db");
|
|
3586
|
-
root.id = "react-redis-browser-portal-root";
|
|
3587
|
-
document.body.append(root);
|
|
3588
|
-
}
|
|
3589
|
-
var portalRoot = root;
|
|
3590
|
-
|
|
3591
|
-
// src/components/ui/context-menu.tsx
|
|
3592
3594
|
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3593
3595
|
var ContextMenu = ContextMenuPrimitive.Root;
|
|
3594
3596
|
var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
@@ -4270,7 +4272,7 @@ var Spinner = ({
|
|
|
4270
4272
|
strokeWidth: "2",
|
|
4271
4273
|
strokeLinecap: "round",
|
|
4272
4274
|
strokeLinejoin: "round",
|
|
4273
|
-
className: "
|
|
4275
|
+
className: cn("h-4 w-4 animate-spin", isLoadingText ? "ml-2" : ""),
|
|
4274
4276
|
children: /* @__PURE__ */ jsx18("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
4275
4277
|
}
|
|
4276
4278
|
)
|
|
@@ -4567,7 +4569,14 @@ function KeyActions({ dataKey, content }) {
|
|
|
4567
4569
|
children: "Copy content"
|
|
4568
4570
|
}
|
|
4569
4571
|
),
|
|
4570
|
-
/* @__PURE__ */ jsx22(
|
|
4572
|
+
/* @__PURE__ */ jsx22(
|
|
4573
|
+
DeleteAlertDialog,
|
|
4574
|
+
{
|
|
4575
|
+
deletionType: "key",
|
|
4576
|
+
onDeleteConfirm: async () => await deleteKey(dataKey),
|
|
4577
|
+
children: /* @__PURE__ */ jsx22(DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" })
|
|
4578
|
+
}
|
|
4579
|
+
)
|
|
4571
4580
|
] })
|
|
4572
4581
|
] });
|
|
4573
4582
|
}
|
|
@@ -4615,7 +4624,7 @@ var TooltipContent = React11.forwardRef(({ className, sideOffset = 4, ...props }
|
|
|
4615
4624
|
ref,
|
|
4616
4625
|
sideOffset,
|
|
4617
4626
|
className: cn(
|
|
4618
|
-
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
|
4627
|
+
"z-50 overflow-hidden rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:bg-zinc-50 dark:text-zinc-900",
|
|
4619
4628
|
className
|
|
4620
4629
|
),
|
|
4621
4630
|
...props
|
|
@@ -4701,7 +4710,8 @@ var CustomEditor = ({
|
|
|
4701
4710
|
value,
|
|
4702
4711
|
onChange,
|
|
4703
4712
|
height,
|
|
4704
|
-
showCopyButton
|
|
4713
|
+
showCopyButton,
|
|
4714
|
+
readOnly
|
|
4705
4715
|
}) => {
|
|
4706
4716
|
const monaco = useMonaco();
|
|
4707
4717
|
const editorRef = useRef3();
|
|
@@ -4732,6 +4742,7 @@ var CustomEditor = ({
|
|
|
4732
4742
|
},
|
|
4733
4743
|
defaultLanguage: language,
|
|
4734
4744
|
options: {
|
|
4745
|
+
readOnly,
|
|
4735
4746
|
wordWrap: "on",
|
|
4736
4747
|
overviewRulerBorder: false,
|
|
4737
4748
|
overviewRulerLanes: 0,
|
|
@@ -4777,7 +4788,8 @@ var useField = ({
|
|
|
4777
4788
|
name,
|
|
4778
4789
|
form,
|
|
4779
4790
|
height,
|
|
4780
|
-
showCopyButton
|
|
4791
|
+
showCopyButton,
|
|
4792
|
+
readOnly
|
|
4781
4793
|
}) => {
|
|
4782
4794
|
const { field, fieldState } = useController({
|
|
4783
4795
|
name,
|
|
@@ -4815,7 +4827,8 @@ var useField = ({
|
|
|
4815
4827
|
value: field.value,
|
|
4816
4828
|
onChange: field.onChange,
|
|
4817
4829
|
height,
|
|
4818
|
-
showCopyButton
|
|
4830
|
+
showCopyButton,
|
|
4831
|
+
readOnly
|
|
4819
4832
|
}
|
|
4820
4833
|
) })
|
|
4821
4834
|
};
|
|
@@ -4866,8 +4879,24 @@ var ListEditForm = ({
|
|
|
4866
4879
|
});
|
|
4867
4880
|
return /* @__PURE__ */ jsx29(FormProvider, { ...form, children: /* @__PURE__ */ jsxs19("form", { onSubmit, className: "flex flex-col gap-2", children: [
|
|
4868
4881
|
/* @__PURE__ */ jsxs19("div", { className: "flex grow flex-col gap-2", children: [
|
|
4869
|
-
type !== "list" && /* @__PURE__ */ jsx29(
|
|
4870
|
-
|
|
4882
|
+
type !== "list" && /* @__PURE__ */ jsx29(
|
|
4883
|
+
FormItem,
|
|
4884
|
+
{
|
|
4885
|
+
readOnly: type === "stream",
|
|
4886
|
+
name: "key",
|
|
4887
|
+
height: type === "set" ? 250 : 100,
|
|
4888
|
+
label: keyLabel
|
|
4889
|
+
}
|
|
4890
|
+
),
|
|
4891
|
+
type === "zset" ? /* @__PURE__ */ jsx29(NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ jsx29(
|
|
4892
|
+
FormItem,
|
|
4893
|
+
{
|
|
4894
|
+
readOnly: type === "stream",
|
|
4895
|
+
name: "value",
|
|
4896
|
+
height: type === "list" ? 250 : 100,
|
|
4897
|
+
label: valueLabel
|
|
4898
|
+
}
|
|
4899
|
+
)
|
|
4871
4900
|
] }),
|
|
4872
4901
|
/* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2", children: [
|
|
4873
4902
|
/* @__PURE__ */ jsx29(
|
|
@@ -4920,14 +4949,16 @@ var NumberFormItem = ({ name, label }) => {
|
|
|
4920
4949
|
var FormItem = ({
|
|
4921
4950
|
name,
|
|
4922
4951
|
label,
|
|
4923
|
-
height
|
|
4952
|
+
height,
|
|
4953
|
+
readOnly
|
|
4924
4954
|
}) => {
|
|
4925
4955
|
const form = useFormContext();
|
|
4926
4956
|
const { editor, selector } = useField({
|
|
4927
4957
|
name,
|
|
4928
4958
|
form,
|
|
4929
4959
|
height,
|
|
4930
|
-
showCopyButton: true
|
|
4960
|
+
showCopyButton: true,
|
|
4961
|
+
readOnly
|
|
4931
4962
|
});
|
|
4932
4963
|
return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
|
|
4933
4964
|
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1 text-xs", children: [
|
|
@@ -5090,10 +5121,14 @@ var EditorDisplayForm = ({
|
|
|
5090
5121
|
import { Fragment as Fragment7, jsx as jsx32 } from "react/jsx-runtime";
|
|
5091
5122
|
var DataDisplay = () => {
|
|
5092
5123
|
const { selectedKey } = useDatabrowserStore();
|
|
5124
|
+
const { query } = useKeys();
|
|
5093
5125
|
const type = useKeyType(selectedKey);
|
|
5094
|
-
return /* @__PURE__ */ jsx32("div", { className: "h-full rounded-xl border p-1
|
|
5126
|
+
return /* @__PURE__ */ jsx32("div", { className: "h-full rounded-xl border bg-white p-1", children: !selectedKey ? /* @__PURE__ */ jsx32("div", {}) : !type ? query.isLoading ? /* @__PURE__ */ jsx32("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx32("span", { className: "text-gray-500", children: "Loading..." }) }) : /* @__PURE__ */ jsx32("div", {}) : /* @__PURE__ */ jsx32(Fragment7, { children: type === "string" || type === "json" ? /* @__PURE__ */ jsx32(EditorDisplay, { dataKey: selectedKey, type }) : /* @__PURE__ */ jsx32(ListDisplay, { dataKey: selectedKey, type }) }) });
|
|
5095
5127
|
};
|
|
5096
5128
|
|
|
5129
|
+
// src/components/databrowser/components/sidebar/index.tsx
|
|
5130
|
+
import { IconRefresh } from "@tabler/icons-react";
|
|
5131
|
+
|
|
5097
5132
|
// src/components/databrowser/components/add-key-modal.tsx
|
|
5098
5133
|
import { useState as useState8 } from "react";
|
|
5099
5134
|
import { DialogDescription as DialogDescription2 } from "@radix-ui/react-dialog";
|
|
@@ -5214,23 +5249,16 @@ function AddKeyModal() {
|
|
|
5214
5249
|
}
|
|
5215
5250
|
});
|
|
5216
5251
|
const onSubmit = handleSubmit(async ({ key, type }) => {
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
inline: "nearest"
|
|
5226
|
-
});
|
|
5227
|
-
}, 100);
|
|
5228
|
-
} catch (error) {
|
|
5229
|
-
toast({
|
|
5230
|
-
description: error instanceof Error ? error.message : "An error occurred",
|
|
5231
|
-
variant: "destructive"
|
|
5252
|
+
await addKey({ key, type });
|
|
5253
|
+
setSelectedKey(key);
|
|
5254
|
+
setOpen(false);
|
|
5255
|
+
setTimeout(() => {
|
|
5256
|
+
window.document.querySelector(`[data-key="${key}"]`)?.scrollIntoView({
|
|
5257
|
+
behavior: "smooth",
|
|
5258
|
+
block: "start",
|
|
5259
|
+
inline: "nearest"
|
|
5232
5260
|
});
|
|
5233
|
-
}
|
|
5261
|
+
}, 100);
|
|
5234
5262
|
});
|
|
5235
5263
|
return /* @__PURE__ */ jsxs23(
|
|
5236
5264
|
Dialog,
|
|
@@ -5472,12 +5500,15 @@ function DataTypeSelector() {
|
|
|
5472
5500
|
// src/components/databrowser/components/sidebar/index.tsx
|
|
5473
5501
|
import { jsx as jsx41, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5474
5502
|
function Sidebar() {
|
|
5475
|
-
const { keys, query } = useKeys();
|
|
5476
|
-
return /* @__PURE__ */ jsxs30("div", { className: "flex h-full flex-col gap-2 rounded-xl border p-1
|
|
5503
|
+
const { keys, query, refetch } = useKeys();
|
|
5504
|
+
return /* @__PURE__ */ jsxs30("div", { className: "flex h-full flex-col gap-2 rounded-xl border bg-white p-1", children: [
|
|
5477
5505
|
/* @__PURE__ */ jsxs30("div", { className: "rounded-lg bg-zinc-100 px-3 py-2", children: [
|
|
5478
5506
|
/* @__PURE__ */ jsxs30("div", { className: "flex h-10 items-center justify-between pl-1", children: [
|
|
5479
5507
|
/* @__PURE__ */ jsx41(DisplayDbSize, {}),
|
|
5480
|
-
/* @__PURE__ */
|
|
5508
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex gap-1", children: [
|
|
5509
|
+
/* @__PURE__ */ jsx41(Button, { className: "h-7 w-7 px-0", onClick: refetch, children: /* @__PURE__ */ jsx41(Spinner, { isLoading: query.isFetching, children: /* @__PURE__ */ jsx41(IconRefresh, { size: 16 }) }) }),
|
|
5510
|
+
/* @__PURE__ */ jsx41(AddKeyModal, {})
|
|
5511
|
+
] })
|
|
5481
5512
|
] }),
|
|
5482
5513
|
/* @__PURE__ */ jsxs30("div", { className: "flex h-10 items-center", children: [
|
|
5483
5514
|
/* @__PURE__ */ jsx41(DataTypeSelector, {}),
|
|
@@ -5492,6 +5523,9 @@ function Sidebar() {
|
|
|
5492
5523
|
import { jsx as jsx42, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5493
5524
|
var RedisBrowser = ({ token, url }) => {
|
|
5494
5525
|
const credentials = useMemo6(() => ({ token, url }), [token, url]);
|
|
5526
|
+
useEffect9(() => {
|
|
5527
|
+
queryClient.resetQueries();
|
|
5528
|
+
}, [credentials.url]);
|
|
5495
5529
|
return /* @__PURE__ */ jsx42(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx42(TooltipProvider, { children: /* @__PURE__ */ jsx42(DatabrowserProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx42(KeysProvider, { children: /* @__PURE__ */ jsxs31("div", { className: "ups-db", style: { height: "100%" }, children: [
|
|
5496
5530
|
/* @__PURE__ */ jsxs31(
|
|
5497
5531
|
PanelGroup,
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "name": "@upstash/react-redis-browser", "version": "v0.1.2-canary-
|
|
1
|
+
{ "name": "@upstash/react-redis-browser", "version": "v0.1.2-canary-8", "main": "./dist/index.js", "types": "./dist/index.d.ts", "license": "MIT", "private": false, "publishConfig": { "access": "public" }, "bugs": { "url": "https://github.com/upstash/react-redis-browser/issues" }, "homepage": "https://github.com/upstash/react-redis-browser", "files": [ "./dist/**" ], "scripts": { "build": "tsup", "dev": "vite", "lint": "tsc && eslint", "fmt": "prettier --write ./src" }, "lint-staged": { "**/*.{js,ts,tsx}": [ "prettier --write", "eslint --fix" ] }, "dependencies": { "@ianvs/prettier-plugin-sort-imports": "^4.4.0", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-context-menu": "^2.2.2", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-icons": "1.3.0", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-portal": "^1.1.2", "@radix-ui/react-scroll-area": "^1.0.3", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip": "^1.0.7", "@tabler/icons-react": "^3.19.0", "@tanstack/react-query": "^5.32.0", "@types/bytes": "^3.1.4", "@upstash/redis": "^1.34.3", "bytes": "^3.1.2", "react-hook-form": "^7.53.0", "react-resizable-panels": "^2.1.4", "zustand": "5.0.0" }, "devDependencies": { "postcss-prefix-selector": "^2.1.0", "@types/node": "^22.8.4", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@typescript-eslint/eslint-plugin": "8.4.0", "@typescript-eslint/parser": "8.4.0", "@vitejs/plugin-react": "^4.1.0", "autoprefixer": "^10.4.14", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", "eslint": "9.10.0", "eslint-plugin-unicorn": "55.0.0", "postcss": "^8.4.31", "prettier": "^3.0.3", "prettier-plugin-tailwindcss": "^0.5.5", "react": "^18.3.1", "react-dom": "^18.3.1", "tailwind-merge": "^2.5.4", "tailwindcss": "^3.4.14", "tailwindcss-animate": "^1.0.7", "tsup": "^8.3.5", "typescript": "^5.0.4", "vite": "^5.4.10", "vite-tsconfig-paths": "^5.0.1" }, "peerDependencies": { "react": "^18.2.0 || ^19", "react-dom": "^18.2.0 || ^19" } }
|