mirror of
https://github.com/Kong/insomnia.git
synced 2026-07-30 09:16:44 -04:00
* perf: rewrite command palette search to eliminate UI freezes and stale results
Problems fixed:
- clientLoader blocked navigation on every palette open, freezing the UI during
full sequential DB scan
- no AbortController: stale searches could overwrite newer results mid-type
- no debounce: every keystroke triggered a full DB traversal immediately
- React Aria's default contains filter re-filtered server-side fuzzy results,
silently dropping valid matches and making fuzzy work redundant
- no warm baseline: palette started blank until the entire load completed
Changes:
- move fuzzyMatch/fuzzyMatchAll → insomnia-data/common-src/search.ts (shared,
testable in node)
- move search logic → insomnia-data/node-src/services/helpers/command-search.ts
- per-request AbortController cancellation via abort(requestId)
- recursion depth guard (max 20) on request group traversal
- safeParent() replaces non-null assertions, safe against orphaned documents
- add CommandSearchResult type in insomnia-data/src/command-search-types.ts
- add useCommandSearch hook: 250ms debounce + abort on filter change + warm
baseline on mount
- add defaultFilter={() => true} to ComboBox, delegating all filtering to the
service
- delete routes/commands.tsx
* fix
* fix
70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { fuzzyMatch, fuzzyMatchAll } from './search';
|
|
|
|
describe('fuzzyMatch()', () => {
|
|
it('can get a positive fuzzy match on a single field', () => {
|
|
expect(fuzzyMatch('test', 'testing')).toEqual({
|
|
score: -3,
|
|
indexes: [0, 1, 2, 3],
|
|
target: 'testing',
|
|
});
|
|
expect(fuzzyMatch('tst', 'testing')).toEqual({
|
|
score: -3004,
|
|
indexes: [0, 2, 3],
|
|
target: 'testing',
|
|
});
|
|
});
|
|
|
|
it('can get a negative fuzzy match on a single field', () => {
|
|
// @ts-expect-error
|
|
expect(fuzzyMatch('foo')).toBeNull();
|
|
expect(fuzzyMatch('foo', 'bar')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('fuzzyMatchAll()', () => {
|
|
it('can get a positive fuzzy match on multiple fields', () => {
|
|
// @ts-expect-error
|
|
expect(fuzzyMatchAll('', [undefined])).toEqual(null);
|
|
expect(fuzzyMatchAll('', ['testing'])).toEqual(null);
|
|
expect(fuzzyMatchAll(' ', ['testing'])).toEqual(null);
|
|
expect(fuzzyMatchAll('test', ['testing', 'foo'])).toEqual({
|
|
score: -3,
|
|
indexes: [0, 1, 2, 3],
|
|
target: 'testing foo',
|
|
});
|
|
expect(
|
|
fuzzyMatchAll('test foo', ['testing', 'foo'], {
|
|
splitSpace: true,
|
|
}),
|
|
).toEqual({
|
|
score: 0,
|
|
indexes: [0, 1, 2, 3, 0, 1, 2],
|
|
target: 'testing foo',
|
|
});
|
|
expect(fuzzyMatchAll('tst', ['testing'])).toEqual({
|
|
score: -3004,
|
|
indexes: [0, 2, 3],
|
|
target: 'testing',
|
|
});
|
|
expect(
|
|
fuzzyMatch('tst this ou', 'testing this out', {
|
|
splitSpace: true,
|
|
loose: true,
|
|
}),
|
|
).toEqual({
|
|
score: -12.8,
|
|
indexes: [0, 2, 3, 8, 9, 10, 11, 13, 14],
|
|
target: 'testing this out',
|
|
});
|
|
});
|
|
|
|
it('can get a negative fuzzy match on multiple fields', () => {
|
|
// @ts-expect-error
|
|
expect(fuzzyMatchAll('foo', [undefined])).toEqual(null);
|
|
expect(fuzzyMatchAll('foo', ['bar'])).toEqual(null);
|
|
expect(fuzzyMatchAll('wrong this ou', ['testing', 'this', 'out'])).toEqual(null);
|
|
});
|
|
});
|