mod.tsimport {
BaseOptions,
Fetch,
exportPages,
listPages,
getPage,
readLinksBulk,
InvalidFollowingIdError,
Result,
TooLongURIError,
} from "../scrapbox-userscript-std/rest.ts";
import {
Page,
ExportedPage,
NotFoundError,
NotLoggedInError,
NotMemberError,
} from "../scrapbox-jp%2Ftypes/rest.ts";
import { makeThrottle } from "https://raw.githubusercontent.com/takker99/Scrapbubble/0.7.3/throttle.ts";
export interface PageLoader {
count: number;
pages: ExportedPage<true>[] | AsyncGenerator<
Result<Page, NotFoundError | NotLoggedInError | NotMemberError | TooLongURIError>,
void,
unknown
>;
}
export const getAllPages = async (project: string, options?: BaseOptions): Promise<Result<PageLoader, NotFoundError | NotLoggedInError | NotMemberError | InvalidFollowingIdError>> => {
{
const result = await exportPages(project, { metadata: true, ...options });
if (result.ok) return {
ok: true,
value: {
count: result.value.pages.length,
pages: result.value.pages,
},
};
const error = result.value;
if (error.name === "NotFoundError") return { ok: false, value: error };
}
const result = await listPages(project, { ...options, limit: 1 });
if (!result.ok) return result;
const reader = await readLinksBulk(project, options);
if ("name" in reader) return { ok: false, value: reader };
return {
ok: true,
value: {
count: result.value.count,
pages: (async function* () {
const promises: Promise<
Result<Page, NotFoundError | NotLoggedInError | NotMemberError | TooLongURIError>
>[] = [];
const throttle = makeThrottle<Response>(3);
const { fetch: fetch_ = globalThis.fetch, ...rest } = options ?? {};
const fetch: Fetch = (args) => throttle(() => fetch_(args));
for await (const links of reader) {
promises.push(...links.map(
(link) => getPage(project, link.title, { ...rest, fetch })
));
}
for await (const promise of promises) {
yield await promise;
}
})(),
},
};
};