A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

Debounce mention lookup + guard registration via hasFilter

+8 -8
+7 -8
src/lib/editor/mention-autocompleter.ts
··· 1 1 import { createElement } from '@wordpress/element'; 2 - import { addFilter } from '@wordpress/hooks'; 2 + import { addFilter, hasFilter } from '@wordpress/hooks'; 3 3 import { lookupActor, type ActorPreview } from '../landing/actor-lookup'; 4 4 5 5 type LookupFn = ( query: string ) => Promise< ActorPreview | null >; ··· 18 18 return { 19 19 name: 'skypress/mention', 20 20 triggerPrefix: '@', 21 + isDebounced: true, 21 22 async options( query: string ): Promise< ActorPreview[] > { 22 23 const trimmed = query.trim(); 23 24 if ( ! trimmed ) { ··· 71 72 }; 72 73 } 73 74 74 - let registered = false; 75 + const MENTION_FILTER_NAMESPACE = 'skypress/mention-autocompleter'; 75 76 76 - /** Add the mention completer to every RichText instance in the editor. */ 77 + /** Add the mention completer to every RichText instance in the editor (idempotent). */ 77 78 export function registerMentionAutocompleter(): void { 78 - if ( registered ) { 79 + if ( hasFilter( 'editor.Autocomplete.completers', MENTION_FILTER_NAMESPACE ) ) { 79 80 return; 80 81 } 81 - registered = true; 82 82 const completer = createMentionCompleter(); 83 83 addFilter( 84 84 'editor.Autocomplete.completers', 85 - 'skypress/mention-autocompleter', 86 - // The local `addFilter` type signs the callback as `( ...args: unknown[] )`, 87 - // so accept `unknown` and narrow to the completers array here. 85 + MENTION_FILTER_NAMESPACE, 86 + // @wordpress/hooks types the callback as (...args) => unknown; cast the first arg. 88 87 ( completers: unknown ) => [ ...( completers as unknown[] ), completer ] 89 88 ); 90 89 }
+1
src/types/wordpress.d.ts
··· 36 36 callback: ( ...args: unknown[] ) => unknown, 37 37 priority?: number 38 38 ): void; 39 + export function hasFilter( hookName: string, namespace?: string ): boolean; 39 40 export function applyFilters( hookName: string, value: unknown, ...args: unknown[] ): unknown; 40 41 }