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 (
);
}