200 lines · 5.3 KB · TypeScript
RawDownload
import { Bus } from "@/bus"import { Config } from "@/config/config"import { ulid } from "ulid"import { Provider } from "@/provider/provider"import { Session } from "@/session"import { MessageV2 } from "@/session/message-v2"import { Storage } from "@/storage/storage"import { Log } from "@/util/log"import type * as SDK from "@synsci/sdk/v2" export namespace ShareNext {  const log = Log.create({ service: "share-next" })   async function url() {    return Config.get().then((x) => x.enterprise?.url ?? "https://syntheticsciences.ai")  }   const disabled = true   export async function init() {    if (disabled) return    Bus.subscribe(Session.Event.Updated, async (evt) => {      await sync(evt.properties.info.id, [        {          type: "session",          data: evt.properties.info,        },      ])    })    Bus.subscribe(MessageV2.Event.Updated, async (evt) => {      await sync(evt.properties.info.sessionID, [        {          type: "message",          data: evt.properties.info,        },      ])      if (evt.properties.info.role === "user") {        await sync(evt.properties.info.sessionID, [          {            type: "model",            data: [              await Provider.getModel(evt.properties.info.model.providerID, evt.properties.info.model.modelID).then(                (m) => m,              ),            ],          },        ])      }    })    Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {      await sync(evt.properties.part.sessionID, [        {          type: "part",          data: evt.properties.part,        },      ])    })    Bus.subscribe(Session.Event.Diff, async (evt) => {      await sync(evt.properties.sessionID, [        {          type: "session_diff",          data: evt.properties.diff,        },      ])    })  }   export async function create(sessionID: string) {    if (disabled) return { id: "", url: "", secret: "" }    log.info("creating share", { sessionID })    const result = await fetch(`${await url()}/api/share`, {      method: "POST",      headers: {        "Content-Type": "application/json",      },      body: JSON.stringify({ sessionID: sessionID }),    })      .then((x) => x.json())      .then((x) => x as { id: string; url: string; secret: string })    await Storage.write(["session_share", sessionID], result)    fullSync(sessionID)    return result  }   function get(sessionID: string) {    return Storage.read<{      id: string      secret: string      url: string    }>(["session_share", sessionID])  }   type Data =    | {        type: "session"        data: SDK.Session      }    | {        type: "message"        data: SDK.Message      }    | {        type: "part"        data: SDK.Part      }    | {        type: "session_diff"        data: SDK.FileDiff[]      }    | {        type: "model"        data: SDK.Model[]      }   const queue = new Map<string, { timeout: NodeJS.Timeout; data: Map<string, Data> }>()  async function sync(sessionID: string, data: Data[]) {    if (disabled) return    const existing = queue.get(sessionID)    if (existing) {      for (const item of data) {        existing.data.set("id" in item ? (item.id as string) : ulid(), item)      }      return    }     const dataMap = new Map<string, Data>()    for (const item of data) {      dataMap.set("id" in item ? (item.id as string) : ulid(), item)    }     const timeout = setTimeout(async () => {      const queued = queue.get(sessionID)      if (!queued) return      queue.delete(sessionID)      const share = await get(sessionID).catch(() => undefined)      if (!share) return       await fetch(`${await url()}/api/share/${share.id}/sync`, {        method: "POST",        headers: {          "Content-Type": "application/json",        },        body: JSON.stringify({          secret: share.secret,          data: Array.from(queued.data.values()),        }),      })    }, 1000)    queue.set(sessionID, { timeout, data: dataMap })  }   export async function remove(sessionID: string) {    if (disabled) return    log.info("removing share", { sessionID })    const share = await get(sessionID)    if (!share) return    await fetch(`${await url()}/api/share/${share.id}`, {      method: "DELETE",      headers: {        "Content-Type": "application/json",      },      body: JSON.stringify({        secret: share.secret,      }),    })    await Storage.remove(["session_share", sessionID])  }   async function fullSync(sessionID: string) {    log.info("full sync", { sessionID })    const session = await Session.get(sessionID)    const diffs = await Session.diff(sessionID)    const messages = await Array.fromAsync(MessageV2.stream(sessionID))    const models = await Promise.all(      messages        .filter((m) => m.info.role === "user")        .map((m) => (m.info as SDK.UserMessage).model)        .map((m) => Provider.getModel(m.providerID, m.modelID).then((m) => m)),    )    await sync(sessionID, [      {        type: "session",        data: session,      },      ...messages.map((x) => ({        type: "message" as const,        data: x.info,      })),      ...messages.flatMap((x) => x.parts.map((y) => ({ type: "part" as const, data: y }))),      {        type: "session_diff",        data: diffs,      },      {        type: "model",        data: models,      },    ])  }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t