import { code, refkey } from "@alloy-js/core"; import * as ts from "@alloy-js/typescript"; import { Declaration } from "@alloy-js/typescript"; export function getPagedAsyncIterableIteratorRefkey() { return refkey("PagedAsyncIterableIterator", "interface"); } export function getBuildPagedAsyncIteratorRefkey() { return refkey("buildPagedAsyncIterator", "function"); } function getPagedResultRefkey() { return refkey("PagedResult", "interface"); } function getBuildPagedAsyncIteratorOptionsRefkey() { return refkey("BuildPagedAsyncIteratorOptions", "interface"); } function PagedAsyncIterableIteratorInterfaceDeclaration() { return ( {code` /** * An interface that allows async iterable iteration both to completion and by page. */ export interface PagedAsyncIterableIterator< TElement, TPageResponse, TPageSettings, > { /** * The next method, part of the iteration protocol */ next(): Promise>; /** * The connection to the async iterator, part of the iteration protocol */ [Symbol.asyncIterator](): PagedAsyncIterableIterator< TElement, TPageResponse, TPageSettings >; /** * Return an AsyncIterableIterator that works a page at a time */ byPage: ( settings?: TPageSettings, ) => AsyncIterableIterator; } `} ); } function PagedResultInterfaceDeclaration() { return ( {code` /** * An interface that describes how to communicate with the service. */ interface PagedResult< TElement, TPageResponse, TPageSettings, > { /** * Extract the paged elements from the response. Only support array of elements. * @param response paged response * @returns TElement[] */ getElements: (response: TPageResponse) => TElement[]; /** * A method that returns a page of results. */ getPage: ( nextLinkOrContinuationToken?: string, settings?: TPageSettings, ) => Promise<{ pagedResponse: TPageResponse; nextToken?: string } | undefined>; /** * a function to implement the \`byPage\` method on the paged async iterator. */ byPage: ( settings?: TPageSettings, ) => AsyncIterableIterator; }`} ); } function BuildPagedAsyncIteratorOptionsInterfaceDeclaration() { return ( {code` /** * Options for the paging helper */ export interface BuildPagedAsyncIteratorOptions< TElement, TPageResponse, TPageSettings, > { getElements: (response: TPageResponse) => TElement[]; getPagedResponse: (nextToken?: string, settings?: TPageSettings) => Promise<{ pagedResponse: TPageResponse; nextToken?: string } | undefined>; }`} ); } function BuildPagedAsyncIteratorInterfaceDeclaration() { return ( {code` /** * Helper to paginate results in a generic way and return a PagedAsyncIterableIterator */ export function buildPagedAsyncIterator< TElement, TPageResponse, TPageSettings >( options: BuildPagedAsyncIteratorOptions, ): PagedAsyncIterableIterator { const pagedResult: ${getPagedResultRefkey()} = { getElements: options.getElements, getPage: options.getPagedResponse, byPage: (setting?: TPageSettings) => { return getPageAsyncIterator(pagedResult, { setting }); }, }; const iter = getItemAsyncIterator(pagedResult); return { next() { return iter.next(); }, [Symbol.asyncIterator]() { return this; }, byPage: pagedResult.byPage, }; } async function* getItemAsyncIterator( pagedResult: ${getPagedResultRefkey()}, ): AsyncIterableIterator { const pages = getPageAsyncIterator(pagedResult); for await (const page of pages) { const results = pagedResult.getElements(page); yield* results; } } async function* getPageAsyncIterator( pagedResult: ${getPagedResultRefkey()}, options: { setting?: TPageSettings; } = {}, ): AsyncIterableIterator { let response = await pagedResult.getPage(undefined, options.setting); let results = response?.pagedResponse; let nextToken = response?.nextToken; if (!results) { return; } yield results; while (nextToken) { response = await pagedResult.getPage(nextToken, options.setting); if (!response) { return; } results = response.pagedResponse; nextToken = response.nextToken; yield results; } }`} ); } export function PagingHelpers() { return ( ); }