share.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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() ? "https://api.dev.opencode.ai" : "https://api.opencode.ai")
  51. export async function create(sessionID: string) {
  52. return fetch(`${URL}/share_create`, {
  53. method: "POST",
  54. body: JSON.stringify({ sessionID: sessionID }),
  55. })
  56. .then((x) => x.json())
  57. .then((x) => x as { url: string; secret: string })
  58. }
  59. export async function remove(sessionID: string, secret: string) {
  60. return fetch(`${URL}/share_delete`, {
  61. method: "POST",
  62. body: JSON.stringify({ sessionID, secret }),
  63. }).then((x) => x.json())
  64. }
  65. }