@yuktishaalaa/yuktai 5.3.6 → 5.3.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuktishaalaa/yuktai",
3
- "version": "5.3.6",
3
+ "version": "5.3.7",
4
4
  "description": "Accessibility, AI and data toolkit for Next.js, React and plain HTML: WCAG 2.2 auto-fix, agentic data grid, accessibility copilot, QA reports and in-browser RAG. Zero API keys.",
5
5
  "author": "Sandeep Miriyala — Yuktishaalaa AI Lab",
6
6
  "license": "GPL-3.0-only",
package/vanilla/README.md CHANGED
@@ -74,6 +74,7 @@ The v5.1 vanilla signature `renderGrid(container, rows, columns, options)` still
74
74
  | `parseIntent(text, ctx)` | Replace the built-in phrase parser |
75
75
  | `webmcp`, `toolName`, `toolDescriptions`, `onWebMCPStatusChange` | Expose the 11 grid tools to browser AI agents |
76
76
  | `engine` | `"ts"` (default), `"rust"`, or `"auto"` (Rust from 10,000 rows). Rust runs the same search and number/date sort faster; results are identical. `grid.engine` tells you which one is active, `await grid.whenEngineReady()` waits for it |
77
+ | `showSearchTime`, `onSearchTime` | Show "· 0.9 ms · Rust" next to the row count after each search or sort, and/or get `{ query, ms, rows, engine }` in a callback. `grid.getSearchTime()` returns the last one |
77
78
  | `referenceDate` | "Now" for "this month" questions |
78
79
  | `onRowClick(row)`, `onOpenRow(id)` | Enables the `open` tool and "open Ravi" |
79
80
  | `onSelectionChange(keys)`, `onSortChange(sort)`, `onFiltersChange(filters)`, `onAgentResult(r)` | Events |
package/vanilla/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! yuktai vanilla 5.3.5 — accessible data grid, page agents and WCAG tools for plain HTML.
1
+ /*! yuktai vanilla 5.3.7 — accessible data grid, page agents and WCAG tools for plain HTML.
2
2
  * No framework, no API keys, runs in the browser. ISC © Sandeep Miriyala, Yuktishaalaa AI Lab.
3
3
  * Built from github.com/sandeepmiriyala03/yuktai (vanilla/src + src/agentic, src/grid, src/core; grid engine in Rust: rust/grid-core). */
4
4
  "use strict";
@@ -5617,6 +5617,10 @@ Missing landmarks: ${missing.join(", ")}.` : ""}`,
5617
5617
  }
5618
5618
  }
5619
5619
  };
5620
+ function formatSearchTime(ms) {
5621
+ if (!(ms >= 0.1)) return "<0.1 ms";
5622
+ return `${ms < 10 ? ms.toFixed(1) : Math.round(ms)} ms`;
5623
+ }
5620
5624
  function pickRows(rows, positions) {
5621
5625
  const out = new Array(positions.length);
5622
5626
  for (let i = 0; i < positions.length; i++) out[i] = rows[positions[i]];
@@ -5830,21 +5834,36 @@ Missing landmarks: ${missing.join(", ")}.` : ""}`,
5830
5834
  if (!Number.isFinite(out)) out = String(av).localeCompare(String(bv));
5831
5835
  return dir === "desc" ? -out : out;
5832
5836
  }
5837
+ let lastSearchTime = null;
5838
+ let lastRunKey = null;
5833
5839
  function viewRows() {
5834
5840
  ensureCore();
5841
+ const t0 = performance.now();
5842
+ let searchedBy = null;
5843
+ let sortedBy = null;
5835
5844
  let out;
5836
5845
  const q = query ? norm3(query) : "";
5837
5846
  const found = q ? rustSearch(q) : null;
5838
5847
  if (found) {
5848
+ searchedBy = "rust";
5839
5849
  out = applyGridFilters(found, toolColumns, filters);
5840
5850
  } else {
5841
5851
  out = applyGridFilters(data, toolColumns, filters);
5842
- if (q) out = out.filter((row) => columns.some((c) => norm3(row[c.key]).includes(q) || norm3(formatPlain(c, row[c.key])).includes(q)));
5852
+ if (q) {
5853
+ searchedBy = "ts";
5854
+ out = out.filter((row) => columns.some((c) => norm3(row[c.key]).includes(q) || norm3(formatPlain(c, row[c.key])).includes(q)));
5855
+ }
5843
5856
  }
5857
+ const matched = out.length;
5844
5858
  if (sort && sort.key) {
5845
5859
  const column = columns.find((c) => c.key === sort.key);
5846
- if (column) out = rustSort(out, column, sort.direction) || out.slice().sort((a, b) => compare2(a, b, column, sort.direction));
5860
+ if (column) {
5861
+ const fast = rustSort(out, column, sort.direction);
5862
+ sortedBy = fast ? "rust" : "ts";
5863
+ out = fast || out.slice().sort((a, b) => compare2(a, b, column, sort.direction));
5864
+ }
5847
5865
  }
5866
+ lastSearchTime = searchedBy || sortedBy ? { query: q ? query : "", ms: performance.now() - t0, rows: matched, engine: searchedBy === "rust" || sortedBy === "rust" ? "rust" : "ts" } : null;
5848
5867
  return out;
5849
5868
  }
5850
5869
  let numberFormat = null;
@@ -5894,7 +5913,11 @@ Missing landmarks: ${missing.join(", ")}.` : ""}`,
5894
5913
  const current = rows.slice(start, end);
5895
5914
  host.className = `yv-grid yv-theme-${theme}${opts.wrap ? " yv-wrap" : ""}${opts.className ? " " + opts.className : ""}`;
5896
5915
  host.setAttribute("aria-busy", String(loading2));
5897
- info.textContent = `${rows.length.toLocaleString(numberLocale)} ${t.rows}${selectable ? ` \xB7 ${selected.size.toLocaleString(numberLocale)} ${t.selected}` : ""}`;
5916
+ info.textContent = `${rows.length.toLocaleString(numberLocale)} ${t.rows}${selectable ? ` \xB7 ${selected.size.toLocaleString(numberLocale)} ${t.selected}` : ""}${opts.showSearchTime && lastSearchTime ? ` \xB7 ${formatSearchTime(lastSearchTime.ms)} \xB7 ${lastSearchTime.engine === "rust" ? "Rust" : "TS"}` : ""}`;
5917
+ const runKey = lastSearchTime ? [query, sort && sort.key, sort && sort.direction, filters, data] : null;
5918
+ const changed = !runKey || !lastRunKey || runKey.some((v, i) => v !== lastRunKey[i]);
5919
+ if (lastSearchTime && changed && typeof opts.onSearchTime === "function") opts.onSearchTime({ ...lastSearchTime });
5920
+ lastRunKey = runKey;
5898
5921
  viewBtn.innerHTML = icon(isCards() ? "grid" : "cards", 18);
5899
5922
  viewBtn.setAttribute("aria-label", isCards() ? t.tableView : t.cardView);
5900
5923
  viewBtn.title = isCards() ? t.tableView : t.cardView;
@@ -6461,6 +6484,8 @@ Missing landmarks: ${missing.join(", ")}.` : ""}`,
6461
6484
  get engine() {
6462
6485
  return core && wantsRustEngine(engineOption, data.length) ? "rust" : "ts";
6463
6486
  },
6487
+ /** Last search/sort: { query, ms, rows, engine } or null. */
6488
+ getSearchTime: () => lastSearchTime ? { ...lastSearchTime } : null,
6464
6489
  /** Resolves "rust" or "ts" once the engine choice is settled. */
6465
6490
  whenEngineReady: () => ensureCore().then(() => api.engine),
6466
6491
  // highlight
@@ -7305,7 +7330,7 @@ ${command ? command.say : "Not a voice command. Try: make text bigger, high cont
7305
7330
  }
7306
7331
 
7307
7332
  // vanilla/src/index.js
7308
- var VERSION = "5.3.5";
7333
+ var VERSION = "5.3.7";
7309
7334
  (function boot() {
7310
7335
  if (!isBrowser2()) return;
7311
7336
  if (window.yuktai && window.yuktai.__vanillaInitialized) return;