@seed-ship/mcp-ui-solid 2.1.0 → 2.1.2
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/dist/components/DraggableGridItem.cjs +2 -2
- package/dist/components/DraggableGridItem.cjs.map +1 -1
- package/dist/components/DraggableGridItem.d.ts +1 -1
- package/dist/components/DraggableGridItem.d.ts.map +1 -1
- package/dist/components/DraggableGridItem.js +2 -2
- package/dist/components/DraggableGridItem.js.map +1 -1
- package/dist/components/EditableUIResourceRenderer.cjs +2 -6
- package/dist/components/EditableUIResourceRenderer.cjs.map +1 -1
- package/dist/components/EditableUIResourceRenderer.d.ts.map +1 -1
- package/dist/components/EditableUIResourceRenderer.js +2 -6
- package/dist/components/EditableUIResourceRenderer.js.map +1 -1
- package/dist/components/ResizeHandle.cjs +6 -2
- package/dist/components/ResizeHandle.cjs.map +1 -1
- package/dist/components/ResizeHandle.d.ts +1 -1
- package/dist/components/ResizeHandle.d.ts.map +1 -1
- package/dist/components/ResizeHandle.js +6 -2
- package/dist/components/ResizeHandle.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +1 -1
- package/dist/components/UIResourceRenderer.js +1 -1
- package/dist/hooks/useAutocomplete.cjs +8 -0
- package/dist/hooks/useAutocomplete.cjs.map +1 -1
- package/dist/hooks/useAutocomplete.d.ts.map +1 -1
- package/dist/hooks/useAutocomplete.js +8 -0
- package/dist/hooks/useAutocomplete.js.map +1 -1
- package/dist/node_modules/.pnpm/{@tanstack_solid-virtual@3.13.18_solid-js@1.9.10 → @tanstack_solid-virtual@3.13.18_solid-js@1.9.11}/node_modules/@tanstack/solid-virtual/dist/esm/index.cjs.map +1 -1
- package/dist/node_modules/.pnpm/{@tanstack_solid-virtual@3.13.18_solid-js@1.9.10 → @tanstack_solid-virtual@3.13.18_solid-js@1.9.11}/node_modules/@tanstack/solid-virtual/dist/esm/index.js.map +1 -1
- package/esbuild-why-Full bundle (with deps).html +51 -0
- package/esbuild-why-Hooks only.html +51 -0
- package/esbuild-why-Streaming renderer.html +51 -0
- package/package.json +2 -2
- package/src/components/DraggableGridItem.tsx +3 -3
- package/src/components/EditableUIResourceRenderer.tsx +2 -7
- package/src/components/ResizeHandle.tsx +8 -3
- package/src/hooks/useAutocomplete.ts +16 -0
- package/tsconfig.tsbuildinfo +1 -1
- /package/dist/node_modules/.pnpm/{@tanstack_solid-virtual@3.13.18_solid-js@1.9.10 → @tanstack_solid-virtual@3.13.18_solid-js@1.9.11}/node_modules/@tanstack/solid-virtual/dist/esm/index.cjs +0 -0
- /package/dist/node_modules/.pnpm/{@tanstack_solid-virtual@3.13.18_solid-js@1.9.10 → @tanstack_solid-virtual@3.13.18_solid-js@1.9.11}/node_modules/@tanstack/solid-virtual/dist/esm/index.js +0 -0
|
@@ -40,6 +40,7 @@ function useAutocomplete(options) {
|
|
|
40
40
|
const [error, setError] = solidJs.createSignal(null);
|
|
41
41
|
const [isOpen, setIsOpen] = solidJs.createSignal(false);
|
|
42
42
|
const [resultType, setResultType] = solidJs.createSignal(null);
|
|
43
|
+
let currentRequestId = 0;
|
|
43
44
|
const config = solidJs.createMemo(() => ({
|
|
44
45
|
minChars: minCharsOption ?? (fieldConfig == null ? void 0 : fieldConfig.minChars) ?? (autocompleteCtx == null ? void 0 : autocompleteCtx.config.minChars) ?? 1,
|
|
45
46
|
debounceMs: debounceOption ?? (fieldConfig == null ? void 0 : fieldConfig.debounceMs) ?? (autocompleteCtx == null ? void 0 : autocompleteCtx.config.debounceMs) ?? 150
|
|
@@ -66,6 +67,7 @@ function useAutocomplete(options) {
|
|
|
66
67
|
});
|
|
67
68
|
return;
|
|
68
69
|
}
|
|
70
|
+
const requestId = ++currentRequestId;
|
|
69
71
|
setIsLoading(true);
|
|
70
72
|
setError(null);
|
|
71
73
|
try {
|
|
@@ -76,6 +78,9 @@ function useAutocomplete(options) {
|
|
|
76
78
|
targetPluginId,
|
|
77
79
|
contextData
|
|
78
80
|
);
|
|
81
|
+
if (requestId !== currentRequestId) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
79
84
|
solidJs.batch(() => {
|
|
80
85
|
var _a;
|
|
81
86
|
setResultType(result.type);
|
|
@@ -92,6 +97,9 @@ function useAutocomplete(options) {
|
|
|
92
97
|
setIsLoading(false);
|
|
93
98
|
});
|
|
94
99
|
} catch (e) {
|
|
100
|
+
if (requestId !== currentRequestId) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
95
103
|
solidJs.batch(() => {
|
|
96
104
|
setError(e instanceof Error ? e.message : "Unknown error");
|
|
97
105
|
setIsLoading(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutocomplete.cjs","sources":["../../src/hooks/useAutocomplete.ts"],"sourcesContent":["/**\n * useAutocomplete Hook\n * Provides autocomplete functionality for form fields\n *\n * Sprint Autocomplete Feature\n */\n\nimport {\n createSignal,\n createEffect,\n on,\n Accessor,\n onCleanup,\n batch,\n createMemo\n} from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { useAutocompleteContextSafe } from '../context/AutocompleteContext'\nimport type {\n AutocompleteOption,\n AutocompleteContext,\n FieldAutocompleteConfig\n} from '../types'\n\n/**\n * Options for the useAutocomplete hook\n */\nexport interface UseAutocompleteOptions {\n /**\n * Current input value accessor\n */\n inputValue: Accessor<string>\n\n /**\n * Plugin ID to use (overrides default)\n */\n pluginId?: string\n\n /**\n * Field configuration\n */\n fieldConfig?: FieldAutocompleteConfig\n\n /**\n * Context data for suggestions\n */\n context?: Accessor<AutocompleteContext>\n\n /**\n * Whether autocomplete is enabled\n */\n enabled?: boolean\n\n /**\n * Callback when input value should change (for accepting suggestions)\n */\n onInputChange?: (value: string) => void\n\n /**\n * Minimum characters before triggering\n */\n minChars?: number\n\n /**\n * Debounce delay in ms\n */\n debounceMs?: number\n}\n\n/**\n * Return type for the useAutocomplete hook\n */\nexport interface UseAutocompleteReturn {\n /**\n * Current completion text (for ghost text, LLM mode)\n */\n completion: Accessor<string | null>\n\n /**\n * Ghost text to show (remaining text after input)\n */\n ghostText: Accessor<string>\n\n /**\n * Accept the current completion\n */\n acceptCompletion: () => void\n\n /**\n * Current options (for dropdown, data mode)\n */\n options: Accessor<AutocompleteOption[]>\n\n /**\n * Currently selected option index\n */\n selectedIndex: Accessor<number>\n\n /**\n * Select an option by index\n */\n selectOption: (option: AutocompleteOption) => void\n\n /**\n * Navigate to next option\n */\n nextOption: () => void\n\n /**\n * Navigate to previous option\n */\n prevOption: () => void\n\n /**\n * Select current highlighted option\n */\n selectCurrentOption: () => void\n\n /**\n * Whether suggestions are loading\n */\n isLoading: Accessor<boolean>\n\n /**\n * Error message if any\n */\n error: Accessor<string | null>\n\n /**\n * Dismiss suggestions\n */\n dismiss: () => void\n\n /**\n * Whether suggestions are visible\n */\n isOpen: Accessor<boolean>\n\n /**\n * Result type ('completion' or 'options')\n */\n resultType: Accessor<'completion' | 'options' | null>\n\n /**\n * Open/show suggestions\n */\n open: () => void\n\n /**\n * Handle keyboard events\n */\n handleKeyDown: (e: KeyboardEvent) => boolean\n}\n\n/**\n * Debounce helper\n */\nfunction debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): { call: (...args: Parameters<T>) => void; cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n return {\n call: (...args: Parameters<T>) => {\n if (timeoutId) clearTimeout(timeoutId)\n timeoutId = setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, delay)\n },\n cancel: () => {\n if (timeoutId) {\n clearTimeout(timeoutId)\n timeoutId = null\n }\n }\n }\n}\n\n/**\n * Hook for autocomplete functionality\n */\nexport function useAutocomplete(options: UseAutocompleteOptions): UseAutocompleteReturn {\n const {\n inputValue,\n pluginId,\n fieldConfig,\n context,\n enabled = true,\n onInputChange,\n minChars: minCharsOption,\n debounceMs: debounceOption\n } = options\n\n // Get context (may be undefined if no provider)\n const autocompleteCtx = useAutocompleteContextSafe()\n\n // State\n const [completion, setCompletion] = createSignal<string | null>(null)\n const [options_, setOptions] = createSignal<AutocompleteOption[]>([])\n const [selectedIndex, setSelectedIndex] = createSignal(-1)\n const [isLoading, setIsLoading] = createSignal(false)\n const [error, setError] = createSignal<string | null>(null)\n const [isOpen, setIsOpen] = createSignal(false)\n const [resultType, setResultType] = createSignal<'completion' | 'options' | null>(null)\n\n // Config with defaults from context/options\n const config = createMemo(() => ({\n minChars: minCharsOption ?? fieldConfig?.minChars ?? autocompleteCtx?.config.minChars ?? 1,\n debounceMs: debounceOption ?? fieldConfig?.debounceMs ?? autocompleteCtx?.config.debounceMs ?? 150\n }))\n\n // Ghost text (portion after current input)\n const ghostText = createMemo(() => {\n const comp = completion()\n const input = inputValue()\n\n if (!comp || !input) return ''\n\n // If completion starts with input, show the remaining part\n if (comp.toLowerCase().startsWith(input.toLowerCase())) {\n return comp.slice(input.length)\n }\n\n return ''\n })\n\n // Fetch suggestions\n const fetchSuggestions = async (input: string) => {\n if (!autocompleteCtx) {\n return\n }\n\n if (input.length < config().minChars) {\n batch(() => {\n setCompletion(null)\n setOptions([])\n setIsOpen(false)\n setResultType(null)\n })\n return\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const targetPluginId = pluginId ?? fieldConfig?.plugin\n const contextData = context?.()\n\n const result = await autocompleteCtx.getSuggestions(\n input,\n targetPluginId,\n contextData\n )\n\n batch(() => {\n setResultType(result.type)\n\n if (result.type === 'completion') {\n setCompletion(result.completion || null)\n setOptions([])\n setIsOpen(!!result.completion)\n } else {\n setCompletion(null)\n setOptions(result.options || [])\n setSelectedIndex(-1)\n setIsOpen((result.options?.length || 0) > 0)\n }\n\n setIsLoading(false)\n })\n } catch (e) {\n batch(() => {\n setError(e instanceof Error ? e.message : 'Unknown error')\n setIsLoading(false)\n setIsOpen(false)\n })\n }\n }\n\n // Debounced fetch\n const debouncedFetch = debounce(fetchSuggestions, config().debounceMs)\n\n // Watch input value changes\n createEffect(\n on(inputValue, (value) => {\n if (!enabled || !autocompleteCtx || isServer) {\n return\n }\n\n debouncedFetch.call(value)\n })\n )\n\n // Cleanup\n onCleanup(() => {\n debouncedFetch.cancel()\n })\n\n /**\n * Accept the current completion\n */\n const acceptCompletion = () => {\n const comp = completion()\n if (comp && onInputChange) {\n onInputChange(comp)\n batch(() => {\n setCompletion(null)\n setIsOpen(false)\n })\n }\n }\n\n /**\n * Select an option\n */\n const selectOption = (option: AutocompleteOption) => {\n if (onInputChange) {\n onInputChange(option.value)\n }\n batch(() => {\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n })\n }\n\n /**\n * Navigate to next option\n */\n const nextOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev + 1\n return next >= opts.length ? 0 : next\n })\n }\n\n /**\n * Navigate to previous option\n */\n const prevOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev - 1\n return next < 0 ? opts.length - 1 : next\n })\n }\n\n /**\n * Select current highlighted option\n */\n const selectCurrentOption = () => {\n const idx = selectedIndex()\n const opts = options_()\n if (idx >= 0 && idx < opts.length) {\n selectOption(opts[idx])\n }\n }\n\n /**\n * Dismiss suggestions\n */\n const dismiss = () => {\n debouncedFetch.cancel()\n batch(() => {\n setCompletion(null)\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n setError(null)\n })\n }\n\n /**\n * Open suggestions\n */\n const open = () => {\n const input = inputValue()\n if (input.length >= config().minChars) {\n fetchSuggestions(input)\n }\n }\n\n /**\n * Handle keyboard events\n * Returns true if the event was handled\n */\n const handleKeyDown = (e: KeyboardEvent): boolean => {\n if (!isOpen()) return false\n\n const type = resultType()\n\n // Tab to accept completion\n if (e.key === 'Tab' && type === 'completion' && ghostText()) {\n e.preventDefault()\n acceptCompletion()\n return true\n }\n\n // Arrow keys for dropdown navigation\n if (type === 'options') {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n nextOption()\n return true\n\n case 'ArrowUp':\n e.preventDefault()\n prevOption()\n return true\n\n case 'Enter':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n\n case 'Tab':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n }\n }\n\n // Escape to dismiss\n if (e.key === 'Escape') {\n e.preventDefault()\n dismiss()\n return true\n }\n\n return false\n }\n\n return {\n completion,\n ghostText,\n acceptCompletion,\n options: options_,\n selectedIndex,\n selectOption,\n nextOption,\n prevOption,\n selectCurrentOption,\n isLoading,\n error,\n dismiss,\n isOpen,\n resultType,\n open,\n handleKeyDown\n }\n}\n"],"names":["useAutocompleteContextSafe","createSignal","createMemo","batch","createEffect","on","isServer","onCleanup"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAutocomplete.cjs","sources":["../../src/hooks/useAutocomplete.ts"],"sourcesContent":["/**\n * useAutocomplete Hook\n * Provides autocomplete functionality for form fields\n *\n * Sprint Autocomplete Feature\n */\n\nimport {\n createSignal,\n createEffect,\n on,\n Accessor,\n onCleanup,\n batch,\n createMemo\n} from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { useAutocompleteContextSafe } from '../context/AutocompleteContext'\nimport type {\n AutocompleteOption,\n AutocompleteContext,\n FieldAutocompleteConfig\n} from '../types'\n\n/**\n * Options for the useAutocomplete hook\n */\nexport interface UseAutocompleteOptions {\n /**\n * Current input value accessor\n */\n inputValue: Accessor<string>\n\n /**\n * Plugin ID to use (overrides default)\n */\n pluginId?: string\n\n /**\n * Field configuration\n */\n fieldConfig?: FieldAutocompleteConfig\n\n /**\n * Context data for suggestions\n */\n context?: Accessor<AutocompleteContext>\n\n /**\n * Whether autocomplete is enabled\n */\n enabled?: boolean\n\n /**\n * Callback when input value should change (for accepting suggestions)\n */\n onInputChange?: (value: string) => void\n\n /**\n * Minimum characters before triggering\n */\n minChars?: number\n\n /**\n * Debounce delay in ms\n */\n debounceMs?: number\n}\n\n/**\n * Return type for the useAutocomplete hook\n */\nexport interface UseAutocompleteReturn {\n /**\n * Current completion text (for ghost text, LLM mode)\n */\n completion: Accessor<string | null>\n\n /**\n * Ghost text to show (remaining text after input)\n */\n ghostText: Accessor<string>\n\n /**\n * Accept the current completion\n */\n acceptCompletion: () => void\n\n /**\n * Current options (for dropdown, data mode)\n */\n options: Accessor<AutocompleteOption[]>\n\n /**\n * Currently selected option index\n */\n selectedIndex: Accessor<number>\n\n /**\n * Select an option by index\n */\n selectOption: (option: AutocompleteOption) => void\n\n /**\n * Navigate to next option\n */\n nextOption: () => void\n\n /**\n * Navigate to previous option\n */\n prevOption: () => void\n\n /**\n * Select current highlighted option\n */\n selectCurrentOption: () => void\n\n /**\n * Whether suggestions are loading\n */\n isLoading: Accessor<boolean>\n\n /**\n * Error message if any\n */\n error: Accessor<string | null>\n\n /**\n * Dismiss suggestions\n */\n dismiss: () => void\n\n /**\n * Whether suggestions are visible\n */\n isOpen: Accessor<boolean>\n\n /**\n * Result type ('completion' or 'options')\n */\n resultType: Accessor<'completion' | 'options' | null>\n\n /**\n * Open/show suggestions\n */\n open: () => void\n\n /**\n * Handle keyboard events\n */\n handleKeyDown: (e: KeyboardEvent) => boolean\n}\n\n/**\n * Debounce helper\n */\nfunction debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): { call: (...args: Parameters<T>) => void; cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n return {\n call: (...args: Parameters<T>) => {\n if (timeoutId) clearTimeout(timeoutId)\n timeoutId = setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, delay)\n },\n cancel: () => {\n if (timeoutId) {\n clearTimeout(timeoutId)\n timeoutId = null\n }\n }\n }\n}\n\n/**\n * Hook for autocomplete functionality\n */\nexport function useAutocomplete(options: UseAutocompleteOptions): UseAutocompleteReturn {\n const {\n inputValue,\n pluginId,\n fieldConfig,\n context,\n enabled = true,\n onInputChange,\n minChars: minCharsOption,\n debounceMs: debounceOption\n } = options\n\n // Get context (may be undefined if no provider)\n const autocompleteCtx = useAutocompleteContextSafe()\n\n // State\n const [completion, setCompletion] = createSignal<string | null>(null)\n const [options_, setOptions] = createSignal<AutocompleteOption[]>([])\n const [selectedIndex, setSelectedIndex] = createSignal(-1)\n const [isLoading, setIsLoading] = createSignal(false)\n const [error, setError] = createSignal<string | null>(null)\n const [isOpen, setIsOpen] = createSignal(false)\n const [resultType, setResultType] = createSignal<'completion' | 'options' | null>(null)\n\n // Request ID to track stale responses\n let currentRequestId = 0\n\n // Config with defaults from context/options\n const config = createMemo(() => ({\n minChars: minCharsOption ?? fieldConfig?.minChars ?? autocompleteCtx?.config.minChars ?? 1,\n debounceMs: debounceOption ?? fieldConfig?.debounceMs ?? autocompleteCtx?.config.debounceMs ?? 150\n }))\n\n // Ghost text (portion after current input)\n const ghostText = createMemo(() => {\n const comp = completion()\n const input = inputValue()\n\n if (!comp || !input) return ''\n\n // If completion starts with input, show the remaining part\n if (comp.toLowerCase().startsWith(input.toLowerCase())) {\n return comp.slice(input.length)\n }\n\n return ''\n })\n\n // Fetch suggestions\n const fetchSuggestions = async (input: string) => {\n if (!autocompleteCtx) {\n return\n }\n\n if (input.length < config().minChars) {\n batch(() => {\n setCompletion(null)\n setOptions([])\n setIsOpen(false)\n setResultType(null)\n })\n return\n }\n\n // Increment request ID to track this specific request\n const requestId = ++currentRequestId\n\n setIsLoading(true)\n setError(null)\n\n try {\n const targetPluginId = pluginId ?? fieldConfig?.plugin\n const contextData = context?.()\n\n const result = await autocompleteCtx.getSuggestions(\n input,\n targetPluginId,\n contextData\n )\n\n // Ignore stale responses - if a newer request was made, discard this result\n if (requestId !== currentRequestId) {\n return\n }\n\n batch(() => {\n setResultType(result.type)\n\n if (result.type === 'completion') {\n setCompletion(result.completion || null)\n setOptions([])\n setIsOpen(!!result.completion)\n } else {\n setCompletion(null)\n setOptions(result.options || [])\n setSelectedIndex(-1)\n setIsOpen((result.options?.length || 0) > 0)\n }\n\n setIsLoading(false)\n })\n } catch (e) {\n // Ignore errors from stale requests\n if (requestId !== currentRequestId) {\n return\n }\n\n batch(() => {\n setError(e instanceof Error ? e.message : 'Unknown error')\n setIsLoading(false)\n setIsOpen(false)\n })\n }\n }\n\n // Debounced fetch\n const debouncedFetch = debounce(fetchSuggestions, config().debounceMs)\n\n // Watch input value changes\n createEffect(\n on(inputValue, (value) => {\n if (!enabled || !autocompleteCtx || isServer) {\n return\n }\n\n debouncedFetch.call(value)\n })\n )\n\n // Cleanup\n onCleanup(() => {\n debouncedFetch.cancel()\n })\n\n /**\n * Accept the current completion\n */\n const acceptCompletion = () => {\n const comp = completion()\n if (comp && onInputChange) {\n onInputChange(comp)\n batch(() => {\n setCompletion(null)\n setIsOpen(false)\n })\n }\n }\n\n /**\n * Select an option\n */\n const selectOption = (option: AutocompleteOption) => {\n if (onInputChange) {\n onInputChange(option.value)\n }\n batch(() => {\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n })\n }\n\n /**\n * Navigate to next option\n */\n const nextOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev + 1\n return next >= opts.length ? 0 : next\n })\n }\n\n /**\n * Navigate to previous option\n */\n const prevOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev - 1\n return next < 0 ? opts.length - 1 : next\n })\n }\n\n /**\n * Select current highlighted option\n */\n const selectCurrentOption = () => {\n const idx = selectedIndex()\n const opts = options_()\n if (idx >= 0 && idx < opts.length) {\n selectOption(opts[idx])\n }\n }\n\n /**\n * Dismiss suggestions\n */\n const dismiss = () => {\n debouncedFetch.cancel()\n batch(() => {\n setCompletion(null)\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n setError(null)\n })\n }\n\n /**\n * Open suggestions\n */\n const open = () => {\n const input = inputValue()\n if (input.length >= config().minChars) {\n fetchSuggestions(input)\n }\n }\n\n /**\n * Handle keyboard events\n * Returns true if the event was handled\n */\n const handleKeyDown = (e: KeyboardEvent): boolean => {\n if (!isOpen()) return false\n\n const type = resultType()\n\n // Tab to accept completion\n if (e.key === 'Tab' && type === 'completion' && ghostText()) {\n e.preventDefault()\n acceptCompletion()\n return true\n }\n\n // Arrow keys for dropdown navigation\n if (type === 'options') {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n nextOption()\n return true\n\n case 'ArrowUp':\n e.preventDefault()\n prevOption()\n return true\n\n case 'Enter':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n\n case 'Tab':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n }\n }\n\n // Escape to dismiss\n if (e.key === 'Escape') {\n e.preventDefault()\n dismiss()\n return true\n }\n\n return false\n }\n\n return {\n completion,\n ghostText,\n acceptCompletion,\n options: options_,\n selectedIndex,\n selectOption,\n nextOption,\n prevOption,\n selectCurrentOption,\n isLoading,\n error,\n dismiss,\n isOpen,\n resultType,\n open,\n handleKeyDown\n }\n}\n"],"names":["useAutocompleteContextSafe","createSignal","createMemo","batch","createEffect","on","isServer","onCleanup"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutocomplete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIL,QAAQ,EAIT,MAAM,UAAU,CAAA;AAGjB,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,UAAU,CAAA;AAEjB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE5B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAA;IAErC;;OAEG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA;IAEvC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEvC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAEnC;;OAEG;IACH,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE3B;;OAEG;IACH,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAE5B;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAA;IAEvC;;OAEG;IACH,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE/B;;OAEG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAElD;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAA;IAEtB;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAA;IAEtB;;OAEG;IACH,mBAAmB,EAAE,MAAM,IAAI,CAAA;IAE/B;;OAEG;IACH,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAE5B;;OAEG;IACH,KAAK,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAE9B;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IAEnB;;OAEG;IACH,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEzB;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,YAAY,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IAErD;;OAEG;IACH,IAAI,EAAE,MAAM,IAAI,CAAA;IAEhB;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,OAAO,CAAA;CAC7C;AA4BD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,
|
|
1
|
+
{"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutocomplete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIL,QAAQ,EAIT,MAAM,UAAU,CAAA;AAGjB,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,UAAU,CAAA;AAEjB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE5B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAA;IAErC;;OAEG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA;IAEvC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAEvC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAEnC;;OAEG;IACH,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE3B;;OAEG;IACH,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAE5B;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAA;IAEvC;;OAEG;IACH,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAE/B;;OAEG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAElD;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAA;IAEtB;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAA;IAEtB;;OAEG;IACH,mBAAmB,EAAE,MAAM,IAAI,CAAA;IAE/B;;OAEG;IACH,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAE5B;;OAEG;IACH,KAAK,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAE9B;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IAEnB;;OAEG;IACH,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEzB;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,YAAY,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IAErD;;OAEG;IACH,IAAI,EAAE,MAAM,IAAI,CAAA;IAEhB;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,OAAO,CAAA;CAC7C;AA4BD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA0StF"}
|
|
@@ -38,6 +38,7 @@ function useAutocomplete(options) {
|
|
|
38
38
|
const [error, setError] = createSignal(null);
|
|
39
39
|
const [isOpen, setIsOpen] = createSignal(false);
|
|
40
40
|
const [resultType, setResultType] = createSignal(null);
|
|
41
|
+
let currentRequestId = 0;
|
|
41
42
|
const config = createMemo(() => ({
|
|
42
43
|
minChars: minCharsOption ?? (fieldConfig == null ? void 0 : fieldConfig.minChars) ?? (autocompleteCtx == null ? void 0 : autocompleteCtx.config.minChars) ?? 1,
|
|
43
44
|
debounceMs: debounceOption ?? (fieldConfig == null ? void 0 : fieldConfig.debounceMs) ?? (autocompleteCtx == null ? void 0 : autocompleteCtx.config.debounceMs) ?? 150
|
|
@@ -64,6 +65,7 @@ function useAutocomplete(options) {
|
|
|
64
65
|
});
|
|
65
66
|
return;
|
|
66
67
|
}
|
|
68
|
+
const requestId = ++currentRequestId;
|
|
67
69
|
setIsLoading(true);
|
|
68
70
|
setError(null);
|
|
69
71
|
try {
|
|
@@ -74,6 +76,9 @@ function useAutocomplete(options) {
|
|
|
74
76
|
targetPluginId,
|
|
75
77
|
contextData
|
|
76
78
|
);
|
|
79
|
+
if (requestId !== currentRequestId) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
77
82
|
batch(() => {
|
|
78
83
|
var _a;
|
|
79
84
|
setResultType(result.type);
|
|
@@ -90,6 +95,9 @@ function useAutocomplete(options) {
|
|
|
90
95
|
setIsLoading(false);
|
|
91
96
|
});
|
|
92
97
|
} catch (e) {
|
|
98
|
+
if (requestId !== currentRequestId) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
93
101
|
batch(() => {
|
|
94
102
|
setError(e instanceof Error ? e.message : "Unknown error");
|
|
95
103
|
setIsLoading(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutocomplete.js","sources":["../../src/hooks/useAutocomplete.ts"],"sourcesContent":["/**\n * useAutocomplete Hook\n * Provides autocomplete functionality for form fields\n *\n * Sprint Autocomplete Feature\n */\n\nimport {\n createSignal,\n createEffect,\n on,\n Accessor,\n onCleanup,\n batch,\n createMemo\n} from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { useAutocompleteContextSafe } from '../context/AutocompleteContext'\nimport type {\n AutocompleteOption,\n AutocompleteContext,\n FieldAutocompleteConfig\n} from '../types'\n\n/**\n * Options for the useAutocomplete hook\n */\nexport interface UseAutocompleteOptions {\n /**\n * Current input value accessor\n */\n inputValue: Accessor<string>\n\n /**\n * Plugin ID to use (overrides default)\n */\n pluginId?: string\n\n /**\n * Field configuration\n */\n fieldConfig?: FieldAutocompleteConfig\n\n /**\n * Context data for suggestions\n */\n context?: Accessor<AutocompleteContext>\n\n /**\n * Whether autocomplete is enabled\n */\n enabled?: boolean\n\n /**\n * Callback when input value should change (for accepting suggestions)\n */\n onInputChange?: (value: string) => void\n\n /**\n * Minimum characters before triggering\n */\n minChars?: number\n\n /**\n * Debounce delay in ms\n */\n debounceMs?: number\n}\n\n/**\n * Return type for the useAutocomplete hook\n */\nexport interface UseAutocompleteReturn {\n /**\n * Current completion text (for ghost text, LLM mode)\n */\n completion: Accessor<string | null>\n\n /**\n * Ghost text to show (remaining text after input)\n */\n ghostText: Accessor<string>\n\n /**\n * Accept the current completion\n */\n acceptCompletion: () => void\n\n /**\n * Current options (for dropdown, data mode)\n */\n options: Accessor<AutocompleteOption[]>\n\n /**\n * Currently selected option index\n */\n selectedIndex: Accessor<number>\n\n /**\n * Select an option by index\n */\n selectOption: (option: AutocompleteOption) => void\n\n /**\n * Navigate to next option\n */\n nextOption: () => void\n\n /**\n * Navigate to previous option\n */\n prevOption: () => void\n\n /**\n * Select current highlighted option\n */\n selectCurrentOption: () => void\n\n /**\n * Whether suggestions are loading\n */\n isLoading: Accessor<boolean>\n\n /**\n * Error message if any\n */\n error: Accessor<string | null>\n\n /**\n * Dismiss suggestions\n */\n dismiss: () => void\n\n /**\n * Whether suggestions are visible\n */\n isOpen: Accessor<boolean>\n\n /**\n * Result type ('completion' or 'options')\n */\n resultType: Accessor<'completion' | 'options' | null>\n\n /**\n * Open/show suggestions\n */\n open: () => void\n\n /**\n * Handle keyboard events\n */\n handleKeyDown: (e: KeyboardEvent) => boolean\n}\n\n/**\n * Debounce helper\n */\nfunction debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): { call: (...args: Parameters<T>) => void; cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n return {\n call: (...args: Parameters<T>) => {\n if (timeoutId) clearTimeout(timeoutId)\n timeoutId = setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, delay)\n },\n cancel: () => {\n if (timeoutId) {\n clearTimeout(timeoutId)\n timeoutId = null\n }\n }\n }\n}\n\n/**\n * Hook for autocomplete functionality\n */\nexport function useAutocomplete(options: UseAutocompleteOptions): UseAutocompleteReturn {\n const {\n inputValue,\n pluginId,\n fieldConfig,\n context,\n enabled = true,\n onInputChange,\n minChars: minCharsOption,\n debounceMs: debounceOption\n } = options\n\n // Get context (may be undefined if no provider)\n const autocompleteCtx = useAutocompleteContextSafe()\n\n // State\n const [completion, setCompletion] = createSignal<string | null>(null)\n const [options_, setOptions] = createSignal<AutocompleteOption[]>([])\n const [selectedIndex, setSelectedIndex] = createSignal(-1)\n const [isLoading, setIsLoading] = createSignal(false)\n const [error, setError] = createSignal<string | null>(null)\n const [isOpen, setIsOpen] = createSignal(false)\n const [resultType, setResultType] = createSignal<'completion' | 'options' | null>(null)\n\n // Config with defaults from context/options\n const config = createMemo(() => ({\n minChars: minCharsOption ?? fieldConfig?.minChars ?? autocompleteCtx?.config.minChars ?? 1,\n debounceMs: debounceOption ?? fieldConfig?.debounceMs ?? autocompleteCtx?.config.debounceMs ?? 150\n }))\n\n // Ghost text (portion after current input)\n const ghostText = createMemo(() => {\n const comp = completion()\n const input = inputValue()\n\n if (!comp || !input) return ''\n\n // If completion starts with input, show the remaining part\n if (comp.toLowerCase().startsWith(input.toLowerCase())) {\n return comp.slice(input.length)\n }\n\n return ''\n })\n\n // Fetch suggestions\n const fetchSuggestions = async (input: string) => {\n if (!autocompleteCtx) {\n return\n }\n\n if (input.length < config().minChars) {\n batch(() => {\n setCompletion(null)\n setOptions([])\n setIsOpen(false)\n setResultType(null)\n })\n return\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const targetPluginId = pluginId ?? fieldConfig?.plugin\n const contextData = context?.()\n\n const result = await autocompleteCtx.getSuggestions(\n input,\n targetPluginId,\n contextData\n )\n\n batch(() => {\n setResultType(result.type)\n\n if (result.type === 'completion') {\n setCompletion(result.completion || null)\n setOptions([])\n setIsOpen(!!result.completion)\n } else {\n setCompletion(null)\n setOptions(result.options || [])\n setSelectedIndex(-1)\n setIsOpen((result.options?.length || 0) > 0)\n }\n\n setIsLoading(false)\n })\n } catch (e) {\n batch(() => {\n setError(e instanceof Error ? e.message : 'Unknown error')\n setIsLoading(false)\n setIsOpen(false)\n })\n }\n }\n\n // Debounced fetch\n const debouncedFetch = debounce(fetchSuggestions, config().debounceMs)\n\n // Watch input value changes\n createEffect(\n on(inputValue, (value) => {\n if (!enabled || !autocompleteCtx || isServer) {\n return\n }\n\n debouncedFetch.call(value)\n })\n )\n\n // Cleanup\n onCleanup(() => {\n debouncedFetch.cancel()\n })\n\n /**\n * Accept the current completion\n */\n const acceptCompletion = () => {\n const comp = completion()\n if (comp && onInputChange) {\n onInputChange(comp)\n batch(() => {\n setCompletion(null)\n setIsOpen(false)\n })\n }\n }\n\n /**\n * Select an option\n */\n const selectOption = (option: AutocompleteOption) => {\n if (onInputChange) {\n onInputChange(option.value)\n }\n batch(() => {\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n })\n }\n\n /**\n * Navigate to next option\n */\n const nextOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev + 1\n return next >= opts.length ? 0 : next\n })\n }\n\n /**\n * Navigate to previous option\n */\n const prevOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev - 1\n return next < 0 ? opts.length - 1 : next\n })\n }\n\n /**\n * Select current highlighted option\n */\n const selectCurrentOption = () => {\n const idx = selectedIndex()\n const opts = options_()\n if (idx >= 0 && idx < opts.length) {\n selectOption(opts[idx])\n }\n }\n\n /**\n * Dismiss suggestions\n */\n const dismiss = () => {\n debouncedFetch.cancel()\n batch(() => {\n setCompletion(null)\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n setError(null)\n })\n }\n\n /**\n * Open suggestions\n */\n const open = () => {\n const input = inputValue()\n if (input.length >= config().minChars) {\n fetchSuggestions(input)\n }\n }\n\n /**\n * Handle keyboard events\n * Returns true if the event was handled\n */\n const handleKeyDown = (e: KeyboardEvent): boolean => {\n if (!isOpen()) return false\n\n const type = resultType()\n\n // Tab to accept completion\n if (e.key === 'Tab' && type === 'completion' && ghostText()) {\n e.preventDefault()\n acceptCompletion()\n return true\n }\n\n // Arrow keys for dropdown navigation\n if (type === 'options') {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n nextOption()\n return true\n\n case 'ArrowUp':\n e.preventDefault()\n prevOption()\n return true\n\n case 'Enter':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n\n case 'Tab':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n }\n }\n\n // Escape to dismiss\n if (e.key === 'Escape') {\n e.preventDefault()\n dismiss()\n return true\n }\n\n return false\n }\n\n return {\n completion,\n ghostText,\n acceptCompletion,\n options: options_,\n selectedIndex,\n selectOption,\n nextOption,\n prevOption,\n selectCurrentOption,\n isLoading,\n error,\n dismiss,\n isOpen,\n resultType,\n open,\n handleKeyDown\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAutocomplete.js","sources":["../../src/hooks/useAutocomplete.ts"],"sourcesContent":["/**\n * useAutocomplete Hook\n * Provides autocomplete functionality for form fields\n *\n * Sprint Autocomplete Feature\n */\n\nimport {\n createSignal,\n createEffect,\n on,\n Accessor,\n onCleanup,\n batch,\n createMemo\n} from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport { useAutocompleteContextSafe } from '../context/AutocompleteContext'\nimport type {\n AutocompleteOption,\n AutocompleteContext,\n FieldAutocompleteConfig\n} from '../types'\n\n/**\n * Options for the useAutocomplete hook\n */\nexport interface UseAutocompleteOptions {\n /**\n * Current input value accessor\n */\n inputValue: Accessor<string>\n\n /**\n * Plugin ID to use (overrides default)\n */\n pluginId?: string\n\n /**\n * Field configuration\n */\n fieldConfig?: FieldAutocompleteConfig\n\n /**\n * Context data for suggestions\n */\n context?: Accessor<AutocompleteContext>\n\n /**\n * Whether autocomplete is enabled\n */\n enabled?: boolean\n\n /**\n * Callback when input value should change (for accepting suggestions)\n */\n onInputChange?: (value: string) => void\n\n /**\n * Minimum characters before triggering\n */\n minChars?: number\n\n /**\n * Debounce delay in ms\n */\n debounceMs?: number\n}\n\n/**\n * Return type for the useAutocomplete hook\n */\nexport interface UseAutocompleteReturn {\n /**\n * Current completion text (for ghost text, LLM mode)\n */\n completion: Accessor<string | null>\n\n /**\n * Ghost text to show (remaining text after input)\n */\n ghostText: Accessor<string>\n\n /**\n * Accept the current completion\n */\n acceptCompletion: () => void\n\n /**\n * Current options (for dropdown, data mode)\n */\n options: Accessor<AutocompleteOption[]>\n\n /**\n * Currently selected option index\n */\n selectedIndex: Accessor<number>\n\n /**\n * Select an option by index\n */\n selectOption: (option: AutocompleteOption) => void\n\n /**\n * Navigate to next option\n */\n nextOption: () => void\n\n /**\n * Navigate to previous option\n */\n prevOption: () => void\n\n /**\n * Select current highlighted option\n */\n selectCurrentOption: () => void\n\n /**\n * Whether suggestions are loading\n */\n isLoading: Accessor<boolean>\n\n /**\n * Error message if any\n */\n error: Accessor<string | null>\n\n /**\n * Dismiss suggestions\n */\n dismiss: () => void\n\n /**\n * Whether suggestions are visible\n */\n isOpen: Accessor<boolean>\n\n /**\n * Result type ('completion' or 'options')\n */\n resultType: Accessor<'completion' | 'options' | null>\n\n /**\n * Open/show suggestions\n */\n open: () => void\n\n /**\n * Handle keyboard events\n */\n handleKeyDown: (e: KeyboardEvent) => boolean\n}\n\n/**\n * Debounce helper\n */\nfunction debounce<T extends (...args: any[]) => any>(\n fn: T,\n delay: number\n): { call: (...args: Parameters<T>) => void; cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n return {\n call: (...args: Parameters<T>) => {\n if (timeoutId) clearTimeout(timeoutId)\n timeoutId = setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, delay)\n },\n cancel: () => {\n if (timeoutId) {\n clearTimeout(timeoutId)\n timeoutId = null\n }\n }\n }\n}\n\n/**\n * Hook for autocomplete functionality\n */\nexport function useAutocomplete(options: UseAutocompleteOptions): UseAutocompleteReturn {\n const {\n inputValue,\n pluginId,\n fieldConfig,\n context,\n enabled = true,\n onInputChange,\n minChars: minCharsOption,\n debounceMs: debounceOption\n } = options\n\n // Get context (may be undefined if no provider)\n const autocompleteCtx = useAutocompleteContextSafe()\n\n // State\n const [completion, setCompletion] = createSignal<string | null>(null)\n const [options_, setOptions] = createSignal<AutocompleteOption[]>([])\n const [selectedIndex, setSelectedIndex] = createSignal(-1)\n const [isLoading, setIsLoading] = createSignal(false)\n const [error, setError] = createSignal<string | null>(null)\n const [isOpen, setIsOpen] = createSignal(false)\n const [resultType, setResultType] = createSignal<'completion' | 'options' | null>(null)\n\n // Request ID to track stale responses\n let currentRequestId = 0\n\n // Config with defaults from context/options\n const config = createMemo(() => ({\n minChars: minCharsOption ?? fieldConfig?.minChars ?? autocompleteCtx?.config.minChars ?? 1,\n debounceMs: debounceOption ?? fieldConfig?.debounceMs ?? autocompleteCtx?.config.debounceMs ?? 150\n }))\n\n // Ghost text (portion after current input)\n const ghostText = createMemo(() => {\n const comp = completion()\n const input = inputValue()\n\n if (!comp || !input) return ''\n\n // If completion starts with input, show the remaining part\n if (comp.toLowerCase().startsWith(input.toLowerCase())) {\n return comp.slice(input.length)\n }\n\n return ''\n })\n\n // Fetch suggestions\n const fetchSuggestions = async (input: string) => {\n if (!autocompleteCtx) {\n return\n }\n\n if (input.length < config().minChars) {\n batch(() => {\n setCompletion(null)\n setOptions([])\n setIsOpen(false)\n setResultType(null)\n })\n return\n }\n\n // Increment request ID to track this specific request\n const requestId = ++currentRequestId\n\n setIsLoading(true)\n setError(null)\n\n try {\n const targetPluginId = pluginId ?? fieldConfig?.plugin\n const contextData = context?.()\n\n const result = await autocompleteCtx.getSuggestions(\n input,\n targetPluginId,\n contextData\n )\n\n // Ignore stale responses - if a newer request was made, discard this result\n if (requestId !== currentRequestId) {\n return\n }\n\n batch(() => {\n setResultType(result.type)\n\n if (result.type === 'completion') {\n setCompletion(result.completion || null)\n setOptions([])\n setIsOpen(!!result.completion)\n } else {\n setCompletion(null)\n setOptions(result.options || [])\n setSelectedIndex(-1)\n setIsOpen((result.options?.length || 0) > 0)\n }\n\n setIsLoading(false)\n })\n } catch (e) {\n // Ignore errors from stale requests\n if (requestId !== currentRequestId) {\n return\n }\n\n batch(() => {\n setError(e instanceof Error ? e.message : 'Unknown error')\n setIsLoading(false)\n setIsOpen(false)\n })\n }\n }\n\n // Debounced fetch\n const debouncedFetch = debounce(fetchSuggestions, config().debounceMs)\n\n // Watch input value changes\n createEffect(\n on(inputValue, (value) => {\n if (!enabled || !autocompleteCtx || isServer) {\n return\n }\n\n debouncedFetch.call(value)\n })\n )\n\n // Cleanup\n onCleanup(() => {\n debouncedFetch.cancel()\n })\n\n /**\n * Accept the current completion\n */\n const acceptCompletion = () => {\n const comp = completion()\n if (comp && onInputChange) {\n onInputChange(comp)\n batch(() => {\n setCompletion(null)\n setIsOpen(false)\n })\n }\n }\n\n /**\n * Select an option\n */\n const selectOption = (option: AutocompleteOption) => {\n if (onInputChange) {\n onInputChange(option.value)\n }\n batch(() => {\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n })\n }\n\n /**\n * Navigate to next option\n */\n const nextOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev + 1\n return next >= opts.length ? 0 : next\n })\n }\n\n /**\n * Navigate to previous option\n */\n const prevOption = () => {\n const opts = options_()\n if (opts.length === 0) return\n\n setSelectedIndex((prev) => {\n const next = prev - 1\n return next < 0 ? opts.length - 1 : next\n })\n }\n\n /**\n * Select current highlighted option\n */\n const selectCurrentOption = () => {\n const idx = selectedIndex()\n const opts = options_()\n if (idx >= 0 && idx < opts.length) {\n selectOption(opts[idx])\n }\n }\n\n /**\n * Dismiss suggestions\n */\n const dismiss = () => {\n debouncedFetch.cancel()\n batch(() => {\n setCompletion(null)\n setOptions([])\n setSelectedIndex(-1)\n setIsOpen(false)\n setError(null)\n })\n }\n\n /**\n * Open suggestions\n */\n const open = () => {\n const input = inputValue()\n if (input.length >= config().minChars) {\n fetchSuggestions(input)\n }\n }\n\n /**\n * Handle keyboard events\n * Returns true if the event was handled\n */\n const handleKeyDown = (e: KeyboardEvent): boolean => {\n if (!isOpen()) return false\n\n const type = resultType()\n\n // Tab to accept completion\n if (e.key === 'Tab' && type === 'completion' && ghostText()) {\n e.preventDefault()\n acceptCompletion()\n return true\n }\n\n // Arrow keys for dropdown navigation\n if (type === 'options') {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n nextOption()\n return true\n\n case 'ArrowUp':\n e.preventDefault()\n prevOption()\n return true\n\n case 'Enter':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n\n case 'Tab':\n if (selectedIndex() >= 0) {\n e.preventDefault()\n selectCurrentOption()\n return true\n }\n break\n }\n }\n\n // Escape to dismiss\n if (e.key === 'Escape') {\n e.preventDefault()\n dismiss()\n return true\n }\n\n return false\n }\n\n return {\n completion,\n ghostText,\n acceptCompletion,\n options: options_,\n selectedIndex,\n selectOption,\n nextOption,\n prevOption,\n selectCurrentOption,\n isLoading,\n error,\n dismiss,\n isOpen,\n resultType,\n open,\n handleKeyDown\n }\n}\n"],"names":[],"mappings":";;;AA6JA,SAAS,SACP,IACA,OACgE;AAChE,MAAI,YAAkD;AAEtD,SAAO;AAAA,IACL,MAAM,IAAI,SAAwB;AAChC,UAAI,wBAAwB,SAAS;AACrC,kBAAY,WAAW,MAAM;AAC3B,WAAG,GAAG,IAAI;AACV,oBAAY;AAAA,MACd,GAAG,KAAK;AAAA,IACV;AAAA,IACA,QAAQ,MAAM;AACZ,UAAI,WAAW;AACb,qBAAa,SAAS;AACtB,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,EAAA;AAEJ;AAKO,SAAS,gBAAgB,SAAwD;AACtF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,EAAA,IACV;AAGJ,QAAM,kBAAkB,2BAAA;AAGxB,QAAM,CAAC,YAAY,aAAa,IAAI,aAA4B,IAAI;AACpE,QAAM,CAAC,UAAU,UAAU,IAAI,aAAmC,CAAA,CAAE;AACpE,QAAM,CAAC,eAAe,gBAAgB,IAAI,aAAa,EAAE;AACzD,QAAM,CAAC,WAAW,YAAY,IAAI,aAAa,KAAK;AACpD,QAAM,CAAC,OAAO,QAAQ,IAAI,aAA4B,IAAI;AAC1D,QAAM,CAAC,QAAQ,SAAS,IAAI,aAAa,KAAK;AAC9C,QAAM,CAAC,YAAY,aAAa,IAAI,aAA8C,IAAI;AAGtF,MAAI,mBAAmB;AAGvB,QAAM,SAAS,WAAW,OAAO;AAAA,IAC/B,UAAU,mBAAkB,2CAAa,cAAY,mDAAiB,OAAO,aAAY;AAAA,IACzF,YAAY,mBAAkB,2CAAa,gBAAc,mDAAiB,OAAO,eAAc;AAAA,EAAA,EAC/F;AAGF,QAAM,YAAY,WAAW,MAAM;AACjC,UAAM,OAAO,WAAA;AACb,UAAM,QAAQ,WAAA;AAEd,QAAI,CAAC,QAAQ,CAAC,MAAO,QAAO;AAG5B,QAAI,KAAK,YAAA,EAAc,WAAW,MAAM,YAAA,CAAa,GAAG;AACtD,aAAO,KAAK,MAAM,MAAM,MAAM;AAAA,IAChC;AAEA,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,mBAAmB,OAAO,UAAkB;AAChD,QAAI,CAAC,iBAAiB;AACpB;AAAA,IACF;AAEA,QAAI,MAAM,SAAS,OAAA,EAAS,UAAU;AACpC,YAAM,MAAM;AACV,sBAAc,IAAI;AAClB,mBAAW,CAAA,CAAE;AACb,kBAAU,KAAK;AACf,sBAAc,IAAI;AAAA,MACpB,CAAC;AACD;AAAA,IACF;AAGA,UAAM,YAAY,EAAE;AAEpB,iBAAa,IAAI;AACjB,aAAS,IAAI;AAEb,QAAI;AACF,YAAM,iBAAiB,aAAY,2CAAa;AAChD,YAAM,cAAc;AAEpB,YAAM,SAAS,MAAM,gBAAgB;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAIF,UAAI,cAAc,kBAAkB;AAClC;AAAA,MACF;AAEA,YAAM,MAAM;;AACV,sBAAc,OAAO,IAAI;AAEzB,YAAI,OAAO,SAAS,cAAc;AAChC,wBAAc,OAAO,cAAc,IAAI;AACvC,qBAAW,CAAA,CAAE;AACb,oBAAU,CAAC,CAAC,OAAO,UAAU;AAAA,QAC/B,OAAO;AACL,wBAAc,IAAI;AAClB,qBAAW,OAAO,WAAW,EAAE;AAC/B,2BAAiB,EAAE;AACnB,uBAAW,YAAO,YAAP,mBAAgB,WAAU,KAAK,CAAC;AAAA,QAC7C;AAEA,qBAAa,KAAK;AAAA,MACpB,CAAC;AAAA,IACH,SAAS,GAAG;AAEV,UAAI,cAAc,kBAAkB;AAClC;AAAA,MACF;AAEA,YAAM,MAAM;AACV,iBAAS,aAAa,QAAQ,EAAE,UAAU,eAAe;AACzD,qBAAa,KAAK;AAClB,kBAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,iBAAiB,SAAS,kBAAkB,OAAA,EAAS,UAAU;AAGrE;AAAA,IACE,GAAG,YAAY,CAAC,UAAU;AACxB,UAAI,CAAC,WAAW,CAAC,mBAAmB,UAAU;AAC5C;AAAA,MACF;AAEA,qBAAe,KAAK,KAAK;AAAA,IAC3B,CAAC;AAAA,EAAA;AAIH,YAAU,MAAM;AACd,mBAAe,OAAA;AAAA,EACjB,CAAC;AAKD,QAAM,mBAAmB,MAAM;AAC7B,UAAM,OAAO,WAAA;AACb,QAAI,QAAQ,eAAe;AACzB,oBAAc,IAAI;AAClB,YAAM,MAAM;AACV,sBAAc,IAAI;AAClB,kBAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AAKA,QAAM,eAAe,CAAC,WAA+B;AACnD,QAAI,eAAe;AACjB,oBAAc,OAAO,KAAK;AAAA,IAC5B;AACA,UAAM,MAAM;AACV,iBAAW,CAAA,CAAE;AACb,uBAAiB,EAAE;AACnB,gBAAU,KAAK;AAAA,IACjB,CAAC;AAAA,EACH;AAKA,QAAM,aAAa,MAAM;AACvB,UAAM,OAAO,SAAA;AACb,QAAI,KAAK,WAAW,EAAG;AAEvB,qBAAiB,CAAC,SAAS;AACzB,YAAM,OAAO,OAAO;AACpB,aAAO,QAAQ,KAAK,SAAS,IAAI;AAAA,IACnC,CAAC;AAAA,EACH;AAKA,QAAM,aAAa,MAAM;AACvB,UAAM,OAAO,SAAA;AACb,QAAI,KAAK,WAAW,EAAG;AAEvB,qBAAiB,CAAC,SAAS;AACzB,YAAM,OAAO,OAAO;AACpB,aAAO,OAAO,IAAI,KAAK,SAAS,IAAI;AAAA,IACtC,CAAC;AAAA,EACH;AAKA,QAAM,sBAAsB,MAAM;AAChC,UAAM,MAAM,cAAA;AACZ,UAAM,OAAO,SAAA;AACb,QAAI,OAAO,KAAK,MAAM,KAAK,QAAQ;AACjC,mBAAa,KAAK,GAAG,CAAC;AAAA,IACxB;AAAA,EACF;AAKA,QAAM,UAAU,MAAM;AACpB,mBAAe,OAAA;AACf,UAAM,MAAM;AACV,oBAAc,IAAI;AAClB,iBAAW,CAAA,CAAE;AACb,uBAAiB,EAAE;AACnB,gBAAU,KAAK;AACf,eAAS,IAAI;AAAA,IACf,CAAC;AAAA,EACH;AAKA,QAAM,OAAO,MAAM;AACjB,UAAM,QAAQ,WAAA;AACd,QAAI,MAAM,UAAU,OAAA,EAAS,UAAU;AACrC,uBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAMA,QAAM,gBAAgB,CAAC,MAA8B;AACnD,QAAI,CAAC,OAAA,EAAU,QAAO;AAEtB,UAAM,OAAO,WAAA;AAGb,QAAI,EAAE,QAAQ,SAAS,SAAS,gBAAgB,aAAa;AAC3D,QAAE,eAAA;AACF,uBAAA;AACA,aAAO;AAAA,IACT;AAGA,QAAI,SAAS,WAAW;AACtB,cAAQ,EAAE,KAAA;AAAA,QACR,KAAK;AACH,YAAE,eAAA;AACF,qBAAA;AACA,iBAAO;AAAA,QAET,KAAK;AACH,YAAE,eAAA;AACF,qBAAA;AACA,iBAAO;AAAA,QAET,KAAK;AACH,cAAI,cAAA,KAAmB,GAAG;AACxB,cAAE,eAAA;AACF,gCAAA;AACA,mBAAO;AAAA,UACT;AACA;AAAA,QAEF,KAAK;AACH,cAAI,cAAA,KAAmB,GAAG;AACxB,cAAE,eAAA;AACF,gCAAA;AACA,mBAAO;AAAA,UACT;AACA;AAAA,MAAA;AAAA,IAEN;AAGA,QAAI,EAAE,QAAQ,UAAU;AACtB,QAAE,eAAA;AACF,cAAA;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../../../../../../node_modules/.pnpm/@tanstack+solid-virtual@3.13.18_solid-js@1.9.
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../../../../../../node_modules/.pnpm/@tanstack+solid-virtual@3.13.18_solid-js@1.9.11/node_modules/@tanstack/solid-virtual/dist/esm/index.js"],"sourcesContent":["import { elementScroll, observeElementOffset, observeElementRect, windowScroll, observeWindowOffset, observeWindowRect, Virtualizer } from \"@tanstack/virtual-core\";\nexport * from \"@tanstack/virtual-core\";\nimport { mergeProps, createSignal, onMount, onCleanup, createComputed } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\nfunction createVirtualizerBase(options) {\n const resolvedOptions = mergeProps(options);\n const instance = new Virtualizer(resolvedOptions);\n const [virtualItems, setVirtualItems] = createStore(instance.getVirtualItems());\n const [totalSize, setTotalSize] = createSignal(instance.getTotalSize());\n const handler = {\n get(target, prop) {\n switch (prop) {\n case \"getVirtualItems\":\n return () => virtualItems;\n case \"getTotalSize\":\n return () => totalSize();\n default:\n return Reflect.get(target, prop);\n }\n }\n };\n const virtualizer = new Proxy(instance, handler);\n virtualizer.setOptions(resolvedOptions);\n onMount(() => {\n const cleanup = virtualizer._didMount();\n virtualizer._willUpdate();\n onCleanup(cleanup);\n });\n createComputed(() => {\n virtualizer.setOptions(mergeProps(resolvedOptions, options, {\n onChange: (instance2, sync) => {\n var _a;\n instance2._willUpdate();\n setVirtualItems(reconcile(instance2.getVirtualItems(), {\n key: \"index\"\n }));\n setTotalSize(instance2.getTotalSize());\n (_a = options.onChange) == null ? void 0 : _a.call(options, instance2, sync);\n }\n }));\n virtualizer.measure();\n });\n return virtualizer;\n}\nfunction createVirtualizer(options) {\n return createVirtualizerBase(mergeProps({\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll\n }, options));\n}\nfunction createWindowVirtualizer(options) {\n return createVirtualizerBase(mergeProps({\n getScrollElement: () => typeof document !== \"undefined\" ? window : null,\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => typeof document !== \"undefined\" ? window.scrollY : 0\n }, options));\n}\nexport {\n createVirtualizer,\n createWindowVirtualizer\n};\n//# sourceMappingURL=index.js.map\n"],"names":["mergeProps","Virtualizer","createStore","createSignal","onMount","onCleanup","createComputed","reconcile","observeElementRect","observeElementOffset","elementScroll"],"mappings":";;;;;;AAIA,SAAS,sBAAsB,SAAS;AACtC,QAAM,kBAAkBA,QAAAA,WAAW,OAAO;AAC1C,QAAM,WAAW,IAAIC,MAAAA,YAAY,eAAe;AAChD,QAAM,CAAC,cAAc,eAAe,IAAIC,MAAAA,YAAY,SAAS,iBAAiB;AAC9E,QAAM,CAAC,WAAW,YAAY,IAAIC,QAAAA,aAAa,SAAS,cAAc;AACtE,QAAM,UAAU;AAAA,IACd,IAAI,QAAQ,MAAM;AAChB,cAAQ,MAAI;AAAA,QACV,KAAK;AACH,iBAAO,MAAM;AAAA,QACf,KAAK;AACH,iBAAO,MAAM,UAAS;AAAA,QACxB;AACE,iBAAO,QAAQ,IAAI,QAAQ,IAAI;AAAA,MACzC;AAAA,IACI;AAAA,EACJ;AACE,QAAM,cAAc,IAAI,MAAM,UAAU,OAAO;AAC/C,cAAY,WAAW,eAAe;AACtCC,UAAAA,QAAQ,MAAM;AACZ,UAAM,UAAU,YAAY,UAAS;AACrC,gBAAY,YAAW;AACvBC,YAAAA,UAAU,OAAO;AAAA,EACnB,CAAC;AACDC,UAAAA,eAAe,MAAM;AACnB,gBAAY,WAAWN,mBAAW,iBAAiB,SAAS;AAAA,MAC1D,UAAU,CAAC,WAAW,SAAS;AAC7B,YAAI;AACJ,kBAAU,YAAW;AACrB,wBAAgBO,MAAAA,UAAU,UAAU,mBAAmB;AAAA,UACrD,KAAK;AAAA,QACf,CAAS,CAAC;AACF,qBAAa,UAAU,cAAc;AACrC,SAAC,KAAK,QAAQ,aAAa,OAAO,SAAS,GAAG,KAAK,SAAS,WAAW,IAAI;AAAA,MAC7E;AAAA,IACN,CAAK,CAAC;AACF,gBAAY,QAAO;AAAA,EACrB,CAAC;AACD,SAAO;AACT;AACA,SAAS,kBAAkB,SAAS;AAClC,SAAO,sBAAsBP,QAAAA,WAAW;AAAA,IAC1C,oBAAIQ,MAAAA;AAAAA,IACJ,sBAAIC,MAAAA;AAAAA,IACA,YAAYC,MAAAA;AAAAA,EAChB,GAAK,OAAO,CAAC;AACb;;;;;;;;;;;;;","x_google_ignoreList":[0]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../../../../../node_modules/.pnpm/@tanstack+solid-virtual@3.13.18_solid-js@1.9.
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../../../../../node_modules/.pnpm/@tanstack+solid-virtual@3.13.18_solid-js@1.9.11/node_modules/@tanstack/solid-virtual/dist/esm/index.js"],"sourcesContent":["import { elementScroll, observeElementOffset, observeElementRect, windowScroll, observeWindowOffset, observeWindowRect, Virtualizer } from \"@tanstack/virtual-core\";\nexport * from \"@tanstack/virtual-core\";\nimport { mergeProps, createSignal, onMount, onCleanup, createComputed } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\nfunction createVirtualizerBase(options) {\n const resolvedOptions = mergeProps(options);\n const instance = new Virtualizer(resolvedOptions);\n const [virtualItems, setVirtualItems] = createStore(instance.getVirtualItems());\n const [totalSize, setTotalSize] = createSignal(instance.getTotalSize());\n const handler = {\n get(target, prop) {\n switch (prop) {\n case \"getVirtualItems\":\n return () => virtualItems;\n case \"getTotalSize\":\n return () => totalSize();\n default:\n return Reflect.get(target, prop);\n }\n }\n };\n const virtualizer = new Proxy(instance, handler);\n virtualizer.setOptions(resolvedOptions);\n onMount(() => {\n const cleanup = virtualizer._didMount();\n virtualizer._willUpdate();\n onCleanup(cleanup);\n });\n createComputed(() => {\n virtualizer.setOptions(mergeProps(resolvedOptions, options, {\n onChange: (instance2, sync) => {\n var _a;\n instance2._willUpdate();\n setVirtualItems(reconcile(instance2.getVirtualItems(), {\n key: \"index\"\n }));\n setTotalSize(instance2.getTotalSize());\n (_a = options.onChange) == null ? void 0 : _a.call(options, instance2, sync);\n }\n }));\n virtualizer.measure();\n });\n return virtualizer;\n}\nfunction createVirtualizer(options) {\n return createVirtualizerBase(mergeProps({\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll\n }, options));\n}\nfunction createWindowVirtualizer(options) {\n return createVirtualizerBase(mergeProps({\n getScrollElement: () => typeof document !== \"undefined\" ? window : null,\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => typeof document !== \"undefined\" ? window.scrollY : 0\n }, options));\n}\nexport {\n createVirtualizer,\n createWindowVirtualizer\n};\n//# sourceMappingURL=index.js.map\n"],"names":[],"mappings":";;;;;AAIA,SAAS,sBAAsB,SAAS;AACtC,QAAM,kBAAkB,WAAW,OAAO;AAC1C,QAAM,WAAW,IAAI,YAAY,eAAe;AAChD,QAAM,CAAC,cAAc,eAAe,IAAI,YAAY,SAAS,iBAAiB;AAC9E,QAAM,CAAC,WAAW,YAAY,IAAI,aAAa,SAAS,cAAc;AACtE,QAAM,UAAU;AAAA,IACd,IAAI,QAAQ,MAAM;AAChB,cAAQ,MAAI;AAAA,QACV,KAAK;AACH,iBAAO,MAAM;AAAA,QACf,KAAK;AACH,iBAAO,MAAM,UAAS;AAAA,QACxB;AACE,iBAAO,QAAQ,IAAI,QAAQ,IAAI;AAAA,MACzC;AAAA,IACI;AAAA,EACJ;AACE,QAAM,cAAc,IAAI,MAAM,UAAU,OAAO;AAC/C,cAAY,WAAW,eAAe;AACtC,UAAQ,MAAM;AACZ,UAAM,UAAU,YAAY,UAAS;AACrC,gBAAY,YAAW;AACvB,cAAU,OAAO;AAAA,EACnB,CAAC;AACD,iBAAe,MAAM;AACnB,gBAAY,WAAW,WAAW,iBAAiB,SAAS;AAAA,MAC1D,UAAU,CAAC,WAAW,SAAS;AAC7B,YAAI;AACJ,kBAAU,YAAW;AACrB,wBAAgB,UAAU,UAAU,mBAAmB;AAAA,UACrD,KAAK;AAAA,QACf,CAAS,CAAC;AACF,qBAAa,UAAU,cAAc;AACrC,SAAC,KAAK,QAAQ,aAAa,OAAO,SAAS,GAAG,KAAK,SAAS,WAAW,IAAI;AAAA,MAC7E;AAAA,IACN,CAAK,CAAC;AACF,gBAAY,QAAO;AAAA,EACrB,CAAC;AACD,SAAO;AACT;AACA,SAAS,kBAAkB,SAAS;AAClC,SAAO,sBAAsB,WAAW;AAAA,IACtC;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EAChB,GAAK,OAAO,CAAC;AACb;","x_google_ignoreList":[0]}
|