@upstash/react-redis-browser 0.1.2-canary-3 → 0.1.2-canary-5

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 CHANGED
@@ -1059,9 +1059,6 @@
1059
1059
  font-size: 0.75rem;
1060
1060
  line-height: 1rem;
1061
1061
  }
1062
- .ups-db .font-bold {
1063
- font-weight: 700;
1064
- }
1065
1062
  .ups-db .font-medium {
1066
1063
  font-weight: 500;
1067
1064
  }
package/dist/index.js CHANGED
@@ -3320,7 +3320,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3320
3320
  count: LIST_DISPLAY_PAGE_SIZE
3321
3321
  });
3322
3322
  return {
3323
- cursor: nextCursor,
3323
+ cursor: nextCursor === "0" ? void 0 : nextCursor,
3324
3324
  keys: keys.map((key) => ({ key }))
3325
3325
  };
3326
3326
  },
@@ -3336,7 +3336,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3336
3336
  rev: true
3337
3337
  });
3338
3338
  return {
3339
- cursor: lastIndex + LIST_DISPLAY_PAGE_SIZE,
3339
+ cursor: res.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastIndex + LIST_DISPLAY_PAGE_SIZE,
3340
3340
  keys: transformArray(res)
3341
3341
  };
3342
3342
  },
@@ -3351,7 +3351,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3351
3351
  count: LIST_DISPLAY_PAGE_SIZE
3352
3352
  });
3353
3353
  return {
3354
- cursor: res[0],
3354
+ cursor: res[0] === "0" ? void 0 : res[0],
3355
3355
  keys: transformArray(res[1])
3356
3356
  };
3357
3357
  },
@@ -3365,7 +3365,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3365
3365
  const lastIndex = Number(pageParam);
3366
3366
  const values = await redis.lrange(dataKey, lastIndex, lastIndex + LIST_DISPLAY_PAGE_SIZE);
3367
3367
  return {
3368
- cursor: lastIndex + LIST_DISPLAY_PAGE_SIZE,
3368
+ cursor: values.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastIndex + LIST_DISPLAY_PAGE_SIZE,
3369
3369
  keys: values.map((value, i) => ({
3370
3370
  key: (lastIndex + i).toString(),
3371
3371
  value
@@ -3377,17 +3377,18 @@ var useFetchListItems = ({ dataKey, type }) => {
3377
3377
  const streamQuery = _reactquery.useInfiniteQuery.call(void 0, {
3378
3378
  enabled: type === "stream",
3379
3379
  queryKey: [FETCH_LIST_ITEMS_QUERY_KEY, dataKey, "stream"],
3380
- initialPageParam: "0",
3380
+ initialPageParam: "-",
3381
3381
  queryFn: async ({ pageParam: lastId }) => {
3382
3382
  const messages = await redis.xrange(
3383
3383
  dataKey,
3384
- lastId,
3384
+ lastId === "-" ? "-" : `(${lastId}`,
3385
3385
  "+",
3386
- LIST_DISPLAY_PAGE_SIZE
3386
+ // +1 since first message is the last one
3387
+ LIST_DISPLAY_PAGE_SIZE + 1
3387
3388
  );
3388
3389
  const lastMessageId = messages.length > 0 ? _optionalChain([messages, 'access', _15 => _15.at, 'call', _16 => _16(-1), 'optionalAccess', _17 => _17[0]]) : void 0;
3389
3390
  return {
3390
- cursor: lastMessageId,
3391
+ cursor: messages.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastMessageId,
3391
3392
  keys: messages.map(([id, fields]) => ({
3392
3393
  key: id,
3393
3394
  value: fields.join("\n")
@@ -3790,30 +3791,28 @@ function DeleteAlertDialog({
3790
3791
  children,
3791
3792
  onDeleteConfirm,
3792
3793
  open,
3793
- onOpenChange
3794
+ onOpenChange,
3795
+ deletionType
3794
3796
  }) {
3795
3797
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialog, { open, onOpenChange, children: [
3796
3798
  children && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogTrigger, { asChild: true, children }),
3797
3799
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogContent, { children: [
3798
3800
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogHeader, { children: [
3799
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogTitle, { children: "Irreversible Action!" }),
3801
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogTitle, { children: deletionType === "item" ? "Delete Item" : "Delete Key" }),
3800
3802
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogDescription, { className: "mt-5", children: [
3801
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-bold", children: "This action CANNOT BE UNDONE." }),
3802
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "br", {}),
3803
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "br", {}),
3804
- "By proceeding, you will ",
3805
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-bold", children: "PERMANENTLY REMOVE" }),
3806
- " your data from our servers, resulting in complete and irreversible loss of your information."
3803
+ "Are you sure you want to delete this ",
3804
+ deletionType,
3805
+ "? This action cannot be undone."
3807
3806
  ] })
3808
3807
  ] }),
3809
3808
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogFooter, { children: [
3810
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogCancel, { children: "Cancel" }),
3809
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogCancel, { type: "button", children: "Cancel" }),
3811
3810
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3812
3811
  AlertDialogAction,
3813
3812
  {
3814
3813
  className: "bg-red-500 text-gray-50 hover:bg-red-600",
3815
3814
  onClick: onDeleteConfirm,
3816
- children: "Delete"
3815
+ children: "Yes, Delete"
3817
3816
  }
3818
3817
  )
3819
3818
  ] })
@@ -3836,6 +3835,7 @@ var ItemContextMenu = ({
3836
3835
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3837
3836
  DeleteAlertDialog,
3838
3837
  {
3838
+ deletionType: "item",
3839
3839
  open: isAlertOpen,
3840
3840
  onOpenChange: setAlertOpen,
3841
3841
  onDeleteConfirm: (e) => {
@@ -4540,7 +4540,7 @@ function KeyActions({ dataKey, content }) {
4540
4540
  children: "Copy content"
4541
4541
  }
4542
4542
  ),
4543
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DeleteAlertDialog, { onDeleteConfirm: async () => await deleteKey(dataKey), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" }) })
4543
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DeleteAlertDialog, { deletionType: "key", onDeleteConfirm: async () => await deleteKey(dataKey), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" }) })
4544
4544
  ] })
4545
4545
  ] });
4546
4546
  }
@@ -4552,8 +4552,6 @@ var DisplayHeader = ({
4552
4552
  type,
4553
4553
  content
4554
4554
  }) => {
4555
- const size = _optionalChain([content, 'optionalAccess', _21 => _21.length]);
4556
- const length = _optionalChain([content, 'optionalAccess', _22 => _22.length]);
4557
4555
  const { setSelectedListItem } = useDatabrowserStore();
4558
4556
  const handleAddItem = () => {
4559
4557
  setSelectedListItem({ key: type === "stream" ? "*" : "", value: "", isNew: true });
@@ -4570,7 +4568,6 @@ var DisplayHeader = ({
4570
4568
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TypeTag, { variant: type, type: "badge" }),
4571
4569
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SizeBadge, { dataKey }),
4572
4570
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LengthBadge, { dataKey, type, content }),
4573
- length && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Badge, { label: "Length:", children: size }),
4574
4571
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TTLBadge, { dataKey })
4575
4572
  ] })
4576
4573
  ] });
@@ -4676,7 +4673,7 @@ var CustomEditor = ({
4676
4673
  language,
4677
4674
  value,
4678
4675
  onChange,
4679
- maxDynamicHeight,
4676
+ height,
4680
4677
  showCopyButton
4681
4678
  }) => {
4682
4679
  const monaco = _react2.useMonaco.call(void 0, );
@@ -4685,14 +4682,14 @@ var CustomEditor = ({
4685
4682
  if (!monaco || !editorRef.current) {
4686
4683
  return;
4687
4684
  }
4688
- _optionalChain([monaco, 'optionalAccess', _23 => _23.editor, 'access', _24 => _24.setModelLanguage, 'call', _25 => _25(editorRef.current.getModel(), language)]);
4685
+ _optionalChain([monaco, 'optionalAccess', _21 => _21.editor, 'access', _22 => _22.setModelLanguage, 'call', _23 => _23(editorRef.current.getModel(), language)]);
4689
4686
  }, [monaco, language]);
4690
4687
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4691
4688
  "div",
4692
4689
  {
4693
- className: cn("group/editor relative", maxDynamicHeight === void 0 && "h-full p-2"),
4690
+ className: cn("group/editor relative", height === void 0 && "h-full p-2"),
4694
4691
  style: {
4695
- height: maxDynamicHeight
4692
+ height
4696
4693
  },
4697
4694
  children: [
4698
4695
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -4752,7 +4749,7 @@ var CustomEditor = ({
4752
4749
  var useField = ({
4753
4750
  name,
4754
4751
  form,
4755
- isEditorDynamic = false,
4752
+ height,
4756
4753
  showCopyButton
4757
4754
  }) => {
4758
4755
  const { field, fieldState } = _reacthookform.useController.call(void 0, {
@@ -4790,7 +4787,7 @@ var useField = ({
4790
4787
  language: contentType === "JSON" ? "json" : "plaintext",
4791
4788
  value: field.value,
4792
4789
  onChange: field.onChange,
4793
- maxDynamicHeight: isEditorDynamic ? 100 : void 0,
4790
+ height,
4794
4791
  showCopyButton
4795
4792
  }
4796
4793
  ) })
@@ -4842,13 +4839,14 @@ var ListEditForm = ({
4842
4839
  });
4843
4840
  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: [
4844
4841
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex grow flex-col gap-2", children: [
4845
- type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItem, { name: "key", label: keyLabel }),
4846
- type === "zset" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItem, { name: "value", label: valueLabel })
4842
+ type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItem, { name: "key", height: type === "set" ? 250 : 100, label: keyLabel }),
4843
+ type === "zset" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItem, { name: "value", height: type === "list" ? 250 : 100, label: valueLabel })
4847
4844
  ] }),
4848
4845
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-2", children: [
4849
4846
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4850
4847
  Button,
4851
4848
  {
4849
+ type: "button",
4852
4850
  onClick: () => {
4853
4851
  setSelectedListItem(void 0);
4854
4852
  },
@@ -4892,12 +4890,16 @@ var NumberFormItem = ({ name, label }) => {
4892
4890
  )
4893
4891
  ] });
4894
4892
  };
4895
- var FormItem = ({ name, label }) => {
4893
+ var FormItem = ({
4894
+ name,
4895
+ label,
4896
+ height
4897
+ }) => {
4896
4898
  const form = _reacthookform.useFormContext.call(void 0, );
4897
4899
  const { editor, selector } = useField({
4898
4900
  name,
4899
4901
  form,
4900
- isEditorDynamic: true,
4902
+ height,
4901
4903
  showCopyButton: true
4902
4904
  });
4903
4905
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1", children: [
@@ -4935,7 +4937,7 @@ var ListItems = ({
4935
4937
  dataKey
4936
4938
  }) => {
4937
4939
  const { setSelectedListItem } = useDatabrowserStore();
4938
- const keys = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([query, 'access', _26 => _26.data, 'optionalAccess', _27 => _27.pages, 'access', _28 => _28.flatMap, 'call', _29 => _29((page) => page.keys)]), () => ( [])), [query.data]);
4940
+ const keys = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([query, 'access', _24 => _24.data, 'optionalAccess', _25 => _25.pages, 'access', _26 => _26.flatMap, 'call', _27 => _27((page) => page.keys)]), () => ( [])), [query.data]);
4939
4941
  const { mutate: editItem } = useEditListItem();
4940
4942
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: keys.map(({ key, value }, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4941
4943
  ItemContextMenu,
@@ -4969,22 +4971,33 @@ var ListItems = ({
4969
4971
  children: value
4970
4972
  }
4971
4973
  ),
4972
- type !== "stream" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { width: 20, className: "px-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4973
- DeleteAlertDialog,
4974
+ type !== "stream" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4975
+ "td",
4974
4976
  {
4975
- onDeleteConfirm: (e) => {
4977
+ width: 20,
4978
+ className: "px-3",
4979
+ onClick: (e) => {
4976
4980
  e.stopPropagation();
4977
- editItem({
4978
- type,
4979
- dataKey,
4980
- itemKey: key,
4981
- // For deletion
4982
- newKey: void 0
4983
- });
4984
4981
  },
4985
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { size: "icon-sm", variant: "secondary", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconTrash, { className: "size-4 text-zinc-500" }) })
4982
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4983
+ DeleteAlertDialog,
4984
+ {
4985
+ deletionType: "item",
4986
+ onDeleteConfirm: (e) => {
4987
+ e.stopPropagation();
4988
+ editItem({
4989
+ type,
4990
+ dataKey,
4991
+ itemKey: key,
4992
+ // For deletion
4993
+ newKey: void 0
4994
+ });
4995
+ },
4996
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { size: "icon-sm", variant: "secondary", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconTrash, { className: "size-4 text-zinc-500" }) })
4997
+ }
4998
+ )
4986
4999
  }
4987
- ) })
5000
+ )
4988
5001
  ]
4989
5002
  }
4990
5003
  )
@@ -5063,12 +5076,13 @@ var DataDisplay = () => {
5063
5076
 
5064
5077
  // src/components/databrowser/components/add-key-modal.tsx
5065
5078
 
5079
+ var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog);
5066
5080
 
5067
5081
 
5068
5082
 
5069
5083
  // src/components/ui/dialog.tsx
5070
5084
 
5071
- var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog);
5085
+
5072
5086
 
5073
5087
  var Dialog = DialogPrimitive.Root;
5074
5088
  var DialogTrigger = DialogPrimitive.Trigger;
@@ -5185,7 +5199,7 @@ function AddKeyModal() {
5185
5199
  setSelectedKey(key);
5186
5200
  setOpen(false);
5187
5201
  setTimeout(() => {
5188
- _optionalChain([window, 'access', _30 => _30.document, 'access', _31 => _31.querySelector, 'call', _32 => _32(`[data-key="${key}"]`), 'optionalAccess', _33 => _33.scrollIntoView, 'call', _34 => _34({
5202
+ _optionalChain([window, 'access', _28 => _28.document, 'access', _29 => _29.querySelector, 'call', _30 => _30(`[data-key="${key}"]`), 'optionalAccess', _31 => _31.scrollIntoView, 'call', _32 => _32({
5189
5203
  behavior: "smooth",
5190
5204
  block: "start",
5191
5205
  inline: "nearest"
@@ -5210,6 +5224,7 @@ function AddKeyModal() {
5210
5224
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "primary", size: "icon-sm", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacticons.PlusIcon, { className: "size-4" }) }) }),
5211
5225
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogContent, { className: "max-w-[400px]", children: [
5212
5226
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTitle, { children: "Create new key" }) }),
5227
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sr-only", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactdialog.DialogDescription, { children: "Create new key" }) }),
5213
5228
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "mt-4", onSubmit, children: [
5214
5229
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-1", children: [
5215
5230
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -5235,7 +5250,7 @@ function AddKeyModal() {
5235
5250
  }
5236
5251
  )
5237
5252
  ] }),
5238
- formState.errors.key && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-3 mt-2 text-xs text-red-500", children: _optionalChain([formState, 'access', _35 => _35.errors, 'access', _36 => _36.key, 'optionalAccess', _37 => _37.message]) }),
5253
+ formState.errors.key && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-3 mt-2 text-xs text-red-500", children: _optionalChain([formState, 'access', _33 => _33.errors, 'access', _34 => _34.key, 'optionalAccess', _35 => _35.message]) }),
5239
5254
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-2 text-xs text-zinc-500", children: "After creating the key, you can edit the value" }),
5240
5255
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-6 flex justify-end gap-2", children: [
5241
5256
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -5281,6 +5296,7 @@ var SidebarContextMenu = ({
5281
5296
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5282
5297
  DeleteAlertDialog,
5283
5298
  {
5299
+ deletionType: "key",
5284
5300
  open: isAlertOpen,
5285
5301
  onOpenChange: setAlertOpen,
5286
5302
  onDeleteConfirm: (e) => {
@@ -5316,7 +5332,7 @@ var SidebarContextMenu = ({
5316
5332
 
5317
5333
  var KeysList = () => {
5318
5334
  const { keys } = useKeys();
5319
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "pr-3", children: keys.map((data, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyItem, { nextKey: _nullishCoalesce(_optionalChain([keys, 'access', _38 => _38.at, 'call', _39 => _39(i + 1), 'optionalAccess', _40 => _40[0]]), () => ( "")), data }, data[0])) });
5335
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "pr-3", children: keys.map((data, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyItem, { nextKey: _nullishCoalesce(_optionalChain([keys, 'access', _36 => _36.at, 'call', _37 => _37(i + 1), 'optionalAccess', _38 => _38[0]]), () => ( "")), data }, data[0])) });
5320
5336
  };
5321
5337
  var keyStyles = {
5322
5338
  string: "border-sky-400 !bg-sky-50 text-sky-900",
@@ -5444,8 +5460,8 @@ function Sidebar() {
5444
5460
 
5445
5461
  var RedisBrowser = ({ token, url }) => {
5446
5462
  const credentials = _react.useMemo.call(void 0, () => ({ token, url }), [token, url]);
5447
- 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.jsxs.call(void 0, KeysProvider, { children: [
5448
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "ups-db", style: { height: "100%" }, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5463
+ 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: [
5464
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5449
5465
  _reactresizablepanels.PanelGroup,
5450
5466
  {
5451
5467
  autoSaveId: "persistence",
@@ -5464,9 +5480,9 @@ var RedisBrowser = ({ token, url }) => {
5464
5480
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactresizablepanels.Panel, { minSize: 40, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataDisplay, {}) })
5465
5481
  ]
5466
5482
  }
5467
- ) }),
5483
+ ),
5468
5484
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Toaster, {})
5469
- ] }) }) }) });
5485
+ ] }) }) }) }) });
5470
5486
  };
5471
5487
 
5472
5488
 
package/dist/index.mjs CHANGED
@@ -3320,7 +3320,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3320
3320
  count: LIST_DISPLAY_PAGE_SIZE
3321
3321
  });
3322
3322
  return {
3323
- cursor: nextCursor,
3323
+ cursor: nextCursor === "0" ? void 0 : nextCursor,
3324
3324
  keys: keys.map((key) => ({ key }))
3325
3325
  };
3326
3326
  },
@@ -3336,7 +3336,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3336
3336
  rev: true
3337
3337
  });
3338
3338
  return {
3339
- cursor: lastIndex + LIST_DISPLAY_PAGE_SIZE,
3339
+ cursor: res.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastIndex + LIST_DISPLAY_PAGE_SIZE,
3340
3340
  keys: transformArray(res)
3341
3341
  };
3342
3342
  },
@@ -3351,7 +3351,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3351
3351
  count: LIST_DISPLAY_PAGE_SIZE
3352
3352
  });
3353
3353
  return {
3354
- cursor: res[0],
3354
+ cursor: res[0] === "0" ? void 0 : res[0],
3355
3355
  keys: transformArray(res[1])
3356
3356
  };
3357
3357
  },
@@ -3365,7 +3365,7 @@ var useFetchListItems = ({ dataKey, type }) => {
3365
3365
  const lastIndex = Number(pageParam);
3366
3366
  const values = await redis.lrange(dataKey, lastIndex, lastIndex + LIST_DISPLAY_PAGE_SIZE);
3367
3367
  return {
3368
- cursor: lastIndex + LIST_DISPLAY_PAGE_SIZE,
3368
+ cursor: values.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastIndex + LIST_DISPLAY_PAGE_SIZE,
3369
3369
  keys: values.map((value, i) => ({
3370
3370
  key: (lastIndex + i).toString(),
3371
3371
  value
@@ -3377,17 +3377,18 @@ var useFetchListItems = ({ dataKey, type }) => {
3377
3377
  const streamQuery = useInfiniteQuery2({
3378
3378
  enabled: type === "stream",
3379
3379
  queryKey: [FETCH_LIST_ITEMS_QUERY_KEY, dataKey, "stream"],
3380
- initialPageParam: "0",
3380
+ initialPageParam: "-",
3381
3381
  queryFn: async ({ pageParam: lastId }) => {
3382
3382
  const messages = await redis.xrange(
3383
3383
  dataKey,
3384
- lastId,
3384
+ lastId === "-" ? "-" : `(${lastId}`,
3385
3385
  "+",
3386
- LIST_DISPLAY_PAGE_SIZE
3386
+ // +1 since first message is the last one
3387
+ LIST_DISPLAY_PAGE_SIZE + 1
3387
3388
  );
3388
3389
  const lastMessageId = messages.length > 0 ? messages.at(-1)?.[0] : void 0;
3389
3390
  return {
3390
- cursor: lastMessageId,
3391
+ cursor: messages.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastMessageId,
3391
3392
  keys: messages.map(([id, fields]) => ({
3392
3393
  key: id,
3393
3394
  value: fields.join("\n")
@@ -3790,30 +3791,28 @@ function DeleteAlertDialog({
3790
3791
  children,
3791
3792
  onDeleteConfirm,
3792
3793
  open,
3793
- onOpenChange
3794
+ onOpenChange,
3795
+ deletionType
3794
3796
  }) {
3795
3797
  return /* @__PURE__ */ jsxs5(AlertDialog, { open, onOpenChange, children: [
3796
3798
  children && /* @__PURE__ */ jsx10(AlertDialogTrigger, { asChild: true, children }),
3797
3799
  /* @__PURE__ */ jsxs5(AlertDialogContent, { children: [
3798
3800
  /* @__PURE__ */ jsxs5(AlertDialogHeader, { children: [
3799
- /* @__PURE__ */ jsx10(AlertDialogTitle, { children: "Irreversible Action!" }),
3801
+ /* @__PURE__ */ jsx10(AlertDialogTitle, { children: deletionType === "item" ? "Delete Item" : "Delete Key" }),
3800
3802
  /* @__PURE__ */ jsxs5(AlertDialogDescription, { className: "mt-5", children: [
3801
- /* @__PURE__ */ jsx10("span", { className: "font-bold", children: "This action CANNOT BE UNDONE." }),
3802
- /* @__PURE__ */ jsx10("br", {}),
3803
- /* @__PURE__ */ jsx10("br", {}),
3804
- "By proceeding, you will ",
3805
- /* @__PURE__ */ jsx10("span", { className: "font-bold", children: "PERMANENTLY REMOVE" }),
3806
- " your data from our servers, resulting in complete and irreversible loss of your information."
3803
+ "Are you sure you want to delete this ",
3804
+ deletionType,
3805
+ "? This action cannot be undone."
3807
3806
  ] })
3808
3807
  ] }),
3809
3808
  /* @__PURE__ */ jsxs5(AlertDialogFooter, { children: [
3810
- /* @__PURE__ */ jsx10(AlertDialogCancel, { children: "Cancel" }),
3809
+ /* @__PURE__ */ jsx10(AlertDialogCancel, { type: "button", children: "Cancel" }),
3811
3810
  /* @__PURE__ */ jsx10(
3812
3811
  AlertDialogAction,
3813
3812
  {
3814
3813
  className: "bg-red-500 text-gray-50 hover:bg-red-600",
3815
3814
  onClick: onDeleteConfirm,
3816
- children: "Delete"
3815
+ children: "Yes, Delete"
3817
3816
  }
3818
3817
  )
3819
3818
  ] })
@@ -3836,6 +3835,7 @@ var ItemContextMenu = ({
3836
3835
  /* @__PURE__ */ jsx11(
3837
3836
  DeleteAlertDialog,
3838
3837
  {
3838
+ deletionType: "item",
3839
3839
  open: isAlertOpen,
3840
3840
  onOpenChange: setAlertOpen,
3841
3841
  onDeleteConfirm: (e) => {
@@ -4540,7 +4540,7 @@ function KeyActions({ dataKey, content }) {
4540
4540
  children: "Copy content"
4541
4541
  }
4542
4542
  ),
4543
- /* @__PURE__ */ jsx22(DeleteAlertDialog, { onDeleteConfirm: async () => await deleteKey(dataKey), children: /* @__PURE__ */ jsx22(DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" }) })
4543
+ /* @__PURE__ */ jsx22(DeleteAlertDialog, { deletionType: "key", onDeleteConfirm: async () => await deleteKey(dataKey), children: /* @__PURE__ */ jsx22(DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: "Delete key" }) })
4544
4544
  ] })
4545
4545
  ] });
4546
4546
  }
@@ -4552,8 +4552,6 @@ var DisplayHeader = ({
4552
4552
  type,
4553
4553
  content
4554
4554
  }) => {
4555
- const size = content?.length;
4556
- const length = content?.length;
4557
4555
  const { setSelectedListItem } = useDatabrowserStore();
4558
4556
  const handleAddItem = () => {
4559
4557
  setSelectedListItem({ key: type === "stream" ? "*" : "", value: "", isNew: true });
@@ -4570,7 +4568,6 @@ var DisplayHeader = ({
4570
4568
  /* @__PURE__ */ jsx23(TypeTag, { variant: type, type: "badge" }),
4571
4569
  /* @__PURE__ */ jsx23(SizeBadge, { dataKey }),
4572
4570
  /* @__PURE__ */ jsx23(LengthBadge, { dataKey, type, content }),
4573
- length && /* @__PURE__ */ jsx23(Badge, { label: "Length:", children: size }),
4574
4571
  /* @__PURE__ */ jsx23(TTLBadge, { dataKey })
4575
4572
  ] })
4576
4573
  ] });
@@ -4676,7 +4673,7 @@ var CustomEditor = ({
4676
4673
  language,
4677
4674
  value,
4678
4675
  onChange,
4679
- maxDynamicHeight,
4676
+ height,
4680
4677
  showCopyButton
4681
4678
  }) => {
4682
4679
  const monaco = useMonaco();
@@ -4690,9 +4687,9 @@ var CustomEditor = ({
4690
4687
  return /* @__PURE__ */ jsxs18(
4691
4688
  "div",
4692
4689
  {
4693
- className: cn("group/editor relative", maxDynamicHeight === void 0 && "h-full p-2"),
4690
+ className: cn("group/editor relative", height === void 0 && "h-full p-2"),
4694
4691
  style: {
4695
- height: maxDynamicHeight
4692
+ height
4696
4693
  },
4697
4694
  children: [
4698
4695
  /* @__PURE__ */ jsx27(
@@ -4752,7 +4749,7 @@ import { Fragment as Fragment4, jsx as jsx28 } from "react/jsx-runtime";
4752
4749
  var useField = ({
4753
4750
  name,
4754
4751
  form,
4755
- isEditorDynamic = false,
4752
+ height,
4756
4753
  showCopyButton
4757
4754
  }) => {
4758
4755
  const { field, fieldState } = useController({
@@ -4790,7 +4787,7 @@ var useField = ({
4790
4787
  language: contentType === "JSON" ? "json" : "plaintext",
4791
4788
  value: field.value,
4792
4789
  onChange: field.onChange,
4793
- maxDynamicHeight: isEditorDynamic ? 100 : void 0,
4790
+ height,
4794
4791
  showCopyButton
4795
4792
  }
4796
4793
  ) })
@@ -4842,13 +4839,14 @@ var ListEditForm = ({
4842
4839
  });
4843
4840
  return /* @__PURE__ */ jsx29(FormProvider, { ...form, children: /* @__PURE__ */ jsxs19("form", { onSubmit, className: "flex flex-col gap-2", children: [
4844
4841
  /* @__PURE__ */ jsxs19("div", { className: "flex grow flex-col gap-2", children: [
4845
- type !== "list" && /* @__PURE__ */ jsx29(FormItem, { name: "key", label: keyLabel }),
4846
- type === "zset" ? /* @__PURE__ */ jsx29(NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ jsx29(FormItem, { name: "value", label: valueLabel })
4842
+ type !== "list" && /* @__PURE__ */ jsx29(FormItem, { name: "key", height: type === "set" ? 250 : 100, label: keyLabel }),
4843
+ type === "zset" ? /* @__PURE__ */ jsx29(NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ jsx29(FormItem, { name: "value", height: type === "list" ? 250 : 100, label: valueLabel })
4847
4844
  ] }),
4848
4845
  /* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2", children: [
4849
4846
  /* @__PURE__ */ jsx29(
4850
4847
  Button,
4851
4848
  {
4849
+ type: "button",
4852
4850
  onClick: () => {
4853
4851
  setSelectedListItem(void 0);
4854
4852
  },
@@ -4892,12 +4890,16 @@ var NumberFormItem = ({ name, label }) => {
4892
4890
  )
4893
4891
  ] });
4894
4892
  };
4895
- var FormItem = ({ name, label }) => {
4893
+ var FormItem = ({
4894
+ name,
4895
+ label,
4896
+ height
4897
+ }) => {
4896
4898
  const form = useFormContext();
4897
4899
  const { editor, selector } = useField({
4898
4900
  name,
4899
4901
  form,
4900
- isEditorDynamic: true,
4902
+ height,
4901
4903
  showCopyButton: true
4902
4904
  });
4903
4905
  return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
@@ -4969,22 +4971,33 @@ var ListItems = ({
4969
4971
  children: value
4970
4972
  }
4971
4973
  ),
4972
- type !== "stream" && /* @__PURE__ */ jsx30("td", { width: 20, className: "px-3", children: /* @__PURE__ */ jsx30(
4973
- DeleteAlertDialog,
4974
+ type !== "stream" && /* @__PURE__ */ jsx30(
4975
+ "td",
4974
4976
  {
4975
- onDeleteConfirm: (e) => {
4977
+ width: 20,
4978
+ className: "px-3",
4979
+ onClick: (e) => {
4976
4980
  e.stopPropagation();
4977
- editItem({
4978
- type,
4979
- dataKey,
4980
- itemKey: key,
4981
- // For deletion
4982
- newKey: void 0
4983
- });
4984
4981
  },
4985
- children: /* @__PURE__ */ jsx30(Button, { size: "icon-sm", variant: "secondary", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx30(IconTrash, { className: "size-4 text-zinc-500" }) })
4982
+ children: /* @__PURE__ */ jsx30(
4983
+ DeleteAlertDialog,
4984
+ {
4985
+ deletionType: "item",
4986
+ onDeleteConfirm: (e) => {
4987
+ e.stopPropagation();
4988
+ editItem({
4989
+ type,
4990
+ dataKey,
4991
+ itemKey: key,
4992
+ // For deletion
4993
+ newKey: void 0
4994
+ });
4995
+ },
4996
+ children: /* @__PURE__ */ jsx30(Button, { size: "icon-sm", variant: "secondary", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx30(IconTrash, { className: "size-4 text-zinc-500" }) })
4997
+ }
4998
+ )
4986
4999
  }
4987
- ) })
5000
+ )
4988
5001
  ]
4989
5002
  }
4990
5003
  )
@@ -5063,6 +5076,7 @@ var DataDisplay = () => {
5063
5076
 
5064
5077
  // src/components/databrowser/components/add-key-modal.tsx
5065
5078
  import { useState as useState8 } from "react";
5079
+ import { DialogDescription as DialogDescription2 } from "@radix-ui/react-dialog";
5066
5080
  import { PlusIcon } from "@radix-ui/react-icons";
5067
5081
  import { Controller as Controller3, useForm as useForm4 } from "react-hook-form";
5068
5082
 
@@ -5210,6 +5224,7 @@ function AddKeyModal() {
5210
5224
  /* @__PURE__ */ jsx34(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(Button, { variant: "primary", size: "icon-sm", children: /* @__PURE__ */ jsx34(PlusIcon, { className: "size-4" }) }) }),
5211
5225
  /* @__PURE__ */ jsxs23(DialogContent, { className: "max-w-[400px]", children: [
5212
5226
  /* @__PURE__ */ jsx34(DialogHeader, { children: /* @__PURE__ */ jsx34(DialogTitle, { children: "Create new key" }) }),
5227
+ /* @__PURE__ */ jsx34("div", { className: "sr-only", children: /* @__PURE__ */ jsx34(DialogDescription2, { children: "Create new key" }) }),
5213
5228
  /* @__PURE__ */ jsxs23("form", { className: "mt-4", onSubmit, children: [
5214
5229
  /* @__PURE__ */ jsxs23("div", { className: "flex gap-1", children: [
5215
5230
  /* @__PURE__ */ jsx34(
@@ -5281,6 +5296,7 @@ var SidebarContextMenu = ({
5281
5296
  /* @__PURE__ */ jsx36(
5282
5297
  DeleteAlertDialog,
5283
5298
  {
5299
+ deletionType: "key",
5284
5300
  open: isAlertOpen,
5285
5301
  onOpenChange: setAlertOpen,
5286
5302
  onDeleteConfirm: (e) => {
@@ -5444,8 +5460,8 @@ function Sidebar() {
5444
5460
  import { jsx as jsx42, jsxs as jsxs31 } from "react/jsx-runtime";
5445
5461
  var RedisBrowser = ({ token, url }) => {
5446
5462
  const credentials = useMemo6(() => ({ token, url }), [token, url]);
5447
- return /* @__PURE__ */ jsx42(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx42(TooltipProvider, { children: /* @__PURE__ */ jsx42(DatabrowserProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsxs31(KeysProvider, { children: [
5448
- /* @__PURE__ */ jsx42("div", { className: "ups-db", style: { height: "100%" }, children: /* @__PURE__ */ jsxs31(
5463
+ 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: [
5464
+ /* @__PURE__ */ jsxs31(
5449
5465
  PanelGroup,
5450
5466
  {
5451
5467
  autoSaveId: "persistence",
@@ -5464,9 +5480,9 @@ var RedisBrowser = ({ token, url }) => {
5464
5480
  /* @__PURE__ */ jsx42(Panel, { minSize: 40, children: /* @__PURE__ */ jsx42(DataDisplay, {}) })
5465
5481
  ]
5466
5482
  }
5467
- ) }),
5483
+ ),
5468
5484
  /* @__PURE__ */ jsx42(Toaster, {})
5469
- ] }) }) }) });
5485
+ ] }) }) }) }) });
5470
5486
  };
5471
5487
  export {
5472
5488
  RedisBrowser
package/package.json CHANGED
@@ -1 +1 @@
1
- { "name": "@upstash/react-redis-browser", "version": "v0.1.2-canary-3", "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 ." }, "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-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.31.6", "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" } }
1
+ { "name": "@upstash/react-redis-browser", "version": "v0.1.2-canary-5", "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 ." }, "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-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.31.6", "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" } }