share.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { Bus } from "../bus"
  2. import { Installation } from "../installation"
  3. import { Session } from "../session"
  4. import { Storage } from "../storage/storage"
  5. import { Log } from "../util/log"
  6. export namespace Share {
  7. const log = Log.create({ service: "share" })
  8. let queue: Promise<void> = Promise.resolve()
  9. const pending = new Map<string, any>()
  10. export async function sync(key: string, content: any) {
  11. const [root, ...splits] = key.split("/")
  12. if (root !== "session") return
  13. const [sub, sessionID] = splits
  14. if (sub === "share") return
  15. const share = await Session.getShare(sessionID).catch(() => {})
  16. if (!share) return
  17. const { secret } = share
  18. pending.set(key, content)
  19. queue = queue
  20. .then(async () => {
  21. const content = pending.get(key)
  22. if (content === undefined) return
  23. pending.delete(key)
  24. return fetch(`${URL}/share_sync`, {
  25. method: "POST",
  26. body: JSON.stringify({
  27. sessionID: sessionID,
  28. secret,
  29. key: key,
  30. content,
  31. }),
  32. })
  33. })
  34. .then((x) => {
  35. if (x) {
  36. log.info("synced", {
  37. key: key,
  38. status: x.status,
  39. })
  40. }
  41. })
  42. }
  43. export function init() {
  44. Bus.subscribe(Storage.Event.Write, async (payload) => {
  45. await sync(payload.properties.key, payload.properties.content)
  46. })
  47. }
  48. export const URL =
  49. process.env["OPENCODE_API"] ??
  50. (Installation.isSnapshot() || Installation.isDev()
  51. ? "https://api.dev.opencode.ai"
  52. : "https://api.opencode.ai")
  53. export async function create(sessionID: string) {
  54. return fetch(`${URL}/share_create`, {
  55. method: "POST",
  56. body: JSON.stringify({ sessionID: sessionID }),
  57. })
  58. .then((x) => x.json())
  59. .then((x) => x as { url: string; secret: string })
  60. }
  61. export async function remove(id: string) {
  62. return fetch(`${URL}/share_delete`, {
  63. method: "POST",
  64. body: JSON.stringify({ id }),
  65. }).then((x) => x.json())
  66. }
  67. }