| 1 | import type { EnvironmentId } from "@t3tools/contracts"; |
| 2 | import type { AtomCommandResult } from "@t3tools/client-runtime/state/runtime"; |
| 3 | import { |
| 4 | isAtomCommandInterrupted, |
| 5 | squashAtomCommandFailure, |
| 6 | } from "@t3tools/client-runtime/state/runtime"; |
| 7 | |
| 8 | type RefreshProvidersTarget = { |
| 9 | readonly environmentId: EnvironmentId; |
| 10 | readonly input: { readonly refreshModels: true }; |
| 11 | }; |
| 12 | |
| 13 | /** Pull-to-refresh in the model picker shares any pending discovery. */ |
| 14 | export function createProviderCatalogRefreshRunner<Result>( |
| 15 | refreshProviders: (target: RefreshProvidersTarget) => Promise<Result>, |
| 16 | ) { |
| 17 | let pending: Promise<Result> | null = null; |
| 18 | |
| 19 | return (environmentId: EnvironmentId): Promise<Result> => { |
| 20 | if (pending) return pending; |
| 21 | pending = refreshProviders({ environmentId, input: { refreshModels: true } }).finally(() => { |
| 22 | pending = null; |
| 23 | }); |
| 24 | return pending; |
| 25 | }; |
| 26 | } |
| 27 | |
| 28 | export function providerCatalogRefreshError( |
| 29 | result: AtomCommandResult<unknown, unknown>, |
| 30 | ): string | null { |
| 31 | if (result._tag !== "Failure" || isAtomCommandInterrupted(result)) return null; |
| 32 | const error = squashAtomCommandFailure(result); |
| 33 | return error instanceof Error ? error.message : "Provider discovery failed."; |
| 34 | } |