import { writable, type Unsubscriber, type Writable } from 'svelte/store' import type { RepoCollection, RepoEvent, RepoReadme, } from '$lib/components/repo/type' import { collection_defaults, event_defaults, readme_defaults, } from '$lib/components/repo/type' import { ensureRepoCollection } from './repos' import { cloneArrayToReadMeUrls, selectRepoFromCollection, } from '$lib/components/repo/utils' import { get } from 'svelte/store' export const selected_repo_collection: Writable = writable({ ...collection_defaults, }) export const selected_repo_event: Writable = writable({ ...event_defaults, }) selected_repo_collection.subscribe((collection) => { const selected_from_collection = selectRepoFromCollection(collection) if (selected_from_collection) selected_repo_event.set({ ...selected_from_collection }) }) let selected_repo_unique_commit_or_identifier: string = '' let selected_unsubscriber: Unsubscriber export const ensureSelectedRepoCollection = ( unique_commit_or_identifier: string ): Writable => { if ( selected_repo_unique_commit_or_identifier !== unique_commit_or_identifier ) { let loading = true selected_repo_unique_commit_or_identifier = unique_commit_or_identifier if (selected_unsubscriber) selected_unsubscriber() selected_unsubscriber = ensureRepoCollection( unique_commit_or_identifier ).subscribe((repo_collection) => { selected_repo_collection.set({ ...repo_collection }) if (loading && !repo_collection.loading) { loading = false const repo_event = selectRepoFromCollection(repo_collection) if (repo_event) ensureRepoReadme(repo_event.clone, repo_collection.identifier) } }) } return selected_repo_collection } export const awaitSelectedRepoCollection = async ( unique_commit_or_identifier: string ): Promise => { return new Promise((r) => { const unsubscriber = ensureSelectedRepoCollection( unique_commit_or_identifier ).subscribe((repo_collection) => { if ( selected_repo_unique_commit_or_identifier == unique_commit_or_identifier && !repo_collection.loading ) { setTimeout(() => { if (unsubscriber) unsubscriber() }, 5) r({ ...repo_collection }) } }) }) } export const selected_repo_readme: Writable = writable({ ...readme_defaults, }) const ensureRepoReadme = async ( clone: string[], unique_commit_or_identifier: string ): Promise => { selected_repo_readme.set({ ...readme_defaults }) /** update writable unless selected readme has changed */ const update = (md: string | undefined = undefined): void => { const latest_collection = get(selected_repo_collection) if ( [latest_collection.identifier, latest_collection.unique_commit].includes( unique_commit_or_identifier ) ) { selected_repo_readme.set({ md: md || '', loading: false, failed: !md, }) } } let text: string | undefined try { let readme_urls = cloneArrayToReadMeUrls(clone) // prioritise using github as it doesn't require a proxy readme_urls = [ ...readme_urls.filter((url) => url.includes('raw.githubusercontent.com')), ...readme_urls.filter( (url) => !url.includes('raw.githubusercontent.com') ), ] for (let i = 0; i < readme_urls.length; i++) { try { const res = await fetch( readme_urls[i].includes('raw.githubusercontent.com') ? readme_urls[i] : // use proxy as most servers produce a CORS error `/git_proxy/readme/${encodeURIComponent(readme_urls[i])}` ) if (res.ok) { text = await res.text() break } else { continue } } catch { continue } } } catch {} update(text) }