@upstash/react-redis-browser 0.2.14 → 0.2.16

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.js CHANGED
@@ -3468,43 +3468,51 @@ function Toaster() {
3468
3468
  // src/components/databrowser/hooks/use-fetch-search-indexes.tsx
3469
3469
 
3470
3470
 
3471
- // src/lib/scan-keys.ts
3472
- async function scanKeys(redis, {
3471
+ // src/lib/list-search-indexes.ts
3472
+ async function listSearchIndexes(redis, {
3473
3473
  match,
3474
- type,
3475
- count: count2 = 100,
3476
- limit
3477
- } = {}) {
3478
- let cursor = "0";
3479
- const result = [];
3480
- while (true) {
3481
- const [newCursor, keys] = await redis.scan(cursor, {
3482
- count: count2,
3483
- type,
3484
- match
3485
- });
3486
- result.push(...keys);
3487
- if (limit && result.length >= limit) {
3488
- return result.slice(0, limit);
3489
- }
3490
- if (newCursor === "0") break;
3491
- cursor = newCursor;
3492
- }
3493
- return result;
3474
+ limit,
3475
+ offset = 0
3476
+ }) {
3477
+ const args = ["search.listindexes"];
3478
+ if (match) args.push("MATCH", match);
3479
+ args.push("LIMIT", String(limit), "OFFSET", String(offset));
3480
+ const result = await redis.exec(args);
3481
+ return parseListIndexesResponse(result);
3482
+ }
3483
+ function parseListIndexesResponse(result) {
3484
+ return result.map((entry) => entry[1]);
3494
3485
  }
3495
3486
 
3496
3487
  // src/components/databrowser/hooks/use-fetch-search-indexes.tsx
3497
3488
  var FETCH_SEARCH_INDEXES_QUERY_KEY = "fetch-search-indexes";
3489
+ var PAGE_SIZE = 30;
3498
3490
  var useFetchSearchIndexes = ({
3499
3491
  match,
3500
3492
  enabled
3501
3493
  } = {}) => {
3502
3494
  const { redisNoPipeline: redis } = useRedis();
3503
- return _reactquery.useQuery.call(void 0, {
3504
- queryKey: [FETCH_SEARCH_INDEXES_QUERY_KEY],
3495
+ const query = _reactquery.useInfiniteQuery.call(void 0, {
3496
+ queryKey: [FETCH_SEARCH_INDEXES_QUERY_KEY, match],
3505
3497
  enabled: _nullishCoalesce(enabled, () => ( true)),
3506
- queryFn: () => scanKeys(redis, { match, type: "search" })
3498
+ initialPageParam: 0,
3499
+ queryFn: async ({ pageParam: offset }) => {
3500
+ const names = await listSearchIndexes(redis, { match, limit: PAGE_SIZE, offset });
3501
+ return {
3502
+ names,
3503
+ nextOffset: names.length >= PAGE_SIZE ? offset + names.length : void 0
3504
+ };
3505
+ },
3506
+ getNextPageParam: (lastPage) => lastPage.nextOffset
3507
3507
  });
3508
+ const indexes = _optionalChain([query, 'access', _26 => _26.data, 'optionalAccess', _27 => _27.pages, 'access', _28 => _28.flatMap, 'call', _29 => _29((page) => page.names)]);
3509
+ return {
3510
+ data: indexes,
3511
+ isLoading: query.isLoading || query.isFetching && !query.isFetchingNextPage,
3512
+ hasNextPage: query.hasNextPage,
3513
+ fetchNextPage: query.fetchNextPage,
3514
+ isFetchingNextPage: query.isFetchingNextPage
3515
+ };
3508
3516
  };
3509
3517
 
3510
3518
  // src/components/databrowser/hooks/use-keys.tsx
@@ -3586,6 +3594,21 @@ var KeysProvider = ({ children }) => {
3586
3594
  }
3587
3595
  return { cursor: newCursor, keys: keys2 };
3588
3596
  };
3597
+ const redisSearchIndexScan = async ({
3598
+ count: count2,
3599
+ cursor
3600
+ }) => {
3601
+ const offset = Number.parseInt(cursor, 10) || 0;
3602
+ const names = await listSearchIndexes(redis, {
3603
+ match: search.key || void 0,
3604
+ limit: count2,
3605
+ offset
3606
+ });
3607
+ const keys2 = names.map((name) => ({ key: name, type: "search" }));
3608
+ const hasMore = keys2.length >= count2;
3609
+ const nextCursor = hasMore ? String(offset + keys2.length) : "0";
3610
+ return { cursor: nextCursor, keys: keys2 };
3611
+ };
3589
3612
  const redisValueScan = async ({
3590
3613
  count: count2,
3591
3614
  cursor
@@ -3611,7 +3634,7 @@ var KeysProvider = ({ children }) => {
3611
3634
  return { cursor: nextCursor, keys: keys2 };
3612
3635
  };
3613
3636
  const performScan = async (count2, cursor) => {
3614
- const scanFunction = isValuesSearchSelected ? redisValueScan : redisKeyScan;
3637
+ const scanFunction = isValuesSearchSelected ? redisValueScan : search.type === "search" ? redisSearchIndexScan : redisKeyScan;
3615
3638
  const result = await scanFunction({ count: count2, cursor });
3616
3639
  return [result.cursor, result.keys];
3617
3640
  };
@@ -3650,7 +3673,7 @@ var KeysProvider = ({ children }) => {
3650
3673
  refetchOnMount: false
3651
3674
  });
3652
3675
  const keys = _react.useMemo.call(void 0, () => {
3653
- const keys2 = _nullishCoalesce(_optionalChain([query, 'access', _26 => _26.data, 'optionalAccess', _27 => _27.pages, 'access', _28 => _28.flatMap, 'call', _29 => _29((page) => page.keys)]), () => ( []));
3676
+ const keys2 = _nullishCoalesce(_optionalChain([query, 'access', _30 => _30.data, 'optionalAccess', _31 => _31.pages, 'access', _32 => _32.flatMap, 'call', _33 => _33((page) => page.keys)]), () => ( []));
3654
3677
  const keysSet = /* @__PURE__ */ new Set();
3655
3678
  const dedupedKeys = [];
3656
3679
  for (const key of keys2) {
@@ -3684,7 +3707,7 @@ var useKeys = () => {
3684
3707
  var useKeyType = (key) => {
3685
3708
  const { keys } = useKeys();
3686
3709
  const keyTuple = _react.useMemo.call(void 0, () => keys.find(([k, _]) => k === key), [keys, key]);
3687
- return _optionalChain([keyTuple, 'optionalAccess', _30 => _30[1]]);
3710
+ return _optionalChain([keyTuple, 'optionalAccess', _34 => _34[1]]);
3688
3711
  };
3689
3712
 
3690
3713
  // src/types/index.ts
@@ -4158,7 +4181,7 @@ function parseFieldBuilder(str, fieldName) {
4158
4181
  }
4159
4182
  if (str.startsWith("s.number(")) {
4160
4183
  const typeMatch = str.match(/s\.number\(\s*["']?(U64|I64|F64)?["']?\s*\)/);
4161
- const numType = _optionalChain([typeMatch, 'optionalAccess', _31 => _31[1]]) || "F64";
4184
+ const numType = _optionalChain([typeMatch, 'optionalAccess', _35 => _35[1]]) || "F64";
4162
4185
  const fromValue = extractFromValue(str);
4163
4186
  if (fromValue === void 0) return numType;
4164
4187
  return { type: numType, from: fromValue };
@@ -4184,14 +4207,18 @@ function parseFieldBuilder(str, fieldName) {
4184
4207
  };
4185
4208
  }
4186
4209
  if (str.startsWith("s.keyword()")) {
4187
- return "KEYWORD";
4210
+ const fromValue = extractFromValue(str);
4211
+ if (fromValue === void 0) return "KEYWORD";
4212
+ return { type: "KEYWORD", from: fromValue };
4188
4213
  }
4189
4214
  if (str.startsWith("s.facet()")) {
4190
- return "FACET";
4215
+ const fromValue = extractFromValue(str);
4216
+ if (fromValue === void 0) return "FACET";
4217
+ return { type: "FACET", from: fromValue };
4191
4218
  }
4192
4219
  if (str.startsWith("s.")) {
4193
4220
  const typeMatch = str.match(/^s\.(\w+)\(/);
4194
- const typeName = _nullishCoalesce(_optionalChain([typeMatch, 'optionalAccess', _32 => _32[1]]), () => ( "unknown"));
4221
+ const typeName = _nullishCoalesce(_optionalChain([typeMatch, 'optionalAccess', _36 => _36[1]]), () => ( "unknown"));
4195
4222
  throw new Error(`Unknown field type "s.${typeName}()" for field "${fieldName}"`);
4196
4223
  }
4197
4224
  return void 0;
@@ -4480,6 +4507,18 @@ var useAddKey = () => {
4480
4507
 
4481
4508
  // src/components/databrowser/hooks/use-debounce.ts
4482
4509
 
4510
+ function useDebounce(value, delay) {
4511
+ const [debouncedValue, setDebouncedValue] = _react.useState.call(void 0, value);
4512
+ _react.useEffect.call(void 0, () => {
4513
+ const handler = setTimeout(() => {
4514
+ setDebouncedValue(value);
4515
+ }, delay);
4516
+ return () => {
4517
+ clearTimeout(handler);
4518
+ };
4519
+ }, [value, delay]);
4520
+ return debouncedValue;
4521
+ }
4483
4522
 
4484
4523
  // src/components/databrowser/hooks/use-delete-key.ts
4485
4524
 
@@ -4571,7 +4610,7 @@ var useFetchListItems = ({ dataKey, type }) => {
4571
4610
  // +1 since first message is the last one
4572
4611
  LIST_DISPLAY_PAGE_SIZE + 1
4573
4612
  );
4574
- const lastMessageId = messages.length > 0 ? _optionalChain([messages, 'access', _33 => _33.at, 'call', _34 => _34(-1), 'optionalAccess', _35 => _35[0]]) : void 0;
4613
+ const lastMessageId = messages.length > 0 ? _optionalChain([messages, 'access', _37 => _37.at, 'call', _38 => _38(-1), 'optionalAccess', _39 => _39[0]]) : void 0;
4575
4614
  return {
4576
4615
  cursor: messages.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastMessageId,
4577
4616
  keys: messages.map(([id, fields]) => ({
@@ -4746,7 +4785,7 @@ var useEditListItem = () => {
4746
4785
  }
4747
4786
  case "stream": {
4748
4787
  if (!isNew || !newKey) throw new Error("Stream data type is not mutable");
4749
- const opts = transformArray(_nullishCoalesce(_optionalChain([newValue, 'optionalAccess', _36 => _36.split, 'call', _37 => _37("\n")]), () => ( []))).map(
4788
+ const opts = transformArray((_nullishCoalesce(_optionalChain([newValue, 'optionalAccess', _40 => _40.split, 'call', _41 => _41("\n")]), () => ( []))).filter(Boolean)).map(
4750
4789
  ({ key, value }) => [key, value]
4751
4790
  );
4752
4791
  pipe.xadd(dataKey, newKey, Object.fromEntries(opts));
@@ -5053,7 +5092,7 @@ var LengthBadge = ({
5053
5092
  content
5054
5093
  }) => {
5055
5094
  const { data, isLoading } = useFetchKeyLength({ dataKey, type });
5056
- const length = _nullishCoalesce(_optionalChain([content, 'optionalAccess', _38 => _38.length]), () => ( data));
5095
+ const length = _nullishCoalesce(_optionalChain([content, 'optionalAccess', _42 => _42.length]), () => ( data));
5057
5096
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Badge, { label: "Length:", children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : length });
5058
5097
  };
5059
5098
  var SizeBadge = ({ dataKey }) => {
@@ -5079,7 +5118,7 @@ var Badge = ({ children, label }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void
5079
5118
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children })
5080
5119
  ] });
5081
5120
 
5082
- // src/components/databrowser/components/display/key-actions.tsx
5121
+ // src/components/databrowser/components/display/item-actions.tsx
5083
5122
 
5084
5123
 
5085
5124
  // src/components/ui/dropdown-menu.tsx
@@ -5339,7 +5378,9 @@ function DeleteKeyModal({
5339
5378
  onOpenChange,
5340
5379
  deletionType,
5341
5380
  count: count2 = 1,
5342
- showReindex
5381
+ showReindex,
5382
+ name,
5383
+ nameLabel
5343
5384
  }) {
5344
5385
  const isPlural = count2 > 1;
5345
5386
  const itemLabel = deletionType === "item" ? "Item" : "Key";
@@ -5358,7 +5399,10 @@ function DeleteKeyModal({
5358
5399
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogDescription, { className: "mt-5", children: [
5359
5400
  "Are you sure you want to delete",
5360
5401
  " ",
5361
- isPlural ? `these ${count2} ${deletionType}s` : `this ${deletionType}`,
5402
+ name ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
5403
+ `${_nullishCoalesce(nameLabel, () => ( deletionType))} `,
5404
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-zinc-900 dark:text-zinc-100", children: nameLabel ? name : `"${name}"` })
5405
+ ] }) : isPlural ? `these ${count2} ${deletionType}s` : `this ${deletionType}`,
5362
5406
  "?",
5363
5407
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "br", {}),
5364
5408
  "This action cannot be undone."
@@ -5383,7 +5427,7 @@ function DeleteKeyModal({
5383
5427
  type: "button",
5384
5428
  variant: "outline",
5385
5429
  disabled: isPending,
5386
- onClick: () => _optionalChain([setIsOpen, 'optionalCall', _39 => _39(false)]),
5430
+ onClick: () => _optionalChain([setIsOpen, 'optionalCall', _43 => _43(false)]),
5387
5431
  children: "Cancel"
5388
5432
  }
5389
5433
  ),
@@ -5409,8 +5453,51 @@ function DeleteKeyModal({
5409
5453
  ] });
5410
5454
  }
5411
5455
 
5456
+ // src/components/databrowser/components/display/item-actions.tsx
5457
+
5458
+ function ItemActions({ dataKey, type }) {
5459
+ const { selectedListItem, setSelectedListItem } = useTab();
5460
+ const { mutateAsync: editItem } = useEditListItem();
5461
+ if (!selectedListItem) return;
5462
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DropdownMenu, { modal: false, children: [
5463
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { size: "icon-sm", "aria-label": "Item actions", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5464
+ _iconsreact.IconDotsVertical,
5465
+ {
5466
+ className: "size-4 text-zinc-500 dark:text-zinc-600",
5467
+ fill: "rgb(var(--color-zinc-500))"
5468
+ }
5469
+ ) }) }),
5470
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuContent, { align: "end", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5471
+ DeleteKeyModal,
5472
+ {
5473
+ deletionType: "item",
5474
+ name: selectedListItem.key,
5475
+ nameLabel: type === "list" ? "item at index" : void 0,
5476
+ onDeleteConfirm: async () => {
5477
+ await editItem({
5478
+ type,
5479
+ dataKey,
5480
+ itemKey: selectedListItem.key,
5481
+ newKey: void 0
5482
+ });
5483
+ setSelectedListItem(void 0);
5484
+ },
5485
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5486
+ DropdownMenuItem,
5487
+ {
5488
+ className: "text-red-500 focus:bg-red-500 focus:text-white",
5489
+ onSelect: (e) => e.preventDefault(),
5490
+ children: "Delete item"
5491
+ }
5492
+ )
5493
+ }
5494
+ ) })
5495
+ ] });
5496
+ }
5497
+
5412
5498
  // src/components/databrowser/components/display/key-actions.tsx
5413
5499
 
5500
+
5414
5501
  function KeyActions({
5415
5502
  dataKey,
5416
5503
  content,
@@ -5452,9 +5539,10 @@ function KeyActions({
5452
5539
  DeleteKeyModal,
5453
5540
  {
5454
5541
  deletionType: "key",
5542
+ name: dataKey,
5455
5543
  showReindex: isValuesSearchSelected && type !== "search",
5456
5544
  onDeleteConfirm: async (_e, options) => {
5457
- await deleteKey({ keys: [dataKey], reindex: _optionalChain([options, 'optionalAccess', _40 => _40.reindex]) });
5545
+ await deleteKey({ keys: [dataKey], reindex: _optionalChain([options, 'optionalAccess', _44 => _44.reindex]) });
5458
5546
  },
5459
5547
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5460
5548
  DropdownMenuItem,
@@ -5478,7 +5566,9 @@ var DisplayHeader = ({
5478
5566
  content,
5479
5567
  hideTypeTag
5480
5568
  }) => {
5481
- const { setSelectedListItem } = useTab();
5569
+ const { setSelectedListItem, selectedListItem } = useTab();
5570
+ const isListType = type !== "string" && type !== "json" && type !== "search" && type !== "stream";
5571
+ const showItemActions = isListType && Boolean(selectedListItem);
5482
5572
  const handleAddItem = () => {
5483
5573
  setSelectedListItem({ key: type === "stream" ? "*" : "", isNew: true });
5484
5574
  };
@@ -5486,8 +5576,8 @@ var DisplayHeader = ({
5486
5576
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-[26px] items-center justify-between gap-4", children: [
5487
5577
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "grow truncate text-sm", children: dataKey.trim() === "" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "ml-1 text-zinc-500", children: "(Empty Key)" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-zinc-950", children: dataKey }) }),
5488
5578
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
5489
- type !== "string" && type !== "json" && type !== "search" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Add item", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { onClick: handleAddItem, size: "icon-sm", "aria-label": "Add item", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "size-4 text-zinc-500 dark:text-zinc-600" }) }) }),
5490
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyActions, { dataKey, content, type })
5579
+ type !== "string" && type !== "json" && type !== "search" && !showItemActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Add item", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { onClick: handleAddItem, size: "icon-sm", "aria-label": "Add item", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "size-4 text-zinc-500 dark:text-zinc-600" }) }) }),
5580
+ showItemActions ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ItemActions, { dataKey, type }) : selectedListItem ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyActions, { dataKey, content, type })
5491
5581
  ] })
5492
5582
  ] }),
5493
5583
  type === "search" && hideTypeTag ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollArea, { orientation: "horizontal", className: "w-full whitespace-nowrap", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-max items-center gap-1.5 pb-2 pt-1", children: [
@@ -5685,13 +5775,13 @@ var MonacoEditorWithTypes = ({
5685
5775
  const theme = useTheme();
5686
5776
  _react.useEffect.call(void 0, () => {
5687
5777
  if (!monaco) return;
5688
- _optionalChain([extraLibRef, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.dispose, 'call', _43 => _43()]);
5778
+ _optionalChain([extraLibRef, 'access', _45 => _45.current, 'optionalAccess', _46 => _46.dispose, 'call', _47 => _47()]);
5689
5779
  extraLibRef.current = monaco.languages.typescript.typescriptDefaults.addExtraLib(
5690
5780
  typeDefinitions,
5691
5781
  `file:///${filePath.replace(".ts", "-types.d.ts")}`
5692
5782
  );
5693
5783
  requestAnimationFrame(() => {
5694
- const model = _optionalChain([editorRef, 'access', _44 => _44.current, 'optionalAccess', _45 => _45.getModel, 'optionalCall', _46 => _46()]);
5784
+ const model = _optionalChain([editorRef, 'access', _48 => _48.current, 'optionalAccess', _49 => _49.getModel, 'optionalCall', _50 => _50()]);
5695
5785
  if (model) {
5696
5786
  const currentValue = model.getValue();
5697
5787
  model.setValue(currentValue);
@@ -5700,10 +5790,10 @@ var MonacoEditorWithTypes = ({
5700
5790
  }, [monaco, typeDefinitions, filePath]);
5701
5791
  _react.useEffect.call(void 0, () => {
5702
5792
  return () => {
5703
- _optionalChain([extraLibRef, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.dispose, 'call', _49 => _49()]);
5793
+ _optionalChain([extraLibRef, 'access', _51 => _51.current, 'optionalAccess', _52 => _52.dispose, 'call', _53 => _53()]);
5704
5794
  if (monaco) {
5705
5795
  const model = monaco.editor.getModel(monaco.Uri.parse(filePath));
5706
- _optionalChain([model, 'optionalAccess', _50 => _50.dispose, 'call', _51 => _51()]);
5796
+ _optionalChain([model, 'optionalAccess', _54 => _54.dispose, 'call', _55 => _55()]);
5707
5797
  }
5708
5798
  };
5709
5799
  }, [monaco, filePath]);
@@ -5713,7 +5803,7 @@ var MonacoEditorWithTypes = ({
5713
5803
  } else if (newValue.trim() === "") {
5714
5804
  onChange(defaultValue);
5715
5805
  } else {
5716
- _optionalChain([editorRef, 'access', _52 => _52.current, 'optionalAccess', _53 => _53.setValue, 'optionalCall', _54 => _54(valueRef.current)]);
5806
+ _optionalChain([editorRef, 'access', _56 => _56.current, 'optionalAccess', _57 => _57.setValue, 'optionalCall', _58 => _58(valueRef.current)]);
5717
5807
  }
5718
5808
  };
5719
5809
  _react.useEffect.call(void 0, () => {
@@ -5953,11 +6043,31 @@ declare class DateFieldBuilder<Fast extends Record<"fast", boolean> = {
5953
6043
  from: TFrom["from"];
5954
6044
  } : { type: "DATE" };
5955
6045
  }
5956
- declare class KeywordFieldBuilder {
5957
- [BUILD](): { type: "KEYWORD" };
6046
+ declare class KeywordFieldBuilder<TFrom extends Record<"from", string | null> = {
6047
+ from: null;
6048
+ }> {
6049
+ private _from;
6050
+ constructor(from?: TFrom);
6051
+ from(field: string): KeywordFieldBuilder<{
6052
+ from: string;
6053
+ }>;
6054
+ [BUILD](): TFrom["from"] extends string ? {
6055
+ type: "KEYWORD";
6056
+ from: TFrom["from"];
6057
+ } : { type: "KEYWORD" };
5958
6058
  }
5959
- declare class FacetFieldBuilder {
5960
- [BUILD](): { type: "FACET" };
6059
+ declare class FacetFieldBuilder<TFrom extends Record<"from", string | null> = {
6060
+ from: null;
6061
+ }> {
6062
+ private _from;
6063
+ constructor(from?: TFrom);
6064
+ from(field: string): FacetFieldBuilder<{
6065
+ from: string;
6066
+ }>;
6067
+ [BUILD](): TFrom["from"] extends string ? {
6068
+ type: "FACET";
6069
+ from: TFrom["from"];
6070
+ } : { type: "FACET" };
5961
6071
  }
5962
6072
  type FieldBuilder = TextFieldBuilder<{
5963
6073
  noTokenize: boolean;
@@ -5975,7 +6085,11 @@ type FieldBuilder = TextFieldBuilder<{
5975
6085
  fast: boolean;
5976
6086
  }, {
5977
6087
  from: string | null;
5978
- }> | KeywordFieldBuilder | FacetFieldBuilder;
6088
+ }> | KeywordFieldBuilder<{
6089
+ from: string | null;
6090
+ }> | FacetFieldBuilder<{
6091
+ from: string | null;
6092
+ }>;
5979
6093
  declare const s: {
5980
6094
  string(): TextFieldBuilder;
5981
6095
  number<T extends NumericField["type"] = "F64">(type?: T): NumericFieldBuilder<T>;
@@ -6180,7 +6294,7 @@ var SearchDisplay = ({
6180
6294
  indexName: _nullishCoalesce(indexName, () => ( "")),
6181
6295
  editorValue: data.schema ? schemaToEditorValue(data.schema) : SCHEMA_DEFAULT,
6182
6296
  dataType: data.dataType || "string",
6183
- prefixes: _optionalChain([data, 'access', _55 => _55.prefixes, 'optionalAccess', _56 => _56.join, 'call', _57 => _57(", ")]) || "",
6297
+ prefixes: _optionalChain([data, 'access', _59 => _59.prefixes, 'optionalAccess', _60 => _60.join, 'call', _61 => _61(", ")]) || "",
6184
6298
  language: data.language || "english"
6185
6299
  });
6186
6300
  }, [data, reset, indexName]);
@@ -6296,7 +6410,7 @@ var SearchDisplay = ({
6296
6410
  DocsLink,
6297
6411
  {
6298
6412
  className: "absolute bottom-2 right-2 text-sm",
6299
- href: "https://upstash-search.mintlify.app/redis/search/schema-definition"
6413
+ href: "https://upstash.com/docs/redis/search/schema-definition"
6300
6414
  }
6301
6415
  )
6302
6416
  ] }),
@@ -6553,7 +6667,7 @@ var ItemContextMenu = ({
6553
6667
  editItem({
6554
6668
  type,
6555
6669
  dataKey,
6556
- itemKey: _optionalChain([data, 'optionalAccess', _58 => _58.key]),
6670
+ itemKey: _optionalChain([data, 'optionalAccess', _62 => _62.key]),
6557
6671
  // For deletion
6558
6672
  newKey: void 0
6559
6673
  });
@@ -6588,7 +6702,7 @@ var ItemContextMenu = ({
6588
6702
  {
6589
6703
  onClick: () => {
6590
6704
  if (!data) return;
6591
- navigator.clipboard.writeText(_optionalChain([data, 'optionalAccess', _59 => _59.key]));
6705
+ navigator.clipboard.writeText(_optionalChain([data, 'optionalAccess', _63 => _63.key]));
6592
6706
  toast({
6593
6707
  description: "Key copied to clipboard"
6594
6708
  });
@@ -6600,11 +6714,11 @@ var ItemContextMenu = ({
6600
6714
  ]
6601
6715
  }
6602
6716
  ),
6603
- _optionalChain([data, 'optionalAccess', _60 => _60.value]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6717
+ _optionalChain([data, 'optionalAccess', _64 => _64.value]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6604
6718
  ContextMenuItem,
6605
6719
  {
6606
6720
  onClick: () => {
6607
- navigator.clipboard.writeText(_nullishCoalesce(_optionalChain([data, 'optionalAccess', _61 => _61.value]), () => ( "")));
6721
+ navigator.clipboard.writeText(_nullishCoalesce(_optionalChain([data, 'optionalAccess', _65 => _65.value]), () => ( "")));
6608
6722
  toast({
6609
6723
  description: "Value copied to clipboard"
6610
6724
  });
@@ -6716,7 +6830,7 @@ var useSetHashTTL = () => {
6716
6830
  var HashFieldTTLBadge = ({ dataKey, field }) => {
6717
6831
  const { data } = useFetchHashFieldExpires({ dataKey, fields: [field] });
6718
6832
  const { mutate: setTTL, isPending } = useSetHashTTL();
6719
- const expireAt = _optionalChain([data, 'optionalAccess', _62 => _62[field]]);
6833
+ const expireAt = _optionalChain([data, 'optionalAccess', _66 => _66[field]]);
6720
6834
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6721
6835
  TTLBadge,
6722
6836
  {
@@ -6813,7 +6927,7 @@ var MonacoEditor = ({
6813
6927
  if (!active || !monaco || !editorRef.current) {
6814
6928
  return;
6815
6929
  }
6816
- _optionalChain([monaco, 'optionalAccess', _63 => _63.editor, 'access', _64 => _64.setModelLanguage, 'call', _65 => _65(editorRef.current.getModel(), language)]);
6930
+ _optionalChain([monaco, 'optionalAccess', _67 => _67.editor, 'access', _68 => _68.setModelLanguage, 'call', _69 => _69(editorRef.current.getModel(), language)]);
6817
6931
  }, [monaco, language, active]);
6818
6932
  const editor = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6819
6933
  _react2.Editor,
@@ -6989,7 +7103,7 @@ var ListEditForm = ({
6989
7103
  dataKey
6990
7104
  });
6991
7105
  const findValue = () => {
6992
- for (const page of _nullishCoalesce(_optionalChain([query, 'access', _66 => _66.data, 'optionalAccess', _67 => _67.pages]), () => ( []))) {
7106
+ for (const page of _nullishCoalesce(_optionalChain([query, 'access', _70 => _70.data, 'optionalAccess', _71 => _71.pages]), () => ( []))) {
6993
7107
  const item = page.keys.find((item2) => item2.key === itemKey);
6994
7108
  if (item && "value" in item) return item.value;
6995
7109
  }
@@ -7019,11 +7133,19 @@ var ListEditForm = ({
7019
7133
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacthookform.FormProvider, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit, className: "flex h-full min-h-0 flex-col gap-2", children: [
7020
7134
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-h-0 grow flex-col gap-2", children: [
7021
7135
  type === "zset" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NumberFormItem, { name: "value", label: valueLabel }),
7022
- type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItem, { readOnly: type === "stream", name: "key", label: keyLabel, data: itemKey }),
7136
+ type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7137
+ FormItem,
7138
+ {
7139
+ readOnly: type === "stream" && !isNew,
7140
+ name: "key",
7141
+ label: keyLabel,
7142
+ data: itemKey
7143
+ }
7144
+ ),
7023
7145
  type !== "set" && type !== "zset" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7024
7146
  FormItem,
7025
7147
  {
7026
- readOnly: type === "stream",
7148
+ readOnly: type === "stream" && !isNew,
7027
7149
  name: "value",
7028
7150
  label: valueLabel,
7029
7151
  data: _nullishCoalesce(itemValue, () => ( ""))
@@ -7060,7 +7182,7 @@ var ListEditForm = ({
7060
7182
  variant: "primary",
7061
7183
  type: "submit",
7062
7184
  disabled: !form.formState.isValid || !form.formState.isDirty || type === "stream" && !isNew,
7063
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: isPending, isLoadingText: "Saving", children: "Save" })
7185
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: isPending, isLoadingText: isNew ? "Adding" : "Saving", children: isNew ? "Add Item" : "Save" })
7064
7186
  }
7065
7187
  )
7066
7188
  }
@@ -7135,7 +7257,7 @@ var HashFieldTTLInfo = ({
7135
7257
  fields
7136
7258
  }) => {
7137
7259
  const { data } = useFetchHashFieldExpires({ dataKey, fields });
7138
- const expireAt = _optionalChain([data, 'optionalAccess', _68 => _68[field]]);
7260
+ const expireAt = _optionalChain([data, 'optionalAccess', _72 => _72[field]]);
7139
7261
  const [ttl, setTTL] = _react.useState.call(void 0, () => calculateTTL(expireAt));
7140
7262
  _react.useEffect.call(void 0, () => {
7141
7263
  setTTL(calculateTTL(expireAt));
@@ -7160,7 +7282,7 @@ var headerLabels = {
7160
7282
  var ListDisplay = ({ dataKey, type }) => {
7161
7283
  const { selectedListItem } = useTab();
7162
7284
  const query = useFetchListItems({ dataKey, type });
7163
- const isEmpty = query.isFetched && _optionalChain([query, 'access', _69 => _69.data, 'optionalAccess', _70 => _70.pages, 'access', _71 => _71.every, 'call', _72 => _72((page) => page.keys.length === 0)]);
7285
+ const isEmpty = query.isFetched && _optionalChain([query, 'access', _73 => _73.data, 'optionalAccess', _74 => _74.pages, 'access', _75 => _75.every, 'call', _76 => _76((page) => page.keys.length === 0)]);
7164
7286
  if (isEmpty) {
7165
7287
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyDeleted, {});
7166
7288
  }
@@ -7176,7 +7298,7 @@ var ListItems = ({
7176
7298
  dataKey
7177
7299
  }) => {
7178
7300
  const { setSelectedListItem } = useTab();
7179
- const keys = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([query, 'access', _73 => _73.data, 'optionalAccess', _74 => _74.pages, 'access', _75 => _75.flatMap, 'call', _76 => _76((page) => page.keys)]), () => ( [])), [query.data]);
7301
+ const keys = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([query, 'access', _77 => _77.data, 'optionalAccess', _78 => _78.pages, 'access', _79 => _79.flatMap, 'call', _80 => _80((page) => page.keys)]), () => ( [])), [query.data]);
7180
7302
  const fields = _react.useMemo.call(void 0, () => keys.map((key) => key.key), [keys]);
7181
7303
  const { mutate: editItem } = useEditListItem();
7182
7304
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: keys.map(({ key, value }, i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -7327,6 +7449,7 @@ var DataDisplay = () => {
7327
7449
 
7328
7450
 
7329
7451
 
7452
+
7330
7453
  // src/components/databrowser/components/add-key-modal.tsx
7331
7454
 
7332
7455
 
@@ -7348,7 +7471,7 @@ function AddKeyModal() {
7348
7471
  setSelectedKey(key);
7349
7472
  setOpen(false);
7350
7473
  setTimeout(() => {
7351
- _optionalChain([window, 'access', _77 => _77.document, 'access', _78 => _78.querySelector, 'call', _79 => _79(`[data-key="${key}"]`), 'optionalAccess', _80 => _80.scrollIntoView, 'call', _81 => _81({
7474
+ _optionalChain([window, 'access', _81 => _81.document, 'access', _82 => _82.querySelector, 'call', _83 => _83(`[data-key="${key}"]`), 'optionalAccess', _84 => _84.scrollIntoView, 'call', _85 => _85({
7352
7475
  behavior: "smooth",
7353
7476
  block: "start",
7354
7477
  inline: "nearest"
@@ -7404,7 +7527,7 @@ function AddKeyModal() {
7404
7527
  }
7405
7528
  )
7406
7529
  ] }),
7407
- formState.errors.key && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-3 mt-2 text-xs text-red-500", children: _optionalChain([formState, 'access', _82 => _82.errors, 'access', _83 => _83.key, 'optionalAccess', _84 => _84.message]) }),
7530
+ formState.errors.key && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-3 mt-2 text-xs text-red-500", children: _optionalChain([formState, 'access', _86 => _86.errors, 'access', _87 => _87.key, 'optionalAccess', _88 => _88.message]) }),
7408
7531
  /* @__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" }),
7409
7532
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-6 flex justify-end gap-2", children: [
7410
7533
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -7432,6 +7555,31 @@ function AddKeyModal() {
7432
7555
 
7433
7556
 
7434
7557
 
7558
+ // src/lib/scan-keys.ts
7559
+ async function scanKeys(redis, {
7560
+ match,
7561
+ type,
7562
+ count: count2 = 100,
7563
+ limit
7564
+ } = {}) {
7565
+ let cursor = "0";
7566
+ const result = [];
7567
+ while (true) {
7568
+ const [newCursor, keys] = await redis.scan(cursor, {
7569
+ count: count2,
7570
+ type,
7571
+ match
7572
+ });
7573
+ result.push(...keys);
7574
+ if (limit && result.length >= limit) {
7575
+ return result.slice(0, limit);
7576
+ }
7577
+ if (newCursor === "0") break;
7578
+ cursor = newCursor;
7579
+ }
7580
+ return result;
7581
+ }
7582
+
7435
7583
  // src/components/databrowser/components/query-wizard/consent-prompt.tsx
7436
7584
 
7437
7585
 
@@ -7527,10 +7675,12 @@ export type DateField = {
7527
7675
 
7528
7676
  export type KeywordField = {
7529
7677
  type: "KEYWORD";
7678
+ from?: string;
7530
7679
  };
7531
7680
 
7532
7681
  export type FacetField = {
7533
7682
  type: "FACET";
7683
+ from?: string;
7534
7684
  };
7535
7685
 
7536
7686
  export type DetailedField =
@@ -8417,7 +8567,7 @@ var QueryWizardPopover = ({ onClose }) => {
8417
8567
  const fetchSampleKeys = _reactquery.useMutation.call(void 0, {
8418
8568
  mutationFn: async (index) => {
8419
8569
  const firstTenKeys = await scanKeys(redis, {
8420
- match: `${_optionalChain([index, 'access', _85 => _85.prefixes, 'optionalAccess', _86 => _86[0]])}*`,
8570
+ match: `${_optionalChain([index, 'access', _89 => _89.prefixes, 'optionalAccess', _90 => _90[0]])}*`,
8421
8571
  type: index.dataType,
8422
8572
  limit: 10
8423
8573
  });
@@ -8447,7 +8597,7 @@ var QueryWizardPopover = ({ onClose }) => {
8447
8597
  if (!input.trim() || !valuesSearch.index) return;
8448
8598
  try {
8449
8599
  let samples = sampleData;
8450
- if (samples.length === 0 && _optionalChain([indexData, 'optionalAccess', _87 => _87.prefixes, 'optionalAccess', _88 => _88[0]])) {
8600
+ if (samples.length === 0 && _optionalChain([indexData, 'optionalAccess', _91 => _91.prefixes, 'optionalAccess', _92 => _92[0]])) {
8451
8601
  samples = await fetchSampleKeys.mutateAsync(indexData);
8452
8602
  }
8453
8603
  const result = await generateQuery.mutateAsync({
@@ -8458,7 +8608,7 @@ var QueryWizardPopover = ({ onClose }) => {
8458
8608
  const queryString = toJsLiteral(result.query);
8459
8609
  setValuesSearchQuery(queryString);
8460
8610
  setQueryBuilderMode("code");
8461
- _optionalChain([onClose, 'optionalCall', _89 => _89()]);
8611
+ _optionalChain([onClose, 'optionalCall', _93 => _93()]);
8462
8612
  } catch (error) {
8463
8613
  console.error("Error generating query:", error);
8464
8614
  }
@@ -8518,7 +8668,7 @@ var QueryWizardPopover = ({ onClose }) => {
8518
8668
  ),
8519
8669
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
8520
8670
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs text-zinc-500", children: 'Example: Find people named "John", boost if older than 20.' }),
8521
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/overview" })
8671
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash.com/docs/redis/search/query-operators/boolean-operators/overview" })
8522
8672
  ] })
8523
8673
  ] })
8524
8674
  ] }),
@@ -8563,7 +8713,7 @@ var CreateIndexModal = ({
8563
8713
  className: "max-w-2xl",
8564
8714
  onEscapeKeyDown: (e) => {
8565
8715
  const active = document.activeElement;
8566
- if (_optionalChain([active, 'optionalAccess', _90 => _90.closest, 'call', _91 => _91(".monaco-editor")]) || _optionalChain([active, 'optionalAccess', _92 => _92.tagName]) === "TEXTAREA") {
8716
+ if (_optionalChain([active, 'optionalAccess', _94 => _94.closest, 'call', _95 => _95(".monaco-editor")]) || _optionalChain([active, 'optionalAccess', _96 => _96.tagName]) === "TEXTAREA") {
8567
8717
  e.preventDefault();
8568
8718
  }
8569
8719
  },
@@ -8598,7 +8748,7 @@ var EditIndexModal = ({
8598
8748
  className: "min-h-[500px] max-w-2xl",
8599
8749
  onEscapeKeyDown: (e) => {
8600
8750
  const active = document.activeElement;
8601
- if (_optionalChain([active, 'optionalAccess', _93 => _93.closest, 'call', _94 => _94(".monaco-editor")]) || _optionalChain([active, 'optionalAccess', _95 => _95.tagName]) === "TEXTAREA") {
8751
+ if (_optionalChain([active, 'optionalAccess', _97 => _97.closest, 'call', _98 => _98(".monaco-editor")]) || _optionalChain([active, 'optionalAccess', _99 => _99.tagName]) === "TEXTAREA") {
8602
8752
  e.preventDefault();
8603
8753
  }
8604
8754
  },
@@ -8712,7 +8862,7 @@ var SearchInput = () => {
8712
8862
  } else if (e.key === "Escape") {
8713
8863
  setState("");
8714
8864
  setFocusedIndex(-1);
8715
- _optionalChain([inputRef, 'access', _96 => _96.current, 'optionalAccess', _97 => _97.blur, 'call', _98 => _98()]);
8865
+ _optionalChain([inputRef, 'access', _100 => _100.current, 'optionalAccess', _101 => _101.blur, 'call', _102 => _102()]);
8716
8866
  } else if (e.key === "ArrowDown" || e.key === "Tab" && !e.shiftKey) {
8717
8867
  e.preventDefault();
8718
8868
  if (focusedIndex < filteredHistory.length - 1) {
@@ -8726,7 +8876,7 @@ var SearchInput = () => {
8726
8876
  setFocusedIndex(focusedIndex - 1);
8727
8877
  } else if (filteredHistory.length > 0 && focusedIndex === 0) {
8728
8878
  setFocusedIndex(-1);
8729
- _optionalChain([inputRef, 'access', _99 => _99.current, 'optionalAccess', _100 => _100.focus, 'call', _101 => _101()]);
8879
+ _optionalChain([inputRef, 'access', _103 => _103.current, 'optionalAccess', _104 => _104.focus, 'call', _105 => _105()]);
8730
8880
  } else if (filteredHistory.length > 0) {
8731
8881
  setFocusedIndex(filteredHistory.length - 1);
8732
8882
  }
@@ -8874,19 +9024,26 @@ var IndexSelector = () => {
8874
9024
  valuesSearch: { index },
8875
9025
  setValuesSearchIndex
8876
9026
  } = useTab();
8877
- const { data: indexes, isLoading } = useFetchSearchIndexes();
8878
9027
  const [open, setOpen] = _react.useState.call(void 0, false);
9028
+ const [search, setSearch] = _react.useState.call(void 0, "");
9029
+ const debouncedSearch = useDebounce(search, 150);
9030
+ const match = debouncedSearch ? `${debouncedSearch}*` : void 0;
9031
+ const {
9032
+ data: indexes,
9033
+ isLoading,
9034
+ hasNextPage,
9035
+ fetchNextPage,
9036
+ isFetchingNextPage
9037
+ } = useFetchSearchIndexes({ match });
9038
+ const [editingIndex, setEditingIndex] = _react.useState.call(void 0, );
8879
9039
  _react.useEffect.call(void 0, () => {
8880
- if (!indexes || isLoading) return;
9040
+ if (!indexes || isLoading || debouncedSearch) return;
8881
9041
  if (index && !indexes.includes(index)) {
8882
9042
  setValuesSearchIndex("");
8883
9043
  } else if (!index && indexes.length > 0) {
8884
9044
  setValuesSearchIndex(indexes[0]);
8885
9045
  }
8886
- }, [indexes, index, isLoading, setValuesSearchIndex]);
8887
- const [search, setSearch] = _react.useState.call(void 0, "");
8888
- const [editingIndex, setEditingIndex] = _react.useState.call(void 0, );
8889
- const filteredIndexes = _optionalChain([indexes, 'optionalAccess', _102 => _102.filter, 'call', _103 => _103((idx) => idx.toLowerCase().includes(search.toLowerCase()))]);
9046
+ }, [indexes, index, isLoading, setValuesSearchIndex, debouncedSearch]);
8890
9047
  const handleEditIndex = (indexName) => {
8891
9048
  setOpen(false);
8892
9049
  setEditingIndex(indexName);
@@ -8923,8 +9080,9 @@ var IndexSelector = () => {
8923
9080
  )
8924
9081
  ] }),
8925
9082
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "max-h-[200px] overflow-y-auto", children: [
8926
- _optionalChain([filteredIndexes, 'optionalAccess', _104 => _104.length]) === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "py-4 text-center text-sm text-zinc-500", children: "No indexes found" }),
8927
- _optionalChain([filteredIndexes, 'optionalAccess', _105 => _105.map, 'call', _106 => _106((idx) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
9083
+ isLoading && !indexes && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconLoader2, { className: "size-4 animate-spin text-zinc-400" }) }),
9084
+ !isLoading && _optionalChain([indexes, 'optionalAccess', _106 => _106.length]) === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "py-4 text-center text-sm text-zinc-500", children: "No indexes found" }),
9085
+ _optionalChain([indexes, 'optionalAccess', _107 => _107.map, 'call', _108 => _108((idx) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8928
9086
  "div",
8929
9087
  {
8930
9088
  className: "flex h-9 items-center rounded-md px-2 transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-200",
@@ -8967,7 +9125,16 @@ var IndexSelector = () => {
8967
9125
  ]
8968
9126
  },
8969
9127
  idx
8970
- ))])
9128
+ ))]),
9129
+ hasNextPage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9130
+ "button",
9131
+ {
9132
+ onClick: () => fetchNextPage(),
9133
+ disabled: isFetchingNextPage,
9134
+ className: "flex h-9 w-full items-center justify-center rounded-md text-sm text-emerald-600 transition-colors hover:bg-zinc-100 disabled:opacity-50",
9135
+ children: isFetchingNextPage ? "Loading..." : "Load more"
9136
+ }
9137
+ )
8971
9138
  ] })
8972
9139
  ] }) })
8973
9140
  ]
@@ -9083,7 +9250,7 @@ var generateNestedInterface = (obj, indent = " ") => {
9083
9250
  var toAmbientTypes = (types) => types.replaceAll(/export const (\w+) = (\[.*?]) as const;/g, "declare const $1: readonly $2;").replaceAll("export ", "");
9084
9251
  var generateTypeDefinitions = (schema) => {
9085
9252
  let schemaFieldsInterface = "";
9086
- const schemaFields = _optionalChain([schema, 'optionalAccess', _107 => _107.schema]);
9253
+ const schemaFields = _optionalChain([schema, 'optionalAccess', _109 => _109.schema]);
9087
9254
  if (schemaFields && Object.keys(schemaFields).length > 0) {
9088
9255
  const nested = buildNestedSchema(schemaFields);
9089
9256
  const fieldLines = generateNestedInterface(nested);
@@ -9477,7 +9644,7 @@ var SearchEmptyState = () => {
9477
9644
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9478
9645
  "a",
9479
9646
  {
9480
- href: "https://upstash-search.mintlify.app/redis/search/introduction",
9647
+ href: "https://upstash.com/docs/redis/search/introduction",
9481
9648
  target: "_blank",
9482
9649
  rel: "noopener noreferrer",
9483
9650
  className: "mt-5 inline-block text-sm text-emerald-600 underline-offset-2 hover:underline",
@@ -9541,7 +9708,7 @@ var SidebarContextMenu = ({ children }) => {
9541
9708
  showReindex: isValuesSearchSelected,
9542
9709
  onDeleteConfirm: async (e, options) => {
9543
9710
  e.stopPropagation();
9544
- await deleteKey({ keys: contextKeys, reindex: _optionalChain([options, 'optionalAccess', _108 => _108.reindex]) });
9711
+ await deleteKey({ keys: contextKeys, reindex: _optionalChain([options, 'optionalAccess', _110 => _110.reindex]) });
9545
9712
  setAlertOpen(false);
9546
9713
  }
9547
9714
  }
@@ -10315,7 +10482,7 @@ var BoostBadge = ({
10315
10482
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `flex h-full cursor-default items-center px-2 ${labelBg} ${textColor}`, children: isNegative ? "Demote" : "Boost" }) }),
10316
10483
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TooltipContent, { side: "bottom", className: "max-w-xs", children: [
10317
10484
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: isNegative ? `Multiplies this condition's score by ${_nullishCoalesce(node.boost, () => ( 0))}, subtracting from the total.` : `Multiplies this condition's score by ${_nullishCoalesce(node.boost, () => ( 0))}.` }),
10318
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/boost" })
10485
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash.com/docs/redis/search/query-operators/boolean-operators/boost" })
10319
10486
  ] })
10320
10487
  ] }),
10321
10488
  isStatic ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `px-2 ${textColor}`, children: node.boost }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex h-full items-center bg-white px-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -10437,7 +10604,7 @@ var QueryCondition = ({
10437
10604
  setLocalValue(formattedConditionValue);
10438
10605
  }
10439
10606
  const currentFieldInfo = fieldInfos.find((f) => f.name === condition.field);
10440
- const currentFieldType = _nullishCoalesce(_optionalChain([currentFieldInfo, 'optionalAccess', _109 => _109.type]), () => ( "unknown"));
10607
+ const currentFieldType = _nullishCoalesce(_optionalChain([currentFieldInfo, 'optionalAccess', _111 => _111.type]), () => ( "unknown"));
10441
10608
  const isUnknownField = condition.field && !fieldNames.includes(condition.field);
10442
10609
  const getValueTypeError = () => {
10443
10610
  if (isUnknownField || currentFieldType === "unknown" || currentFieldType === "string") {
@@ -10495,8 +10662,8 @@ var QueryCondition = ({
10495
10662
  }
10496
10663
  }, [currentFieldType, condition.value]);
10497
10664
  const handleFieldChange = (value) => {
10498
- const newFieldInfo = _optionalChain([fieldInfos, 'optionalAccess', _110 => _110.find, 'call', _111 => _111((f) => f.name === value)]);
10499
- const newFieldType = _nullishCoalesce(_optionalChain([newFieldInfo, 'optionalAccess', _112 => _112.type]), () => ( "unknown"));
10665
+ const newFieldInfo = _optionalChain([fieldInfos, 'optionalAccess', _112 => _112.find, 'call', _113 => _113((f) => f.name === value)]);
10666
+ const newFieldType = _nullishCoalesce(_optionalChain([newFieldInfo, 'optionalAccess', _114 => _114.type]), () => ( "unknown"));
10500
10667
  const validOperators = getOperatorsForFieldType(newFieldType);
10501
10668
  const isOperatorValid = validOperators.includes(condition.operator);
10502
10669
  let newValue = condition.value;
@@ -10637,10 +10804,10 @@ var QueryCondition = ({
10637
10804
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10638
10805
  "div",
10639
10806
  {
10640
- ref: _optionalChain([dragHandleProps, 'optionalAccess', _113 => _113.ref]),
10807
+ ref: _optionalChain([dragHandleProps, 'optionalAccess', _115 => _115.ref]),
10641
10808
  className: "flex cursor-grab items-center px-1 text-zinc-400 hover:text-zinc-600",
10642
- ..._optionalChain([dragHandleProps, 'optionalAccess', _114 => _114.attributes]),
10643
- ..._optionalChain([dragHandleProps, 'optionalAccess', _115 => _115.listeners]),
10809
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _116 => _116.attributes]),
10810
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _117 => _117.listeners]),
10644
10811
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconGripVertical, { size: 16 })
10645
10812
  }
10646
10813
  ),
@@ -11148,10 +11315,10 @@ var InnerGroup = ({
11148
11315
  !isRoot && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11149
11316
  "div",
11150
11317
  {
11151
- ref: _optionalChain([dragHandleProps, 'optionalAccess', _116 => _116.ref]),
11318
+ ref: _optionalChain([dragHandleProps, 'optionalAccess', _118 => _118.ref]),
11152
11319
  className: "flex cursor-grab items-center px-1 text-zinc-400",
11153
- ..._optionalChain([dragHandleProps, 'optionalAccess', _117 => _117.attributes]),
11154
- ..._optionalChain([dragHandleProps, 'optionalAccess', _118 => _118.listeners]),
11320
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _119 => _119.attributes]),
11321
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _120 => _120.listeners]),
11155
11322
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconGripVertical, { size: 16 })
11156
11323
  }
11157
11324
  ),
@@ -11223,7 +11390,7 @@ var InnerGroup = ({
11223
11390
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "ml-2 mt-2 flex h-[26px] w-fit cursor-default select-none items-center rounded-md border border-zinc-300 bg-amber-50 px-2 text-sm font-medium capitalize text-amber-800", children: "Must Not" }) }),
11224
11391
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TooltipContent, { side: "right", className: "max-w-xs", children: [
11225
11392
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Keys matching any of the conditions below are excluded from the results." }),
11226
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/must-not" })
11393
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash.com/docs/redis/search/query-operators/boolean-operators/must-not" })
11227
11394
  ] })
11228
11395
  ] }),
11229
11396
  node.children.map(
@@ -11500,7 +11667,7 @@ var UIQueryBuilder = () => {
11500
11667
  const { valuesSearch } = useTab();
11501
11668
  const { data: indexDetails } = useFetchSearchIndex(valuesSearch.index);
11502
11669
  const { queryState, setQueryState } = useQueryStateSync();
11503
- const fieldInfos = _optionalChain([indexDetails, 'optionalAccess', _119 => _119.schema]) ? extractFieldInfo(indexDetails.schema) : [];
11670
+ const fieldInfos = _optionalChain([indexDetails, 'optionalAccess', _121 => _121.schema]) ? extractFieldInfo(indexDetails.schema) : [];
11504
11671
  const hasNormalized = _react.useRef.call(void 0, false);
11505
11672
  _react.useEffect.call(void 0, () => {
11506
11673
  if (hasNormalized.current || fieldInfos.length === 0) return;
@@ -11519,7 +11686,7 @@ var UIQueryBuilder = () => {
11519
11686
  setHasBottomShadow(scrollTop + clientHeight < scrollHeight - 1);
11520
11687
  }, []);
11521
11688
  _react.useEffect.call(void 0, () => {
11522
- viewportRef.current = _optionalChain([scrollAreaRef, 'access', _120 => _120.current, 'optionalAccess', _121 => _121.querySelector, 'call', _122 => _122(
11689
+ viewportRef.current = _optionalChain([scrollAreaRef, 'access', _122 => _122.current, 'optionalAccess', _123 => _123.querySelector, 'call', _124 => _124(
11523
11690
  "[data-radix-scroll-area-viewport]"
11524
11691
  )]);
11525
11692
  recomputeShadows();
@@ -11663,7 +11830,7 @@ var QueryBuilderContent = () => {
11663
11830
  DocsLink,
11664
11831
  {
11665
11832
  className: "absolute bottom-2 right-2 text-sm",
11666
- href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/overview"
11833
+ href: "https://upstash.com/docs/redis/search/query-operators/boolean-operators/overview"
11667
11834
  }
11668
11835
  )
11669
11836
  ] });
@@ -11868,7 +12035,7 @@ var useOverflow = () => {
11868
12035
  }
11869
12036
  if (!node) return;
11870
12037
  observerRef.current = new ResizeObserver((entries) => {
11871
- const el = _optionalChain([entries, 'access', _123 => _123.at, 'call', _124 => _124(0), 'optionalAccess', _125 => _125.target]);
12038
+ const el = _optionalChain([entries, 'access', _125 => _125.at, 'call', _126 => _126(0), 'optionalAccess', _127 => _127.target]);
11872
12039
  if (!el) return;
11873
12040
  setIsOverflow(el.scrollWidth > el.clientWidth);
11874
12041
  });
@@ -11876,7 +12043,7 @@ var useOverflow = () => {
11876
12043
  }, []);
11877
12044
  _react.useEffect.call(void 0, () => {
11878
12045
  return () => {
11879
- _optionalChain([observerRef, 'access', _126 => _126.current, 'optionalAccess', _127 => _127.disconnect, 'call', _128 => _128()]);
12046
+ _optionalChain([observerRef, 'access', _128 => _128.current, 'optionalAccess', _129 => _129.disconnect, 'call', _130 => _130()]);
11880
12047
  };
11881
12048
  }, []);
11882
12049
  return { ref, isOverflow };
@@ -11994,8 +12161,8 @@ var SortableTab = ({ id }) => {
11994
12161
  const [originalWidth, setOriginalWidth] = _react.useState.call(void 0, null);
11995
12162
  const textRef = _react.useRef.call(void 0, null);
11996
12163
  const { tabs } = useDatabrowserStore();
11997
- const tabData = _optionalChain([tabs, 'access', _129 => _129.find, 'call', _130 => _130(([tabId]) => tabId === id), 'optionalAccess', _131 => _131[1]]);
11998
- const isPinned = _optionalChain([tabData, 'optionalAccess', _132 => _132.pinned]);
12164
+ const tabData = _optionalChain([tabs, 'access', _131 => _131.find, 'call', _132 => _132(([tabId]) => tabId === id), 'optionalAccess', _133 => _133[1]]);
12165
+ const isPinned = _optionalChain([tabData, 'optionalAccess', _134 => _134.pinned]);
11999
12166
  const { attributes, listeners: listeners2, setNodeRef, transform, transition, isDragging } = _sortable.useSortable.call(void 0, {
12000
12167
  id,
12001
12168
  disabled: isPinned,
@@ -12211,7 +12378,7 @@ function AddTabButton() {
12211
12378
  const tabsId = addTab();
12212
12379
  selectTab(tabsId);
12213
12380
  setTimeout(() => {
12214
- const tab = _optionalChain([rootRef, 'optionalAccess', _133 => _133.current, 'optionalAccess', _134 => _134.querySelector, 'call', _135 => _135(`#tab-${tabsId}`)]);
12381
+ const tab = _optionalChain([rootRef, 'optionalAccess', _135 => _135.current, 'optionalAccess', _136 => _136.querySelector, 'call', _137 => _137(`#tab-${tabsId}`)]);
12215
12382
  if (!tab) return;
12216
12383
  tab.scrollIntoView({ behavior: "smooth" });
12217
12384
  }, 20);
@@ -12245,7 +12412,7 @@ function TabsListButton({
12245
12412
  onSelectTab(id);
12246
12413
  setOpen(false);
12247
12414
  setTimeout(() => {
12248
- const tab = _optionalChain([rootRef, 'optionalAccess', _136 => _136.current, 'optionalAccess', _137 => _137.querySelector, 'call', _138 => _138(`#tab-${id}`)]);
12415
+ const tab = _optionalChain([rootRef, 'optionalAccess', _138 => _138.current, 'optionalAccess', _139 => _139.querySelector, 'call', _140 => _140(`#tab-${id}`)]);
12249
12416
  if (!tab) return;
12250
12417
  tab.scrollIntoView({ behavior: "smooth" });
12251
12418
  }, 20);