Skip to content

Commit ce18d0d

Browse files
tkirda-bisonclaude
andcommitted
refactor(types): mark internal Autocomplete members as private
The class shipped 2.0.0 with no access modifiers — every method and field was implicitly public, so TypeScript consumers would see ~30 internal helpers (`initialize`, `onKeyPress`, `getSuggestions`, `groupSuggestionsByCategory`, `verifySuggestionsFormat`, etc.) as callable API without warning. That's a wider commitment than the README documents. Adds `private` to every member that isn't in the README's instance- method table or otherwise part of the recommended public API. Public surface is now exactly: - methods: setOptions, clear, clearCache, disable, enable, hide, select (per #846), dispose - fields: options (read-only by convention) - statics: Autocomplete.defaults, Autocomplete.utils Runtime is unchanged — TypeScript's `private` is a type-system contract, not a runtime fence — but the emitted `.d.ts` now reflects the actual surface area, so TS consumers will get a warning if they reach into internals. (53 `private` declarations in `dist/Autocomplete.d.ts` after this change vs 0 before.) JS callers (including the existing test suite) keep working. CLAUDE.md updated to capture the convention for future contributors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b9d5840 commit ce18d0d

4 files changed

Lines changed: 116 additions & 113 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ The minified UMD is ~13 KB; the unminified is ~26 KB.
7373
## Conventions
7474

7575
- TypeScript strict mode is on. Don't introduce `any` in public types. Internal `as unknown as X` casts are OK at jQuery boundaries where typings are imprecise.
76+
- The `Autocomplete` class explicitly marks every member `private` unless it's part of the documented public API in `readme.md` (`setOptions`, `clear`, `clearCache`, `disable`, `enable`, `hide`, `select`, `dispose`, plus the `options` field and the static `defaults`/`utils`). When adding a new member, default to `private`; only drop the keyword when you also add a row to the README's instance-method table. JS callers can still reach private members at runtime — they're a TypeScript-surface contract, not a runtime fence — but the contract is what consumers will rely on.
7677
- Methods use `this` directly. The one exception is `initialize()`, which aliases `const self = this` for the jQuery delegation handlers (`function (this: HTMLElement)`) that need both `$(this)` for the matched element AND access to the Autocomplete instance. Don't add new `that = this` aliases elsewhere — use arrow functions for callbacks instead.
7778
- Prefer native array methods (`.map`, `.filter`, `.find`, `.some`, `.indexOf`) over jQuery's `$.each` / `$.grep` / `$.map` / `$.inArray` in new code; the JS-source equivalents have already been swapped where semantics match.
7879
- Prettier owns formatting. Run `npm run format` before committing source changes.

dist/Autocomplete.d.ts

Lines changed: 54 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,71 @@
1-
import type { AutocompleteOptions, AutocompleteResponse, LookupArray, Orientation, ResolvedOptions, Suggestion } from "./types";
2-
interface Classes {
3-
selected: string;
4-
suggestion: string;
5-
}
1+
import type { AutocompleteOptions, ResolvedOptions } from "./types";
62
export declare class Autocomplete {
73
static defaults: ResolvedOptions;
84
static utils: {
95
escapeRegExChars(value: string): string;
106
createNode(containerClass: string): HTMLDivElement;
117
};
12-
element: HTMLInputElement;
13-
el: JQuery;
14-
suggestions: Suggestion[];
15-
badQueries: string[];
16-
selectedIndex: number;
17-
currentValue: string;
18-
cachedResponse: Record<string, AutocompleteResponse>;
19-
onChangeTimeout: ReturnType<typeof setTimeout> | null;
20-
isLocal: boolean;
21-
suggestionsContainer: HTMLDivElement;
22-
noSuggestionsContainer: HTMLElement;
23-
$container: JQuery;
24-
$noSuggestionsContainer: JQuery;
8+
private element;
9+
private el;
10+
private suggestions;
11+
private badQueries;
12+
private selectedIndex;
13+
private currentValue;
14+
private cachedResponse;
15+
private onChangeTimeout;
16+
private isLocal;
17+
private suggestionsContainer;
18+
private noSuggestionsContainer;
19+
private $container;
20+
private $noSuggestionsContainer;
2521
options: ResolvedOptions;
26-
classes: Classes;
27-
hint: Suggestion | null;
28-
hintValue: string;
29-
selection: Suggestion | null;
30-
disabled?: boolean;
31-
visible?: boolean;
32-
ignoreValueChange?: boolean;
33-
blurTimeoutId?: ReturnType<typeof setTimeout>;
34-
fixPositionCapture?: () => void;
35-
currentRequest: JQuery.jqXHR | null;
22+
private classes;
23+
private hint;
24+
private hintValue;
25+
private selection;
26+
private disabled?;
27+
private visible?;
28+
private ignoreValueChange?;
29+
private blurTimeoutId?;
30+
private fixPositionCapture?;
31+
private currentRequest;
3632
constructor(el: HTMLInputElement, options?: AutocompleteOptions);
37-
initialize(): void;
38-
onFocus(): void;
39-
onBlur(): void;
40-
abortAjax(): void;
33+
private initialize;
34+
private onFocus;
35+
private onBlur;
36+
private abortAjax;
4137
setOptions(suppliedOptions?: AutocompleteOptions): void;
4238
clearCache(): void;
4339
clear(): void;
4440
disable(): void;
4541
enable(): void;
46-
fixPosition(): void;
47-
isCursorAtEnd(): boolean;
48-
onKeyPress(e: JQuery.KeyDownEvent): void;
49-
onKeyUp(e: JQuery.TriggeredEvent): void;
50-
onValueChange(): void;
51-
isExactMatch(query: string): boolean;
52-
getQuery(value: string): string;
53-
getSuggestionsLocal(query: string): AutocompleteResponse;
54-
getSuggestions(q: string): void;
55-
isBadQuery(q: string): boolean;
42+
private fixPosition;
43+
private isCursorAtEnd;
44+
private onKeyPress;
45+
private onKeyUp;
46+
private onValueChange;
47+
private isExactMatch;
48+
private getQuery;
49+
private getSuggestionsLocal;
50+
private getSuggestions;
51+
private isBadQuery;
5652
hide(): void;
57-
groupSuggestionsByCategory(suggestions: Suggestion[], key: string): Suggestion[];
58-
suggest(): void;
59-
noSuggestions(): void;
60-
adjustContainerWidth(): void;
61-
findBestHint(): void;
62-
onHint(suggestion: Suggestion | null): void;
63-
verifySuggestionsFormat(suggestions: LookupArray): Suggestion[];
64-
validateOrientation(orientation: string | undefined, fallback: Orientation): Orientation;
65-
processResponse(result: AutocompleteResponse, originalQuery: string, cacheKey: string): void;
66-
activate(index: number): HTMLElement | null;
67-
selectHint(): void;
53+
private groupSuggestionsByCategory;
54+
private suggest;
55+
private noSuggestions;
56+
private adjustContainerWidth;
57+
private findBestHint;
58+
private onHint;
59+
private verifySuggestionsFormat;
60+
private validateOrientation;
61+
private processResponse;
62+
private activate;
63+
private selectHint;
6864
select(i: number): void;
69-
moveUp(): void;
70-
moveDown(): void;
71-
adjustScroll(index: number): void;
72-
onSelect(index: number): void;
73-
getValue(value: string): string;
65+
private moveUp;
66+
private moveDown;
67+
private adjustScroll;
68+
private onSelect;
69+
private getValue;
7470
dispose(): void;
7571
}
76-
export {};

0 commit comments

Comments
 (0)