share.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { App } from "../app";
  2. import { Bus } from "../bus";
  3. import { Session } from "../session/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. const state = App.state("share", async () => {
  11. Bus.subscribe(Storage.Event.Write, async (payload) => {
  12. const [root, ...splits] = payload.properties.key.split("/");
  13. if (root !== "session") return;
  14. const [, sessionID] = splits;
  15. const session = await Session.get(sessionID);
  16. if (!session.shareID) return;
  17. const key = payload.properties.key;
  18. pending.set(key, payload.properties.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. shareID: session.shareID,
  29. key: key,
  30. content: JSON.stringify(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. });
  44. export async function init() {
  45. await state();
  46. }
  47. const URL = process.env["OPENCODE_API"] ?? "https://api.dev.opencode.ai";
  48. export async function create(sessionID: string) {
  49. return fetch(`${URL}/share_create`, {
  50. method: "POST",
  51. body: JSON.stringify({ sessionID: sessionID }),
  52. })
  53. .then((x) => x.json())
  54. .then((x) => x.shareID);
  55. }
  56. }