110 lines
3.2 KiB
JavaScript
110 lines
3.2 KiB
JavaScript
const endpoint = process.env.APPWRITE_SELF_HOSTED_URL || 'https://app.friborg.uk/v1'
|
|
const projectId = process.env.APPWRITE_SELF_HOSTED_PROJECT_ID || 'freecastle'
|
|
|
|
export const BUILDPULSE_DATABASE_ID = process.env.BUILDPULSE_APPWRITE_DATABASE_ID || process.env.APPWRITE_SELF_HOSTED_DATABASE_ID || 'freecastle'
|
|
export const BUILDPULSE_COLLECTION_ID = process.env.BUILDPULSE_APPWRITE_COLLECTION_ID || 'runtime'
|
|
export const BUILDPULSE_DOCUMENT_ID = process.env.BUILDPULSE_APPWRITE_DOCUMENT_ID || 'buildpulse_state'
|
|
export const BUILDPULSE_DOCUMENT_KEY = process.env.BUILDPULSE_APPWRITE_DOCUMENT_KEY || 'buildpulse_state'
|
|
|
|
const baseHeaders = {
|
|
'Content-Type': 'application/json',
|
|
'X-Appwrite-Project': projectId,
|
|
}
|
|
|
|
const REQUEST_TIMEOUT_MS = Number(process.env.BUILDPULSE_APPWRITE_TIMEOUT_MS || 4500)
|
|
const documentUrl = `${endpoint}/databases/${BUILDPULSE_DATABASE_ID}/collections/${BUILDPULSE_COLLECTION_ID}/documents/${BUILDPULSE_DOCUMENT_ID}`
|
|
const collectionUrl = `${endpoint}/databases/${BUILDPULSE_DATABASE_ID}/collections/${BUILDPULSE_COLLECTION_ID}/documents`
|
|
|
|
async function appwriteFetch(url, init = {}) {
|
|
const controller = new AbortController()
|
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)
|
|
|
|
let response
|
|
try {
|
|
response = await fetch(url, {
|
|
...init,
|
|
signal: init.signal || controller.signal,
|
|
headers: {
|
|
...baseHeaders,
|
|
...(init.headers || {}),
|
|
},
|
|
})
|
|
} catch (error) {
|
|
if (error?.name === 'AbortError') {
|
|
const timeoutError = new Error(`Appwrite request timed out after ${REQUEST_TIMEOUT_MS}ms`)
|
|
timeoutError.status = 504
|
|
throw timeoutError
|
|
}
|
|
throw error
|
|
} finally {
|
|
clearTimeout(timeout)
|
|
}
|
|
|
|
if (response.status === 204) return null
|
|
|
|
const text = await response.text()
|
|
const payload = text ? JSON.parse(text) : null
|
|
|
|
if (!response.ok) {
|
|
const error = new Error(payload?.message || `Appwrite request failed with ${response.status}`)
|
|
error.status = response.status
|
|
error.payload = payload
|
|
throw error
|
|
}
|
|
|
|
return payload
|
|
}
|
|
|
|
export async function fetchStoredAppState() {
|
|
try {
|
|
const document = await appwriteFetch(documentUrl)
|
|
return document?.value ? JSON.parse(document.value) : null
|
|
} catch (error) {
|
|
if (error?.status === 404) return null
|
|
throw error
|
|
}
|
|
}
|
|
|
|
export async function persistAppState(state) {
|
|
const body = {
|
|
data: {
|
|
key: BUILDPULSE_DOCUMENT_KEY,
|
|
value: JSON.stringify(state),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
}
|
|
|
|
try {
|
|
return await appwriteFetch(documentUrl, {
|
|
method: 'PATCH',
|
|
body: JSON.stringify(body),
|
|
})
|
|
} catch (error) {
|
|
if (error?.status !== 404) throw error
|
|
}
|
|
|
|
return appwriteFetch(collectionUrl, {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
documentId: BUILDPULSE_DOCUMENT_ID,
|
|
...body,
|
|
}),
|
|
})
|
|
}
|
|
|
|
export async function checkBackendHealth() {
|
|
const document = await appwriteFetch(documentUrl).catch((error) => {
|
|
if (error?.status === 404) return null
|
|
throw error
|
|
})
|
|
|
|
return {
|
|
ok: true,
|
|
backend: 'appwrite',
|
|
endpoint,
|
|
databaseId: BUILDPULSE_DATABASE_ID,
|
|
collectionId: BUILDPULSE_COLLECTION_ID,
|
|
documentPresent: Boolean(document),
|
|
}
|
|
}
|