doc.get.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. type DocResponse = { code: number, msg: string, data: string }
  2. const TTL_MS = 60 * 60 * 1000
  3. const cache = new Map<string, { value: string, expiresAt: number }>()
  4. const inFlight = new Map<string, Promise<string>>()
  5. export default defineEventHandler(async (event) => {
  6. const { key } = getQuery(event) as { key?: string }
  7. if (!key) {
  8. throw createError({ statusCode: 400, statusMessage: 'Missing key' })
  9. }
  10. const now = Date.now()
  11. const hit = cache.get(key)
  12. if (hit && hit.expiresAt > now) {
  13. return { code: 0, msg: '', data: hit.value }
  14. }
  15. const existing = inFlight.get(key)
  16. if (existing) {
  17. return { code: 0, msg: '', data: await existing }
  18. }
  19. const p = (async () => {
  20. const runtimeConfig = useRuntimeConfig()
  21. const baseURL = runtimeConfig.serverApiBase as string | undefined
  22. if (!baseURL) {
  23. throw createError({ statusCode: 500, statusMessage: 'Missing serverApiBase' })
  24. }
  25. const res = await $fetch<DocResponse>('/base/doc/get', {
  26. baseURL,
  27. params: { key },
  28. })
  29. if (!res || res.code !== 0) {
  30. throw createError({ statusCode: 500, statusMessage: res?.msg || 'Request failed' })
  31. }
  32. const html = res.data || ''
  33. cache.set(key, { value: html, expiresAt: Date.now() + TTL_MS })
  34. return html
  35. })()
  36. inFlight.set(key, p)
  37. try {
  38. return { code: 0, msg: '', data: await p }
  39. }
  40. finally {
  41. inFlight.delete(key)
  42. }
  43. })