(
options: SyncOptions = {}
)
| 582 | } |
| 583 | |
| 584 | export async function syncBookmarksGraphQL( |
| 585 | options: SyncOptions = {} |
| 586 | ): Promise<SyncResult> { |
| 587 | const incremental = options.incremental ?? true; |
| 588 | const maxPages = options.maxPages ?? Infinity; |
| 589 | const delayMs = options.delayMs ?? 600; |
| 590 | const maxMinutes = options.maxMinutes ?? 30; |
| 591 | const stalePageLimit = options.stalePageLimit ?? 3; |
| 592 | const checkpointEvery = options.checkpointEvery ?? 25; |
| 593 | const pageSize = Math.max(1, Math.min(options.pageSize ?? 20, 100)); |
| 594 | |
| 595 | let csrfToken: string; |
| 596 | let cookieHeader: string | undefined; |
| 597 | |
| 598 | if (options.csrfToken) { |
| 599 | csrfToken = options.csrfToken; |
| 600 | cookieHeader = options.cookieHeader; |
| 601 | } else { |
| 602 | const config = loadChromeSessionConfig({ browserId: options.browser }); |
| 603 | |
| 604 | if (config.browser.cookieBackend === 'firefox') { |
| 605 | const cookies = extractFirefoxXCookies(options.firefoxProfileDir); |
| 606 | csrfToken = cookies.csrfToken; |
| 607 | cookieHeader = cookies.cookieHeader; |
| 608 | } else { |
| 609 | const chromeDir = options.chromeUserDataDir ?? config.chromeUserDataDir; |
| 610 | const chromeProfile = options.chromeProfileDirectory ?? config.chromeProfileDirectory; |
| 611 | const cookies = extractChromeXCookies(chromeDir, chromeProfile, config.browser); |
| 612 | csrfToken = cookies.csrfToken; |
| 613 | cookieHeader = cookies.cookieHeader; |
| 614 | } |
| 615 | } |
| 616 | |
| 617 | ensureDataDir(); |
| 618 | const cachePath = twitterBookmarksCachePath(); |
| 619 | const metaPath = twitterBookmarksMetaPath(); |
| 620 | const statePath = twitterBackfillStatePath(); |
| 621 | const loaded = await loadExistingBookmarks(); |
| 622 | let existing = loaded.records; |
| 623 | const bookmarkedAtRepaired = loaded.repaired; |
| 624 | const newestKnownId = incremental ? existing[0]?.id : undefined; |
| 625 | const previousMeta = (await pathExists(metaPath)) |
| 626 | ? await readJson<BookmarkCacheMeta>(metaPath) |
| 627 | : undefined; |
| 628 | const prevState: BookmarkBackfillState = (await pathExists(statePath)) |
| 629 | ? await readJson<BookmarkBackfillState>(statePath) |
| 630 | : { provider: 'twitter', totalRuns: 0, totalAdded: 0, lastAdded: 0, lastSeenIds: [] }; |
| 631 | |
| 632 | const started = Date.now(); |
| 633 | let page = 0; |
| 634 | let totalAdded = 0; |
| 635 | let stalePages = 0; |
| 636 | let cursor: string | undefined = options.resumeCursor; |
| 637 | const allSeenIds: string[] = []; |
| 638 | let stopReason = 'unknown'; |
| 639 | let retryAfterSec: number | undefined; |
| 640 | |
| 641 | const fetchNextPage = async (): Promise<PageResult | undefined> => { |
no test coverage detected