@lotics/app-sdk 0.77.3 → 0.77.4

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.
@@ -407,15 +407,30 @@ pieces. Compose these — don't hand-roll search:
407
407
  search constraint and would dump the table on first paint. `enabled` makes "nothing loads until
408
408
  you type" true. Add `revalidateOnFocus: false` — re-running an ephemeral search on refocus is
409
409
  wasted work.
410
+ - **Debounce the term — `enabled` is not a substitute.** `enabled` decides *whether* to ask, not
411
+ *how often*: wire an input's own state into `params` and every keystroke past the first is a
412
+ fresh cache key and a fresh request. A six-letter name costs six, and on a list screen each one
413
+ is several — `usePaginatedQuery` re-counts whenever `params` change, and any sibling query
414
+ taking the same term goes with it. Keep the input's value in one state and debounce the COMMIT
415
+ into a second (`useDebouncedCallback` from `@lotics/ui/use_debounced_callback`, ~250 ms). The
416
+ two values are genuinely different — what is being typed, and what the rows on screen answer —
417
+ and anything reporting on the results (an empty state, a count, a "showing N for X" line) reads
418
+ the committed one, or it describes a set the server was never asked for. `Combobox` already
419
+ debounces its own `onSearchChange`; this is for a search box you built yourself.
410
420
  - **`useRecents(key, { max })`** — persist the picked option locally; pass its list as
411
421
  `recentOptions` ([./navigation_and_state.md](./navigation_and_state.md)).
412
422
 
413
423
  ```tsx
414
- const [term, setTerm] = useState(""); // live input stays local
424
+ const [typed, setTyped] = useState(""); // the input's own value, every keystroke
425
+ const [term, setTerm] = useState(""); // what the server is asked, once typing settles
426
+ const commit = useDebouncedCallback(setTerm, 250);
427
+
428
+ <SearchInput value={typed} onChangeText={(v) => { setTyped(v); commit(v.trim()); }} />;
429
+
415
430
  const { rows, loading } = useQuery(
416
431
  "searchCustomers",
417
432
  { q: term },
418
- { enabled: term.trim().length > 0, revalidateOnFocus: false },
433
+ { enabled: term.length > 0, revalidateOnFocus: false },
419
434
  );
420
435
  ```
421
436
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.77.3",
3
+ "version": "0.77.4",
4
4
  "description": "Runtime SDK for Lotics custom-code apps — typed hooks, postMessage bridge, mount entry point",
5
5
  "type": "module",
6
6
  "exports": {