49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
import type { Database } from 'sql.js'
|
|
import type { Entry } from './types'
|
|
import { getMeta, persistDb, setMeta, upsertEntries } from './db'
|
|
|
|
const LAST_SYNC_KEY = 'last_sync_at'
|
|
|
|
export async function syncEntries(db: Database) {
|
|
const lastSyncAt = getMeta(db, LAST_SYNC_KEY)
|
|
const url = new URL('https://sanasto.wiki/api/entries')
|
|
if (lastSyncAt) {
|
|
url.searchParams.set('since', lastSyncAt)
|
|
}
|
|
|
|
const response = await fetch(url.toString(), {
|
|
headers: {
|
|
'X-Sanasto-App': 'app.sanasto',
|
|
},
|
|
})
|
|
if (!response.ok) {
|
|
throw new Error(`Sync failed with ${response.status}`)
|
|
}
|
|
|
|
const entries = (await response.json()) as Entry[]
|
|
if (entries.length === 0) {
|
|
return { updated: 0, lastSyncAt }
|
|
}
|
|
|
|
upsertEntries(db, entries)
|
|
|
|
const newest = entries.reduce<Date | null>((current, entry) => {
|
|
if (!entry.updated_at) {
|
|
return current
|
|
}
|
|
const date = new Date(entry.updated_at)
|
|
if (!current || date > current) {
|
|
return date
|
|
}
|
|
return current
|
|
}, lastSyncAt ? new Date(lastSyncAt) : null)
|
|
|
|
if (newest) {
|
|
setMeta(db, LAST_SYNC_KEY, newest.toISOString())
|
|
}
|
|
|
|
await persistDb(db)
|
|
|
|
return { updated: entries.length, lastSyncAt: newest?.toISOString() ?? lastSyncAt }
|
|
}
|