@upstash/react-redis-browser 0.2.4 → 0.2.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
@@ -371,6 +371,9 @@
371
371
  white-space: nowrap;
372
372
  border-width: 0;
373
373
  }
374
+ .ups-db .pointer-events-none {
375
+ pointer-events: none;
376
+ }
374
377
  .ups-db .pointer-events-auto {
375
378
  pointer-events: auto;
376
379
  }
@@ -440,6 +443,9 @@
440
443
  .ups-db .-z-10 {
441
444
  z-index: -10;
442
445
  }
446
+ .ups-db .z-10 {
447
+ z-index: 10;
448
+ }
443
449
  .ups-db .z-50 {
444
450
  z-index: 50;
445
451
  }
@@ -479,6 +485,9 @@
479
485
  .ups-db .mr-1 {
480
486
  margin-right: 0.25rem;
481
487
  }
488
+ .ups-db .mr-2 {
489
+ margin-right: 0.5rem;
490
+ }
482
491
  .ups-db .mt-0\.5 {
483
492
  margin-top: 0.125rem;
484
493
  }
@@ -574,6 +583,9 @@
574
583
  .ups-db .h-px {
575
584
  height: 1px;
576
585
  }
586
+ .ups-db .max-h-\[300px\] {
587
+ max-height: 300px;
588
+ }
577
589
  .ups-db .max-h-\[var\(--radix-dropdown-menu-content-available-height\)\] {
578
590
  max-height: var(--radix-dropdown-menu-content-available-height);
579
591
  }
@@ -616,6 +628,9 @@
616
628
  .ups-db .w-5 {
617
629
  width: 1.25rem;
618
630
  }
631
+ .ups-db .w-6 {
632
+ width: 1.5rem;
633
+ }
619
634
  .ups-db .w-7 {
620
635
  width: 1.75rem;
621
636
  }
@@ -734,6 +749,9 @@
734
749
  -moz-user-select: none;
735
750
  user-select: none;
736
751
  }
752
+ .ups-db .resize {
753
+ resize: both;
754
+ }
737
755
  .ups-db .flex-col {
738
756
  flex-direction: column;
739
757
  }
@@ -812,15 +830,15 @@
812
830
  .ups-db .overflow-visible {
813
831
  overflow: visible;
814
832
  }
833
+ .ups-db .overflow-x-auto {
834
+ overflow-x: auto;
835
+ }
815
836
  .ups-db .overflow-y-auto {
816
837
  overflow-y: auto;
817
838
  }
818
839
  .ups-db .overflow-x-hidden {
819
840
  overflow-x: hidden;
820
841
  }
821
- .ups-db .overflow-x-scroll {
822
- overflow-x: scroll;
823
- }
824
842
  .ups-db .truncate {
825
843
  overflow: hidden;
826
844
  text-overflow: ellipsis;
@@ -1133,6 +1151,9 @@
1133
1151
  .ups-db .pl-\[3px\] {
1134
1152
  padding-left: 3px;
1135
1153
  }
1154
+ .ups-db .pr-1 {
1155
+ padding-right: 0.25rem;
1156
+ }
1136
1157
  .ups-db .pr-2 {
1137
1158
  padding-right: 0.5rem;
1138
1159
  }
@@ -1342,6 +1363,9 @@
1342
1363
  .ups-db .opacity-0 {
1343
1364
  opacity: 0;
1344
1365
  }
1366
+ .ups-db .opacity-100 {
1367
+ opacity: 1;
1368
+ }
1345
1369
  .ups-db .opacity-50 {
1346
1370
  opacity: 0.5;
1347
1371
  }
@@ -1354,6 +1378,14 @@
1354
1378
  .ups-db .opacity-90 {
1355
1379
  opacity: 0.9;
1356
1380
  }
1381
+ .ups-db .shadow {
1382
+ --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
1383
+ --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
1384
+ box-shadow:
1385
+ var(--tw-ring-offset-shadow, 0 0 #0000),
1386
+ var(--tw-ring-shadow, 0 0 #0000),
1387
+ var(--tw-shadow);
1388
+ }
1357
1389
  .ups-db .shadow-lg {
1358
1390
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
1359
1391
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
@@ -1511,6 +1543,20 @@
1511
1543
  .ups-db .duration-200 {
1512
1544
  animation-duration: 200ms;
1513
1545
  }
1546
+ .ups-db .ups-db .tabs-shadow-left {
1547
+ background:
1548
+ linear-gradient(
1549
+ to right,
1550
+ rgba(0, 0, 0, 0.08),
1551
+ rgba(0, 0, 0, 0));
1552
+ }
1553
+ .ups-db .ups-db .tabs-shadow-right {
1554
+ background:
1555
+ linear-gradient(
1556
+ to left,
1557
+ rgba(0, 0, 0, 0.08),
1558
+ rgba(0, 0, 0, 0));
1559
+ }
1514
1560
  .ups-db .file\:border-0::file-selector-button {
1515
1561
  border-width: 0px;
1516
1562
  }
@@ -1524,6 +1570,14 @@
1524
1570
  .ups-db .file\:font-medium::file-selector-button {
1525
1571
  font-weight: 500;
1526
1572
  }
1573
+ .ups-db .placeholder\:text-neutral-500::-moz-placeholder {
1574
+ --tw-text-opacity: 1;
1575
+ color: rgb(115 115 115 / var(--tw-text-opacity));
1576
+ }
1577
+ .ups-db .placeholder\:text-neutral-500::placeholder {
1578
+ --tw-text-opacity: 1;
1579
+ color: rgb(115 115 115 / var(--tw-text-opacity));
1580
+ }
1527
1581
  .ups-db .placeholder\:text-zinc-500::-moz-placeholder {
1528
1582
  --tw-text-opacity: 1;
1529
1583
  color: rgb(113 113 122 / var(--tw-text-opacity));
@@ -1709,6 +1763,9 @@
1709
1763
  .ups-db .peer:disabled ~ .peer-disabled\:opacity-70 {
1710
1764
  opacity: 0.7;
1711
1765
  }
1766
+ .ups-db .data-\[disabled\=true\]\:pointer-events-none[data-disabled=true] {
1767
+ pointer-events: none;
1768
+ }
1712
1769
  .ups-db .data-\[disabled\]\:pointer-events-none[data-disabled] {
1713
1770
  pointer-events: none;
1714
1771
  }
@@ -1740,6 +1797,10 @@
1740
1797
  --tw-translate-x: var(--radix-toast-swipe-move-x);
1741
1798
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1742
1799
  }
1800
+ .ups-db .data-\[selected\=true\]\:bg-neutral-100[data-selected=true] {
1801
+ --tw-bg-opacity: 1;
1802
+ background-color: rgb(245 245 245 / var(--tw-bg-opacity));
1803
+ }
1743
1804
  .ups-db .data-\[state\=open\]\:bg-neutral-100[data-state=open] {
1744
1805
  --tw-bg-opacity: 1;
1745
1806
  background-color: rgb(245 245 245 / var(--tw-bg-opacity));
@@ -1748,6 +1809,10 @@
1748
1809
  --tw-bg-opacity: 1;
1749
1810
  background-color: rgb(244 244 245 / var(--tw-bg-opacity));
1750
1811
  }
1812
+ .ups-db .data-\[selected\=true\]\:text-neutral-900[data-selected=true] {
1813
+ --tw-text-opacity: 1;
1814
+ color: rgb(23 23 23 / var(--tw-text-opacity));
1815
+ }
1751
1816
  .ups-db .data-\[state\=open\]\:text-neutral-900[data-state=open] {
1752
1817
  --tw-text-opacity: 1;
1753
1818
  color: rgb(23 23 23 / var(--tw-text-opacity));
@@ -1756,6 +1821,9 @@
1756
1821
  --tw-text-opacity: 1;
1757
1822
  color: rgb(113 113 122 / var(--tw-text-opacity));
1758
1823
  }
1824
+ .ups-db .data-\[disabled\=true\]\:opacity-50[data-disabled=true] {
1825
+ opacity: 0.5;
1826
+ }
1759
1827
  .ups-db .data-\[disabled\]\:opacity-50[data-disabled] {
1760
1828
  opacity: 0.5;
1761
1829
  }
@@ -1918,6 +1986,14 @@
1918
1986
  .ups-db .dark\:ring-offset-zinc-950:is(.dark *) {
1919
1987
  --tw-ring-offset-color: #09090b;
1920
1988
  }
1989
+ .ups-db .dark\:placeholder\:text-neutral-400:is(.dark *)::-moz-placeholder {
1990
+ --tw-text-opacity: 1;
1991
+ color: rgb(163 163 163 / var(--tw-text-opacity));
1992
+ }
1993
+ .ups-db .dark\:placeholder\:text-neutral-400:is(.dark *)::placeholder {
1994
+ --tw-text-opacity: 1;
1995
+ color: rgb(163 163 163 / var(--tw-text-opacity));
1996
+ }
1921
1997
  .ups-db .dark\:placeholder\:text-zinc-400:is(.dark *)::-moz-placeholder {
1922
1998
  --tw-text-opacity: 1;
1923
1999
  color: rgb(161 161 170 / var(--tw-text-opacity));
@@ -1993,6 +2069,10 @@
1993
2069
  --tw-ring-opacity: 1;
1994
2070
  --tw-ring-color: rgb(127 29 29 / var(--tw-ring-opacity));
1995
2071
  }
2072
+ .ups-db .dark\:data-\[selected\=true\]\:bg-neutral-800[data-selected=true]:is(.dark *) {
2073
+ --tw-bg-opacity: 1;
2074
+ background-color: rgb(38 38 38 / var(--tw-bg-opacity));
2075
+ }
1996
2076
  .ups-db .dark\:data-\[state\=open\]\:bg-neutral-800[data-state=open]:is(.dark *) {
1997
2077
  --tw-bg-opacity: 1;
1998
2078
  background-color: rgb(38 38 38 / var(--tw-bg-opacity));
@@ -2001,6 +2081,10 @@
2001
2081
  --tw-bg-opacity: 1;
2002
2082
  background-color: rgb(39 39 42 / var(--tw-bg-opacity));
2003
2083
  }
2084
+ .ups-db .dark\:data-\[selected\=true\]\:text-neutral-50[data-selected=true]:is(.dark *) {
2085
+ --tw-text-opacity: 1;
2086
+ color: rgb(250 250 250 / var(--tw-text-opacity));
2087
+ }
2004
2088
  .ups-db .dark\:data-\[state\=open\]\:text-neutral-50[data-state=open]:is(.dark *) {
2005
2089
  --tw-text-opacity: 1;
2006
2090
  color: rgb(250 250 250 / var(--tw-text-opacity));
@@ -2062,6 +2146,59 @@
2062
2146
  .ups-db .\[\&\>svg\]\:shrink-0 > svg {
2063
2147
  flex-shrink: 0;
2064
2148
  }
2149
+ .ups-db .\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading] {
2150
+ padding-left: 0.5rem;
2151
+ padding-right: 0.5rem;
2152
+ }
2153
+ .ups-db .\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading] {
2154
+ padding-top: 0.375rem;
2155
+ padding-bottom: 0.375rem;
2156
+ }
2157
+ .ups-db .\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading] {
2158
+ font-size: 0.75rem;
2159
+ line-height: 1rem;
2160
+ }
2161
+ .ups-db .\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading] {
2162
+ font-weight: 500;
2163
+ }
2164
+ .ups-db .\[\&_\[cmdk-group-heading\]\]\:text-neutral-500 [cmdk-group-heading] {
2165
+ --tw-text-opacity: 1;
2166
+ color: rgb(115 115 115 / var(--tw-text-opacity));
2167
+ }
2168
+ .ups-db .dark\:\[\&_\[cmdk-group-heading\]\]\:text-neutral-400 [cmdk-group-heading]:is(.dark *) {
2169
+ --tw-text-opacity: 1;
2170
+ color: rgb(163 163 163 / var(--tw-text-opacity));
2171
+ }
2172
+ .ups-db .\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden]) ~ [cmdk-group] {
2173
+ padding-top: 0px;
2174
+ }
2175
+ .ups-db .\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group] {
2176
+ padding-left: 0.5rem;
2177
+ padding-right: 0.5rem;
2178
+ }
2179
+ .ups-db .\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg {
2180
+ height: 1.25rem;
2181
+ }
2182
+ .ups-db .\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg {
2183
+ width: 1.25rem;
2184
+ }
2185
+ .ups-db .\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input] {
2186
+ height: 3rem;
2187
+ }
2188
+ .ups-db .\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item] {
2189
+ padding-left: 0.5rem;
2190
+ padding-right: 0.5rem;
2191
+ }
2192
+ .ups-db .\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item] {
2193
+ padding-top: 0.75rem;
2194
+ padding-bottom: 0.75rem;
2195
+ }
2196
+ .ups-db .\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg {
2197
+ height: 1.25rem;
2198
+ }
2199
+ .ups-db .\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg {
2200
+ width: 1.25rem;
2201
+ }
2065
2202
  .ups-db .\[\&_svg\]\:pointer-events-none svg {
2066
2203
  pointer-events: none;
2067
2204
  }
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/components/databrowser/index.tsx
2
- var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React3 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React7 = _interopRequireWildcard(_react); var React8 = _interopRequireWildcard(_react); var React9 = _interopRequireWildcard(_react); var React10 = _interopRequireWildcard(_react); var React11 = _interopRequireWildcard(_react); var React12 = _interopRequireWildcard(_react);
2
+ var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react); var React3 = _interopRequireWildcard(_react); var React4 = _interopRequireWildcard(_react); var React5 = _interopRequireWildcard(_react); var React6 = _interopRequireWildcard(_react); var React7 = _interopRequireWildcard(_react); var React8 = _interopRequireWildcard(_react); var React9 = _interopRequireWildcard(_react); var React10 = _interopRequireWildcard(_react); var React11 = _interopRequireWildcard(_react); var React12 = _interopRequireWildcard(_react); var React13 = _interopRequireWildcard(_react);
3
3
 
4
4
  // src/redis-context.tsx
5
5
 
6
6
 
7
7
  // src/lib/clients.ts
8
8
  var _reactquery = require('@tanstack/react-query');
9
- var _redis = require('@upstash/redis');
9
+ var _cloudflare = require('@upstash/redis/cloudflare');
10
10
 
11
11
  // src/components/ui/use-toast.ts
12
12
 
@@ -144,7 +144,7 @@ var redisClient = ({
144
144
  if (!token) {
145
145
  throw new Error("Redis TOKEN is missing!");
146
146
  }
147
- const redis = new (0, _redis.Redis)({
147
+ const redis = new (0, _cloudflare.Redis)({
148
148
  url,
149
149
  token,
150
150
  enableAutoPipelining: pipelining,
@@ -5067,7 +5067,8 @@ var CustomEditor = ({
5067
5067
  lineDecorationsWidth: 0,
5068
5068
  automaticLayout: true,
5069
5069
  scrollBeyondLastLine: false,
5070
- renderLineHighlight: "none"
5070
+ renderLineHighlight: "none",
5071
+ unusualLineTerminators: "auto"
5071
5072
  }
5072
5073
  }
5073
5074
  );
@@ -5833,7 +5834,7 @@ var SearchInput = () => {
5833
5834
  setState(value);
5834
5835
  };
5835
5836
  const filteredHistory = dedupeSearchHistory(
5836
- searchHistory.filter((item) => item.includes(state) && item !== state)
5837
+ searchHistory.filter((item) => item.trim() !== "" && item.trim() !== "*").filter((item) => item.includes(state) && item !== state)
5837
5838
  ).slice(0, 5).map((item) => item.endsWith("*") ? item.slice(0, -1) : item);
5838
5839
  _react.useEffect.call(void 0, () => {
5839
5840
  setFocusedIndex(-1);
@@ -6050,6 +6051,106 @@ var _sortable = require('@dnd-kit/sortable');
6050
6051
  var _utilities = require('@dnd-kit/utilities');
6051
6052
 
6052
6053
 
6054
+ // src/components/ui/command.tsx
6055
+
6056
+ var _cmdk = require('cmdk');
6057
+
6058
+
6059
+ var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6060
+ _cmdk.Command,
6061
+ {
6062
+ ref,
6063
+ className: cn(
6064
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-white text-neutral-950 dark:bg-neutral-950 dark:text-neutral-50",
6065
+ className
6066
+ ),
6067
+ ...props
6068
+ }
6069
+ ));
6070
+ Command.displayName = _cmdk.Command.displayName;
6071
+ var CommandInput = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center border-b px-3", "cmdk-input-wrapper": "", children: [
6072
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacticons.MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
6073
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6074
+ _cmdk.Command.Input,
6075
+ {
6076
+ ref,
6077
+ className: cn(
6078
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-neutral-500 disabled:cursor-not-allowed disabled:opacity-50 dark:placeholder:text-neutral-400",
6079
+ className
6080
+ ),
6081
+ ...props
6082
+ }
6083
+ )
6084
+ ] }));
6085
+ CommandInput.displayName = _cmdk.Command.Input.displayName;
6086
+ var CommandList = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6087
+ _cmdk.Command.List,
6088
+ {
6089
+ ref,
6090
+ className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
6091
+ ...props
6092
+ }
6093
+ ));
6094
+ CommandList.displayName = _cmdk.Command.List.displayName;
6095
+ var CommandEmpty = React13.forwardRef((props, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6096
+ _cmdk.Command.Empty,
6097
+ {
6098
+ ref,
6099
+ className: "py-6 text-center text-sm",
6100
+ ...props
6101
+ }
6102
+ ));
6103
+ CommandEmpty.displayName = _cmdk.Command.Empty.displayName;
6104
+ var CommandGroup = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6105
+ _cmdk.Command.Group,
6106
+ {
6107
+ ref,
6108
+ className: cn(
6109
+ "overflow-hidden p-1 text-neutral-950 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-neutral-500 dark:text-neutral-50 dark:[&_[cmdk-group-heading]]:text-neutral-400",
6110
+ className
6111
+ ),
6112
+ ...props
6113
+ }
6114
+ ));
6115
+ CommandGroup.displayName = _cmdk.Command.Group.displayName;
6116
+ var CommandSeparator = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6117
+ _cmdk.Command.Separator,
6118
+ {
6119
+ ref,
6120
+ className: cn("-mx-1 h-px bg-neutral-200 dark:bg-neutral-800", className),
6121
+ ...props
6122
+ }
6123
+ ));
6124
+ CommandSeparator.displayName = _cmdk.Command.Separator.displayName;
6125
+ var CommandItem = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6126
+ _cmdk.Command.Item,
6127
+ {
6128
+ ref,
6129
+ className: cn(
6130
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-neutral-100 data-[selected=true]:text-neutral-900 data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:data-[selected=true]:bg-neutral-800 dark:data-[selected=true]:text-neutral-50",
6131
+ className
6132
+ ),
6133
+ ...props
6134
+ }
6135
+ ));
6136
+ CommandItem.displayName = _cmdk.Command.Item.displayName;
6137
+ var CommandShortcut = ({
6138
+ className,
6139
+ ...props
6140
+ }) => {
6141
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6142
+ "span",
6143
+ {
6144
+ className: cn(
6145
+ "ml-auto text-xs tracking-widest text-neutral-500 dark:text-neutral-400",
6146
+ className
6147
+ ),
6148
+ ...props
6149
+ }
6150
+ );
6151
+ };
6152
+ CommandShortcut.displayName = "CommandShortcut";
6153
+
6053
6154
  // src/components/databrowser/components/tab.tsx
6054
6155
 
6055
6156
 
@@ -6202,7 +6303,54 @@ var SortableTab = ({ id }) => {
6202
6303
  );
6203
6304
  };
6204
6305
  var DatabrowserTabs = () => {
6205
- const { tabs, addTab, reorderTabs, selectedTab } = useDatabrowserStore();
6306
+ const { tabs, addTab, reorderTabs, selectedTab, selectTab } = useDatabrowserStore();
6307
+ const scrollRef = _react.useRef.call(void 0, null);
6308
+ const [hasLeftShadow, setHasLeftShadow] = _react.useState.call(void 0, false);
6309
+ const [hasRightShadow, setHasRightShadow] = _react.useState.call(void 0, false);
6310
+ const [isOverflow, setIsOverflow] = _react.useState.call(void 0, false);
6311
+ _react.useEffect.call(void 0, () => {
6312
+ const el = scrollRef.current;
6313
+ if (!el) return;
6314
+ const onWheel = (event) => {
6315
+ if (el.scrollWidth <= el.clientWidth) return;
6316
+ const primaryDelta = Math.abs(event.deltaY) > Math.abs(event.deltaX) ? event.deltaY : event.deltaX;
6317
+ if (primaryDelta !== 0) {
6318
+ el.scrollLeft += primaryDelta;
6319
+ event.preventDefault();
6320
+ requestAnimationFrame(() => {
6321
+ const { scrollLeft, scrollWidth, clientWidth } = el;
6322
+ setHasLeftShadow(scrollLeft > 0);
6323
+ setHasRightShadow(scrollLeft + clientWidth < scrollWidth - 1);
6324
+ setIsOverflow(scrollWidth > clientWidth + 1);
6325
+ });
6326
+ }
6327
+ };
6328
+ el.addEventListener("wheel", onWheel, { passive: false });
6329
+ return () => {
6330
+ el.removeEventListener("wheel", onWheel);
6331
+ };
6332
+ }, []);
6333
+ const recomputeShadows = _react.useCallback.call(void 0, () => {
6334
+ const el = scrollRef.current;
6335
+ if (!el) return;
6336
+ const { scrollLeft, scrollWidth, clientWidth } = el;
6337
+ setHasLeftShadow(scrollLeft > 0);
6338
+ setHasRightShadow(scrollLeft + clientWidth < scrollWidth - 1);
6339
+ setIsOverflow(scrollWidth > clientWidth + 1);
6340
+ }, []);
6341
+ _react.useEffect.call(void 0, () => {
6342
+ recomputeShadows();
6343
+ const el = scrollRef.current;
6344
+ if (!el) return;
6345
+ const onResize = () => recomputeShadows();
6346
+ window.addEventListener("resize", onResize);
6347
+ const obs = new ResizeObserver(onResize);
6348
+ obs.observe(el);
6349
+ return () => {
6350
+ window.removeEventListener("resize", onResize);
6351
+ obs.disconnect();
6352
+ };
6353
+ }, [recomputeShadows]);
6206
6354
  const sensors = _core.useSensors.call(void 0,
6207
6355
  _core.useSensor.call(void 0, _core.PointerSensor, {
6208
6356
  activationConstraint: {
@@ -6220,36 +6368,152 @@ var DatabrowserTabs = () => {
6220
6368
  };
6221
6369
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative mb-2 shrink-0", children: [
6222
6370
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute bottom-0 left-0 right-0 -z-10 h-[1px] w-full bg-zinc-200" }),
6223
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "scrollbar-hide flex translate-y-[1px] items-center gap-1 overflow-x-scroll pb-[1px] [&::-webkit-scrollbar]:hidden", children: [
6224
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6225
- _core.DndContext,
6226
- {
6227
- sensors,
6228
- collisionDetection: _core.closestCenter,
6229
- onDragEnd: handleDragEnd,
6230
- modifiers: [_modifiers.restrictToHorizontalAxis],
6231
- measuring: {
6232
- droppable: {
6233
- strategy: _core.MeasuringStrategy.Always
6234
- }
6235
- },
6236
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _sortable.SortableContext, { items: tabs.map(([id]) => id), strategy: _sortable.horizontalListSortingStrategy, children: selectedTab && tabs.map(([id]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SortableTab, { id }, id)) })
6237
- }
6238
- ),
6239
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6240
- Button,
6241
- {
6242
- variant: "secondary",
6243
- size: "icon-sm",
6244
- onClick: addTab,
6245
- className: "mr-1 flex-shrink-0",
6246
- title: "Add new tab",
6247
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "text-zinc-500", size: 16 })
6248
- }
6249
- )
6371
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex translate-y-[1px] items-center gap-1", children: [
6372
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative min-w-0 flex-1", children: [
6373
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6374
+ "div",
6375
+ {
6376
+ className: `tabs-shadow-left pointer-events-none absolute left-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasLeftShadow ? "opacity-100" : "opacity-0"}`
6377
+ }
6378
+ ),
6379
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6380
+ "div",
6381
+ {
6382
+ className: `tabs-shadow-right pointer-events-none absolute right-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasRightShadow ? "opacity-100" : "opacity-0"}`
6383
+ }
6384
+ ),
6385
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6386
+ "div",
6387
+ {
6388
+ ref: scrollRef,
6389
+ onScroll: recomputeShadows,
6390
+ className: "scrollbar-hide flex min-w-0 flex-1 items-center gap-1 overflow-x-auto pb-[1px] [&::-webkit-scrollbar]:hidden",
6391
+ children: [
6392
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6393
+ _core.DndContext,
6394
+ {
6395
+ sensors,
6396
+ collisionDetection: _core.closestCenter,
6397
+ onDragEnd: handleDragEnd,
6398
+ modifiers: [_modifiers.restrictToHorizontalAxis],
6399
+ measuring: {
6400
+ droppable: {
6401
+ strategy: _core.MeasuringStrategy.Always
6402
+ }
6403
+ },
6404
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6405
+ _sortable.SortableContext,
6406
+ {
6407
+ items: tabs.map(([id]) => id),
6408
+ strategy: _sortable.horizontalListSortingStrategy,
6409
+ children: selectedTab && tabs.map(([id]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SortableTab, { id }, id))
6410
+ }
6411
+ )
6412
+ }
6413
+ ),
6414
+ !isOverflow && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 pl-1 pr-1", children: [
6415
+ tabs.length > 4 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabSearch, { tabs, onSelectTab: selectTab }),
6416
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6417
+ Button,
6418
+ {
6419
+ variant: "secondary",
6420
+ size: "icon-sm",
6421
+ onClick: addTab,
6422
+ className: "flex-shrink-0",
6423
+ title: "Add new tab",
6424
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "text-zinc-500", size: 16 })
6425
+ }
6426
+ )
6427
+ ] })
6428
+ ]
6429
+ }
6430
+ )
6431
+ ] }),
6432
+ isOverflow && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 pl-1", children: [
6433
+ tabs.length > 4 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabSearch, { tabs, onSelectTab: selectTab }),
6434
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6435
+ Button,
6436
+ {
6437
+ variant: "secondary",
6438
+ size: "icon-sm",
6439
+ onClick: addTab,
6440
+ className: "mr-1 flex-shrink-0",
6441
+ title: "Add new tab",
6442
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "text-zinc-500", size: 16 })
6443
+ }
6444
+ )
6445
+ ] })
6250
6446
  ] })
6251
6447
  ] });
6252
6448
  };
6449
+ function TabSearch({
6450
+ tabs,
6451
+ onSelectTab
6452
+ }) {
6453
+ const [open, setOpen] = _react.useState.call(void 0, false);
6454
+ const [query, setQuery] = _react.useState.call(void 0, "");
6455
+ const items = tabs.map(([id, data]) => ({
6456
+ id,
6457
+ label: data.search.key || data.selectedKey || "New Tab",
6458
+ searchKey: data.search.key,
6459
+ selectedKey: data.selectedKey,
6460
+ selectedItemKey: _optionalChain([data, 'access', _68 => _68.selectedListItem, 'optionalAccess', _69 => _69.key])
6461
+ }));
6462
+ const buildDisplayLabel = (it) => it.selectedItemKey ? `${it.label} > ${it.selectedItemKey}` : it.label;
6463
+ const dedupedMap = /* @__PURE__ */ new Map();
6464
+ for (const it of items) {
6465
+ const display = buildDisplayLabel(it);
6466
+ const key = display.toLowerCase();
6467
+ if (!dedupedMap.has(key)) dedupedMap.set(key, it);
6468
+ }
6469
+ const deduped = [...dedupedMap.values()];
6470
+ const filtered = (query ? deduped.filter((i) => buildDisplayLabel(i).toLowerCase().includes(query.toLowerCase())) : deduped).sort((a, b) => buildDisplayLabel(a).localeCompare(buildDisplayLabel(b)));
6471
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6472
+ Popover,
6473
+ {
6474
+ open,
6475
+ onOpenChange: (v) => {
6476
+ setOpen(v);
6477
+ if (!v) setQuery("");
6478
+ },
6479
+ children: [
6480
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { delayDuration: 400, children: [
6481
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "secondary", size: "icon-sm", "aria-label": "Search in tabs", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconSearch, { className: "text-zinc-500", size: 16 }) }) }) }),
6482
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipContent, { side: "top", children: "Search in tabs" })
6483
+ ] }),
6484
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverContent, { className: "w-72 p-0", align: "end", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Command, { children: [
6485
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6486
+ CommandInput,
6487
+ {
6488
+ placeholder: "Search tabs...",
6489
+ value: query,
6490
+ onValueChange: (v) => setQuery(v),
6491
+ className: "h-9"
6492
+ }
6493
+ ),
6494
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, CommandList, { children: [
6495
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CommandEmpty, { children: "No tabs" }),
6496
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CommandGroup, { children: filtered.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6497
+ CommandItem,
6498
+ {
6499
+ value: buildDisplayLabel(item),
6500
+ onSelect: () => {
6501
+ onSelectTab(item.id);
6502
+ setOpen(false);
6503
+ },
6504
+ children: [
6505
+ item.searchKey ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconSearch, { size: 15 }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabTypeIcon, { selectedKey: item.selectedKey }),
6506
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: buildDisplayLabel(item) })
6507
+ ]
6508
+ },
6509
+ item.id
6510
+ )) })
6511
+ ] })
6512
+ ] }) })
6513
+ ]
6514
+ }
6515
+ );
6516
+ }
6253
6517
 
6254
6518
  // src/components/databrowser/index.tsx
6255
6519
 
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ import { createContext, useContext, useMemo } from "react";
6
6
 
7
7
  // src/lib/clients.ts
8
8
  import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";
9
- import { Redis } from "@upstash/redis";
9
+ import { Redis } from "@upstash/redis/cloudflare";
10
10
 
11
11
  // src/components/ui/use-toast.ts
12
12
  import * as React from "react";
@@ -5067,7 +5067,8 @@ var CustomEditor = ({
5067
5067
  lineDecorationsWidth: 0,
5068
5068
  automaticLayout: true,
5069
5069
  scrollBeyondLastLine: false,
5070
- renderLineHighlight: "none"
5070
+ renderLineHighlight: "none",
5071
+ unusualLineTerminators: "auto"
5071
5072
  }
5072
5073
  }
5073
5074
  );
@@ -5833,7 +5834,7 @@ var SearchInput = () => {
5833
5834
  setState(value);
5834
5835
  };
5835
5836
  const filteredHistory = dedupeSearchHistory(
5836
- searchHistory.filter((item) => item.includes(state) && item !== state)
5837
+ searchHistory.filter((item) => item.trim() !== "" && item.trim() !== "*").filter((item) => item.includes(state) && item !== state)
5837
5838
  ).slice(0, 5).map((item) => item.endsWith("*") ? item.slice(0, -1) : item);
5838
5839
  useEffect11(() => {
5839
5840
  setFocusedIndex(-1);
@@ -6036,7 +6037,7 @@ var DatabrowserInstance = ({ hidden }) => {
6036
6037
  };
6037
6038
 
6038
6039
  // src/components/databrowser/components/databrowser-tabs.tsx
6039
- import { useEffect as useEffect13, useRef as useRef5, useState as useState13 } from "react";
6040
+ import { useCallback as useCallback3, useEffect as useEffect13, useRef as useRef5, useState as useState13 } from "react";
6040
6041
  import {
6041
6042
  closestCenter,
6042
6043
  DndContext,
@@ -6048,18 +6049,118 @@ import {
6048
6049
  import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
6049
6050
  import { horizontalListSortingStrategy, SortableContext, useSortable } from "@dnd-kit/sortable";
6050
6051
  import { CSS } from "@dnd-kit/utilities";
6051
- import { IconPlus as IconPlus2 } from "@tabler/icons-react";
6052
+ import { IconPlus as IconPlus2, IconSearch as IconSearch2 } from "@tabler/icons-react";
6053
+
6054
+ // src/components/ui/command.tsx
6055
+ import * as React13 from "react";
6056
+ import { Command as CommandPrimitive } from "cmdk";
6057
+ import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
6058
+ import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
6059
+ var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
6060
+ CommandPrimitive,
6061
+ {
6062
+ ref,
6063
+ className: cn(
6064
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-white text-neutral-950 dark:bg-neutral-950 dark:text-neutral-50",
6065
+ className
6066
+ ),
6067
+ ...props
6068
+ }
6069
+ ));
6070
+ Command.displayName = CommandPrimitive.displayName;
6071
+ var CommandInput = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs33("div", { className: "flex items-center border-b px-3", "cmdk-input-wrapper": "", children: [
6072
+ /* @__PURE__ */ jsx48(MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
6073
+ /* @__PURE__ */ jsx48(
6074
+ CommandPrimitive.Input,
6075
+ {
6076
+ ref,
6077
+ className: cn(
6078
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-neutral-500 disabled:cursor-not-allowed disabled:opacity-50 dark:placeholder:text-neutral-400",
6079
+ className
6080
+ ),
6081
+ ...props
6082
+ }
6083
+ )
6084
+ ] }));
6085
+ CommandInput.displayName = CommandPrimitive.Input.displayName;
6086
+ var CommandList = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
6087
+ CommandPrimitive.List,
6088
+ {
6089
+ ref,
6090
+ className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
6091
+ ...props
6092
+ }
6093
+ ));
6094
+ CommandList.displayName = CommandPrimitive.List.displayName;
6095
+ var CommandEmpty = React13.forwardRef((props, ref) => /* @__PURE__ */ jsx48(
6096
+ CommandPrimitive.Empty,
6097
+ {
6098
+ ref,
6099
+ className: "py-6 text-center text-sm",
6100
+ ...props
6101
+ }
6102
+ ));
6103
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
6104
+ var CommandGroup = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
6105
+ CommandPrimitive.Group,
6106
+ {
6107
+ ref,
6108
+ className: cn(
6109
+ "overflow-hidden p-1 text-neutral-950 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-neutral-500 dark:text-neutral-50 dark:[&_[cmdk-group-heading]]:text-neutral-400",
6110
+ className
6111
+ ),
6112
+ ...props
6113
+ }
6114
+ ));
6115
+ CommandGroup.displayName = CommandPrimitive.Group.displayName;
6116
+ var CommandSeparator = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
6117
+ CommandPrimitive.Separator,
6118
+ {
6119
+ ref,
6120
+ className: cn("-mx-1 h-px bg-neutral-200 dark:bg-neutral-800", className),
6121
+ ...props
6122
+ }
6123
+ ));
6124
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
6125
+ var CommandItem = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx48(
6126
+ CommandPrimitive.Item,
6127
+ {
6128
+ ref,
6129
+ className: cn(
6130
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-neutral-100 data-[selected=true]:text-neutral-900 data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:data-[selected=true]:bg-neutral-800 dark:data-[selected=true]:text-neutral-50",
6131
+ className
6132
+ ),
6133
+ ...props
6134
+ }
6135
+ ));
6136
+ CommandItem.displayName = CommandPrimitive.Item.displayName;
6137
+ var CommandShortcut = ({
6138
+ className,
6139
+ ...props
6140
+ }) => {
6141
+ return /* @__PURE__ */ jsx48(
6142
+ "span",
6143
+ {
6144
+ className: cn(
6145
+ "ml-auto text-xs tracking-widest text-neutral-500 dark:text-neutral-400",
6146
+ className
6147
+ ),
6148
+ ...props
6149
+ }
6150
+ );
6151
+ };
6152
+ CommandShortcut.displayName = "CommandShortcut";
6052
6153
 
6053
6154
  // src/components/databrowser/components/tab.tsx
6054
6155
  import { IconSearch, IconX as IconX2 } from "@tabler/icons-react";
6055
6156
 
6056
6157
  // src/components/databrowser/components/tab-type-icon.tsx
6057
- import { jsx as jsx48 } from "react/jsx-runtime";
6158
+ import { jsx as jsx49 } from "react/jsx-runtime";
6058
6159
  function TabTypeIcon({ selectedKey }) {
6059
6160
  const { data: keyType, isLoading } = useFetchKeyType(selectedKey);
6060
- if (isLoading) return /* @__PURE__ */ jsx48(Skeleton, { className: "h-5 w-5 rounded" });
6161
+ if (isLoading) return /* @__PURE__ */ jsx49(Skeleton, { className: "h-5 w-5 rounded" });
6061
6162
  if (!keyType || keyType === "none") return;
6062
- return /* @__PURE__ */ jsx48(TypeTag, { variant: keyType, type: "icon" });
6163
+ return /* @__PURE__ */ jsx49(TypeTag, { variant: keyType, type: "icon" });
6063
6164
  }
6064
6165
 
6065
6166
  // src/hooks/use-overflow.ts
@@ -6089,14 +6190,14 @@ var useOverflow = () => {
6089
6190
  };
6090
6191
 
6091
6192
  // src/components/databrowser/components/tab.tsx
6092
- import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
6193
+ import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
6093
6194
  var Tab = ({ id }) => {
6094
6195
  const { active, search, selectedKey } = useTab();
6095
6196
  const { selectTab, removeTab, tabs } = useDatabrowserStore();
6096
6197
  const { ref, isOverflow } = useOverflow();
6097
6198
  const label = search.key || selectedKey;
6098
- const iconNode = search.key ? /* @__PURE__ */ jsx49(IconSearch, { size: 15 }) : selectedKey ? /* @__PURE__ */ jsx49(TabTypeIcon, { selectedKey }) : void 0;
6099
- const tabNode = /* @__PURE__ */ jsxs33(
6199
+ const iconNode = search.key ? /* @__PURE__ */ jsx50(IconSearch, { size: 15 }) : selectedKey ? /* @__PURE__ */ jsx50(TabTypeIcon, { selectedKey }) : void 0;
6200
+ const tabNode = /* @__PURE__ */ jsxs34(
6100
6201
  "div",
6101
6202
  {
6102
6203
  onClick: () => selectTab(id),
@@ -6106,8 +6207,8 @@ var Tab = ({ id }) => {
6106
6207
  ),
6107
6208
  children: [
6108
6209
  iconNode,
6109
- /* @__PURE__ */ jsx49("span", { ref, className: "max-w-32 truncate whitespace-nowrap", children: label || "New Tab" }),
6110
- tabs.length > 1 && /* @__PURE__ */ jsx49(
6210
+ /* @__PURE__ */ jsx50("span", { ref, className: "max-w-32 truncate whitespace-nowrap", children: label || "New Tab" }),
6211
+ tabs.length > 1 && /* @__PURE__ */ jsx50(
6111
6212
  "button",
6112
6213
  {
6113
6214
  onClick: (e) => {
@@ -6115,17 +6216,17 @@ var Tab = ({ id }) => {
6115
6216
  removeTab(id);
6116
6217
  },
6117
6218
  className: "p-1 text-zinc-300 transition-colors hover:text-zinc-500",
6118
- children: /* @__PURE__ */ jsx49(IconX2, { size: 16 })
6219
+ children: /* @__PURE__ */ jsx50(IconX2, { size: 16 })
6119
6220
  }
6120
6221
  )
6121
6222
  ]
6122
6223
  }
6123
6224
  );
6124
- return /* @__PURE__ */ jsx49(SimpleTooltip, { content: isOverflow ? label : void 0, children: tabNode });
6225
+ return /* @__PURE__ */ jsx50(SimpleTooltip, { content: isOverflow ? label : void 0, children: tabNode });
6125
6226
  };
6126
6227
 
6127
6228
  // src/components/databrowser/components/databrowser-tabs.tsx
6128
- import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
6229
+ import { jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
6129
6230
  var SortableTab = ({ id }) => {
6130
6231
  const [originalWidth, setOriginalWidth] = useState13(null);
6131
6232
  const textRef = useRef5(null);
@@ -6189,7 +6290,7 @@ var SortableTab = ({ id }) => {
6189
6290
  minWidth: originalWidth ? `${originalWidth}px` : void 0
6190
6291
  } : {}
6191
6292
  };
6192
- return /* @__PURE__ */ jsx50(
6293
+ return /* @__PURE__ */ jsx51(
6193
6294
  "div",
6194
6295
  {
6195
6296
  ref: measureRef,
@@ -6197,12 +6298,59 @@ var SortableTab = ({ id }) => {
6197
6298
  className: isDragging ? "cursor-grabbing" : "cursor-grab",
6198
6299
  ...attributes,
6199
6300
  ...listeners2,
6200
- children: /* @__PURE__ */ jsx50(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx50(Tab, { id }) })
6301
+ children: /* @__PURE__ */ jsx51(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx51(Tab, { id }) })
6201
6302
  }
6202
6303
  );
6203
6304
  };
6204
6305
  var DatabrowserTabs = () => {
6205
- const { tabs, addTab, reorderTabs, selectedTab } = useDatabrowserStore();
6306
+ const { tabs, addTab, reorderTabs, selectedTab, selectTab } = useDatabrowserStore();
6307
+ const scrollRef = useRef5(null);
6308
+ const [hasLeftShadow, setHasLeftShadow] = useState13(false);
6309
+ const [hasRightShadow, setHasRightShadow] = useState13(false);
6310
+ const [isOverflow, setIsOverflow] = useState13(false);
6311
+ useEffect13(() => {
6312
+ const el = scrollRef.current;
6313
+ if (!el) return;
6314
+ const onWheel = (event) => {
6315
+ if (el.scrollWidth <= el.clientWidth) return;
6316
+ const primaryDelta = Math.abs(event.deltaY) > Math.abs(event.deltaX) ? event.deltaY : event.deltaX;
6317
+ if (primaryDelta !== 0) {
6318
+ el.scrollLeft += primaryDelta;
6319
+ event.preventDefault();
6320
+ requestAnimationFrame(() => {
6321
+ const { scrollLeft, scrollWidth, clientWidth } = el;
6322
+ setHasLeftShadow(scrollLeft > 0);
6323
+ setHasRightShadow(scrollLeft + clientWidth < scrollWidth - 1);
6324
+ setIsOverflow(scrollWidth > clientWidth + 1);
6325
+ });
6326
+ }
6327
+ };
6328
+ el.addEventListener("wheel", onWheel, { passive: false });
6329
+ return () => {
6330
+ el.removeEventListener("wheel", onWheel);
6331
+ };
6332
+ }, []);
6333
+ const recomputeShadows = useCallback3(() => {
6334
+ const el = scrollRef.current;
6335
+ if (!el) return;
6336
+ const { scrollLeft, scrollWidth, clientWidth } = el;
6337
+ setHasLeftShadow(scrollLeft > 0);
6338
+ setHasRightShadow(scrollLeft + clientWidth < scrollWidth - 1);
6339
+ setIsOverflow(scrollWidth > clientWidth + 1);
6340
+ }, []);
6341
+ useEffect13(() => {
6342
+ recomputeShadows();
6343
+ const el = scrollRef.current;
6344
+ if (!el) return;
6345
+ const onResize = () => recomputeShadows();
6346
+ window.addEventListener("resize", onResize);
6347
+ const obs = new ResizeObserver(onResize);
6348
+ obs.observe(el);
6349
+ return () => {
6350
+ window.removeEventListener("resize", onResize);
6351
+ obs.disconnect();
6352
+ };
6353
+ }, [recomputeShadows]);
6206
6354
  const sensors = useSensors(
6207
6355
  useSensor(PointerSensor, {
6208
6356
  activationConstraint: {
@@ -6218,41 +6366,157 @@ var DatabrowserTabs = () => {
6218
6366
  reorderTabs(oldIndex, newIndex);
6219
6367
  }
6220
6368
  };
6221
- return /* @__PURE__ */ jsxs34("div", { className: "relative mb-2 shrink-0", children: [
6222
- /* @__PURE__ */ jsx50("div", { className: "absolute bottom-0 left-0 right-0 -z-10 h-[1px] w-full bg-zinc-200" }),
6223
- /* @__PURE__ */ jsxs34("div", { className: "scrollbar-hide flex translate-y-[1px] items-center gap-1 overflow-x-scroll pb-[1px] [&::-webkit-scrollbar]:hidden", children: [
6224
- /* @__PURE__ */ jsx50(
6225
- DndContext,
6226
- {
6227
- sensors,
6228
- collisionDetection: closestCenter,
6229
- onDragEnd: handleDragEnd,
6230
- modifiers: [restrictToHorizontalAxis],
6231
- measuring: {
6232
- droppable: {
6233
- strategy: MeasuringStrategy.Always
6234
- }
6235
- },
6236
- children: /* @__PURE__ */ jsx50(SortableContext, { items: tabs.map(([id]) => id), strategy: horizontalListSortingStrategy, children: selectedTab && tabs.map(([id]) => /* @__PURE__ */ jsx50(SortableTab, { id }, id)) })
6237
- }
6238
- ),
6239
- /* @__PURE__ */ jsx50(
6240
- Button,
6241
- {
6242
- variant: "secondary",
6243
- size: "icon-sm",
6244
- onClick: addTab,
6245
- className: "mr-1 flex-shrink-0",
6246
- title: "Add new tab",
6247
- children: /* @__PURE__ */ jsx50(IconPlus2, { className: "text-zinc-500", size: 16 })
6248
- }
6249
- )
6369
+ return /* @__PURE__ */ jsxs35("div", { className: "relative mb-2 shrink-0", children: [
6370
+ /* @__PURE__ */ jsx51("div", { className: "absolute bottom-0 left-0 right-0 -z-10 h-[1px] w-full bg-zinc-200" }),
6371
+ /* @__PURE__ */ jsxs35("div", { className: "flex translate-y-[1px] items-center gap-1", children: [
6372
+ /* @__PURE__ */ jsxs35("div", { className: "relative min-w-0 flex-1", children: [
6373
+ /* @__PURE__ */ jsx51(
6374
+ "div",
6375
+ {
6376
+ className: `tabs-shadow-left pointer-events-none absolute left-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasLeftShadow ? "opacity-100" : "opacity-0"}`
6377
+ }
6378
+ ),
6379
+ /* @__PURE__ */ jsx51(
6380
+ "div",
6381
+ {
6382
+ className: `tabs-shadow-right pointer-events-none absolute right-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasRightShadow ? "opacity-100" : "opacity-0"}`
6383
+ }
6384
+ ),
6385
+ /* @__PURE__ */ jsxs35(
6386
+ "div",
6387
+ {
6388
+ ref: scrollRef,
6389
+ onScroll: recomputeShadows,
6390
+ className: "scrollbar-hide flex min-w-0 flex-1 items-center gap-1 overflow-x-auto pb-[1px] [&::-webkit-scrollbar]:hidden",
6391
+ children: [
6392
+ /* @__PURE__ */ jsx51(
6393
+ DndContext,
6394
+ {
6395
+ sensors,
6396
+ collisionDetection: closestCenter,
6397
+ onDragEnd: handleDragEnd,
6398
+ modifiers: [restrictToHorizontalAxis],
6399
+ measuring: {
6400
+ droppable: {
6401
+ strategy: MeasuringStrategy.Always
6402
+ }
6403
+ },
6404
+ children: /* @__PURE__ */ jsx51(
6405
+ SortableContext,
6406
+ {
6407
+ items: tabs.map(([id]) => id),
6408
+ strategy: horizontalListSortingStrategy,
6409
+ children: selectedTab && tabs.map(([id]) => /* @__PURE__ */ jsx51(SortableTab, { id }, id))
6410
+ }
6411
+ )
6412
+ }
6413
+ ),
6414
+ !isOverflow && /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-1 pl-1 pr-1", children: [
6415
+ tabs.length > 4 && /* @__PURE__ */ jsx51(TabSearch, { tabs, onSelectTab: selectTab }),
6416
+ /* @__PURE__ */ jsx51(
6417
+ Button,
6418
+ {
6419
+ variant: "secondary",
6420
+ size: "icon-sm",
6421
+ onClick: addTab,
6422
+ className: "flex-shrink-0",
6423
+ title: "Add new tab",
6424
+ children: /* @__PURE__ */ jsx51(IconPlus2, { className: "text-zinc-500", size: 16 })
6425
+ }
6426
+ )
6427
+ ] })
6428
+ ]
6429
+ }
6430
+ )
6431
+ ] }),
6432
+ isOverflow && /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-1 pl-1", children: [
6433
+ tabs.length > 4 && /* @__PURE__ */ jsx51(TabSearch, { tabs, onSelectTab: selectTab }),
6434
+ /* @__PURE__ */ jsx51(
6435
+ Button,
6436
+ {
6437
+ variant: "secondary",
6438
+ size: "icon-sm",
6439
+ onClick: addTab,
6440
+ className: "mr-1 flex-shrink-0",
6441
+ title: "Add new tab",
6442
+ children: /* @__PURE__ */ jsx51(IconPlus2, { className: "text-zinc-500", size: 16 })
6443
+ }
6444
+ )
6445
+ ] })
6250
6446
  ] })
6251
6447
  ] });
6252
6448
  };
6449
+ function TabSearch({
6450
+ tabs,
6451
+ onSelectTab
6452
+ }) {
6453
+ const [open, setOpen] = useState13(false);
6454
+ const [query, setQuery] = useState13("");
6455
+ const items = tabs.map(([id, data]) => ({
6456
+ id,
6457
+ label: data.search.key || data.selectedKey || "New Tab",
6458
+ searchKey: data.search.key,
6459
+ selectedKey: data.selectedKey,
6460
+ selectedItemKey: data.selectedListItem?.key
6461
+ }));
6462
+ const buildDisplayLabel = (it) => it.selectedItemKey ? `${it.label} > ${it.selectedItemKey}` : it.label;
6463
+ const dedupedMap = /* @__PURE__ */ new Map();
6464
+ for (const it of items) {
6465
+ const display = buildDisplayLabel(it);
6466
+ const key = display.toLowerCase();
6467
+ if (!dedupedMap.has(key)) dedupedMap.set(key, it);
6468
+ }
6469
+ const deduped = [...dedupedMap.values()];
6470
+ const filtered = (query ? deduped.filter((i) => buildDisplayLabel(i).toLowerCase().includes(query.toLowerCase())) : deduped).sort((a, b) => buildDisplayLabel(a).localeCompare(buildDisplayLabel(b)));
6471
+ return /* @__PURE__ */ jsxs35(
6472
+ Popover,
6473
+ {
6474
+ open,
6475
+ onOpenChange: (v) => {
6476
+ setOpen(v);
6477
+ if (!v) setQuery("");
6478
+ },
6479
+ children: [
6480
+ /* @__PURE__ */ jsxs35(Tooltip, { delayDuration: 400, children: [
6481
+ /* @__PURE__ */ jsx51(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx51(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx51(Button, { variant: "secondary", size: "icon-sm", "aria-label": "Search in tabs", children: /* @__PURE__ */ jsx51(IconSearch2, { className: "text-zinc-500", size: 16 }) }) }) }),
6482
+ /* @__PURE__ */ jsx51(TooltipContent, { side: "top", children: "Search in tabs" })
6483
+ ] }),
6484
+ /* @__PURE__ */ jsx51(PopoverContent, { className: "w-72 p-0", align: "end", children: /* @__PURE__ */ jsxs35(Command, { children: [
6485
+ /* @__PURE__ */ jsx51(
6486
+ CommandInput,
6487
+ {
6488
+ placeholder: "Search tabs...",
6489
+ value: query,
6490
+ onValueChange: (v) => setQuery(v),
6491
+ className: "h-9"
6492
+ }
6493
+ ),
6494
+ /* @__PURE__ */ jsxs35(CommandList, { children: [
6495
+ /* @__PURE__ */ jsx51(CommandEmpty, { children: "No tabs" }),
6496
+ /* @__PURE__ */ jsx51(CommandGroup, { children: filtered.map((item) => /* @__PURE__ */ jsxs35(
6497
+ CommandItem,
6498
+ {
6499
+ value: buildDisplayLabel(item),
6500
+ onSelect: () => {
6501
+ onSelectTab(item.id);
6502
+ setOpen(false);
6503
+ },
6504
+ children: [
6505
+ item.searchKey ? /* @__PURE__ */ jsx51(IconSearch2, { size: 15 }) : /* @__PURE__ */ jsx51(TabTypeIcon, { selectedKey: item.selectedKey }),
6506
+ /* @__PURE__ */ jsx51("span", { className: "truncate", children: buildDisplayLabel(item) })
6507
+ ]
6508
+ },
6509
+ item.id
6510
+ )) })
6511
+ ] })
6512
+ ] }) })
6513
+ ]
6514
+ }
6515
+ );
6516
+ }
6253
6517
 
6254
6518
  // src/components/databrowser/index.tsx
6255
- import { jsx as jsx51, jsxs as jsxs35 } from "react/jsx-runtime";
6519
+ import { jsx as jsx52, jsxs as jsxs36 } from "react/jsx-runtime";
6256
6520
  var RedisBrowser = ({
6257
6521
  token,
6258
6522
  url,
@@ -6263,14 +6527,14 @@ var RedisBrowser = ({
6263
6527
  useEffect14(() => {
6264
6528
  queryClient.resetQueries();
6265
6529
  }, [credentials.url]);
6266
- return /* @__PURE__ */ jsx51(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx51(RedisProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx51(DatabrowserProvider, { storage, children: /* @__PURE__ */ jsx51(TooltipProvider, { children: /* @__PURE__ */ jsxs35(
6530
+ return /* @__PURE__ */ jsx52(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx52(RedisProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx52(DatabrowserProvider, { storage, children: /* @__PURE__ */ jsx52(TooltipProvider, { children: /* @__PURE__ */ jsxs36(
6267
6531
  "div",
6268
6532
  {
6269
6533
  className: "ups-db",
6270
6534
  style: { height: "100%", display: "flex", flexDirection: "column" },
6271
6535
  children: [
6272
- !hideTabs && /* @__PURE__ */ jsx51(DatabrowserTabs, {}),
6273
- /* @__PURE__ */ jsx51(DatabrowserInstances, {})
6536
+ !hideTabs && /* @__PURE__ */ jsx52(DatabrowserTabs, {}),
6537
+ /* @__PURE__ */ jsx52(DatabrowserInstances, {})
6274
6538
  ]
6275
6539
  }
6276
6540
  ) }) }) }) });
@@ -6282,7 +6546,7 @@ var DatabrowserInstances = () => {
6282
6546
  else if (!selectedTab) selectTab(tabs[0][0]);
6283
6547
  }, [tabs, selectedTab, addTab, selectTab]);
6284
6548
  if (!selectedTab) return;
6285
- return tabs.map(([id]) => /* @__PURE__ */ jsx51(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx51(DatabrowserInstance, { hidden: id !== selectedTab }) }, id));
6549
+ return tabs.map(([id]) => /* @__PURE__ */ jsx52(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx52(DatabrowserInstance, { hidden: id !== selectedTab }) }, id));
6286
6550
  };
6287
6551
  export {
6288
6552
  RedisBrowser
package/package.json CHANGED
@@ -1 +1 @@
1
- { "name": "@upstash/react-redis-browser", "version": "v0.2.4", "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": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@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.15", "@radix-ui/react-icons": "1.3.0", "@radix-ui/react-label": "^2.1.7", "@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.35.3", "bytes": "^3.1.2", "react-hook-form": "^7.53.0", "react-resizable-panels": "^2.1.4", "zustand": "5.0.0" }, "devDependencies": { "@playwright/test": "^1.53.1", "@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", "dotenv": "^16.5.0", "eslint": "9.10.0", "eslint-plugin-unicorn": "55.0.0", "postcss": "^8.4.31", "postcss-prefix-selector": "^2.1.0", "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.2.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 ./src" }, "lint-staged": { "**/*.{js,ts,tsx}": [ "prettier --write", "eslint --fix" ] }, "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@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.1.14", "@radix-ui/react-dropdown-menu": "^2.1.15", "@radix-ui/react-icons": "1.3.0", "@radix-ui/react-label": "^2.1.7", "@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.35.3", "bytes": "^3.1.2", "cmdk": "^1.1.1", "react-hook-form": "^7.53.0", "react-resizable-panels": "^2.1.4", "zustand": "5.0.0" }, "devDependencies": { "@playwright/test": "^1.53.1", "@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", "dotenv": "^16.5.0", "eslint": "9.10.0", "eslint-plugin-unicorn": "55.0.0", "postcss": "^8.4.31", "postcss-prefix-selector": "^2.1.0", "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" } }