{"version":3,"sources":["../../src/durable/index.ts","../../src/durable/cloudflare.ts","../../src/durable/redis.ts","../../src/durable/types.ts"],"sourcesContent":["export {\n  type CloudflareBackendOptions,\n  type CloudflareEdgeObserver,\n  cloudflare,\n  type WebhookConfig,\n} from \"./cloudflare\";\nexport { type RedisLike, redis } from \"./redis\";\nexport type {\n  DurabilityBackend,\n  DurableBackend,\n  EdgeObserveParams,\n  EdgeObserver,\n  SessionCheckpoint,\n} from \"./types\";\nexport { isEdgeObserver } from \"./types\";\n","import type { EdgeObserveParams, EdgeObserver } from \"./types\";\n\nexport interface WebhookConfig {\n  url: string;\n  secret: string;\n}\n\nexport interface CloudflareBackendOptions {\n  url: string;\n  apiKey?: string;\n  webhook: WebhookConfig;\n}\n\nexport interface CloudflareEdgeObserver extends EdgeObserver {\n  readonly webhook: WebhookConfig;\n}\n\nexport function cloudflare(\n  options: CloudflareBackendOptions,\n): CloudflareEdgeObserver {\n  const base = options.url.replace(/\\/+$/, \"\");\n  const headers: Record<string, string> = {\n    \"Content-Type\": \"application/json\",\n    ...(options.apiKey ? { Authorization: `Bearer ${options.apiKey}` } : {}),\n  };\n\n  return {\n    webhook: options.webhook,\n\n    async observe(params: EdgeObserveParams) {\n      const res = await fetch(`${base}/observe`, {\n        method: \"POST\",\n        headers,\n        body: JSON.stringify(params),\n      });\n      if (!res.ok) {\n        throw new Error(`cloudflare observe failed: ${res.status}`);\n      }\n    },\n\n    async stop(sessionId: string) {\n      const res = await fetch(\n        `${base}/observe/${encodeURIComponent(sessionId)}`,\n        { method: \"DELETE\", headers },\n      );\n      if (!res.ok && res.status !== 404) {\n        throw new Error(`cloudflare stop failed: ${res.status}`);\n      }\n    },\n  };\n}\n","import type { DurabilityBackend, SessionCheckpoint } from \"./types\";\n\n/** Minimal subset of `redis` / `ioredis` — pass your own client instance. */\nexport interface RedisLike {\n  hSet(\n    key: string,\n    field: string,\n    value: string,\n  ): Promise<number | string | unknown>;\n  hDel(key: string, ...fields: string[]): Promise<number | string | unknown>;\n  hGetAll(key: string): Promise<Record<string, string>>;\n}\n\nconst DEFAULT_KEY = \"thalamus:sessions\";\n\nexport function redis(\n  client: RedisLike,\n  options?: { key?: string },\n): DurabilityBackend {\n  const key = options?.key ?? DEFAULT_KEY;\n\n  return {\n    async save(checkpoint) {\n      await client.hSet(key, checkpoint.sessionId, JSON.stringify(checkpoint));\n    },\n    async remove(sessionId) {\n      await client.hDel(key, sessionId);\n    },\n    async getActive() {\n      const all = await client.hGetAll(key);\n      return Object.values(all).map((v) => JSON.parse(v) as SessionCheckpoint);\n    },\n  };\n}\n","export interface SessionCheckpoint {\n  sessionId: string;\n  provider: string;\n  lastEventId: string;\n  createdAt: number;\n  runId: string;\n  metadata?: Record<string, string>;\n}\n\n/** Checkpoint-based durability — stores event cursors in an external store. */\nexport interface DurabilityBackend {\n  save(checkpoint: SessionCheckpoint): Promise<void>;\n  remove(sessionId: string): Promise<void>;\n  getActive(): Promise<SessionCheckpoint[]>;\n}\n\n/* ------------------------------------------------------------------ */\n/*  Edge observer — holds SSE connections at the edge on behalf of     */\n/*  the application (e.g. Cloudflare Durable Objects).                 */\n/* ------------------------------------------------------------------ */\n\nexport interface EdgeObserveParams {\n  sessionId: string;\n  /** Unique identifier for this `send()` invocation. Forwarded in every webhook event. */\n  runId: string;\n  streamUrl: string;\n  headers: Record<string, string>;\n  provider: string;\n  webhook: {\n    url: string;\n    secret: string;\n    metadata?: Record<string, string>;\n  };\n}\n\n/** Edge-proxy durability — SSE lives outside the consumer process, events delivered via webhook. */\nexport interface EdgeObserver {\n  observe(params: EdgeObserveParams): Promise<void>;\n  stop(sessionId: string): Promise<void>;\n}\n\n/* ------------------------------------------------------------------ */\n/*  Unified type                                                       */\n/* ------------------------------------------------------------------ */\n\nexport type DurableBackend = DurabilityBackend | EdgeObserver;\n\nexport function isEdgeObserver(\n  backend: DurableBackend,\n): backend is EdgeObserver {\n  return \"observe\" in backend && \"stop\" in backend && !(\"save\" in backend);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACiBO,SAAS,WACd,SACwB;AACxB,QAAM,OAAO,QAAQ,IAAI,QAAQ,QAAQ,EAAE;AAC3C,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,GAAI,QAAQ,SAAS,EAAE,eAAe,UAAU,QAAQ,MAAM,GAAG,IAAI,CAAC;AAAA,EACxE;AAEA,SAAO;AAAA,IACL,SAAS,QAAQ;AAAA,IAEjB,MAAM,QAAQ,QAA2B;AACvC,YAAM,MAAM,MAAM,MAAM,GAAG,IAAI,YAAY;AAAA,QACzC,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,IAAI,MAAM,8BAA8B,IAAI,MAAM,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,IAEA,MAAM,KAAK,WAAmB;AAC5B,YAAM,MAAM,MAAM;AAAA,QAChB,GAAG,IAAI,YAAY,mBAAmB,SAAS,CAAC;AAAA,QAChD,EAAE,QAAQ,UAAU,QAAQ;AAAA,MAC9B;AACA,UAAI,CAAC,IAAI,MAAM,IAAI,WAAW,KAAK;AACjC,cAAM,IAAI,MAAM,2BAA2B,IAAI,MAAM,EAAE;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AACF;;;ACrCA,IAAM,cAAc;AAEb,SAAS,MACd,QACA,SACmB;AACnB,QAAM,MAAM,SAAS,OAAO;AAE5B,SAAO;AAAA,IACL,MAAM,KAAK,YAAY;AACrB,YAAM,OAAO,KAAK,KAAK,WAAW,WAAW,KAAK,UAAU,UAAU,CAAC;AAAA,IACzE;AAAA,IACA,MAAM,OAAO,WAAW;AACtB,YAAM,OAAO,KAAK,KAAK,SAAS;AAAA,IAClC;AAAA,IACA,MAAM,YAAY;AAChB,YAAM,MAAM,MAAM,OAAO,QAAQ,GAAG;AACpC,aAAO,OAAO,OAAO,GAAG,EAAE,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAsB;AAAA,IACzE;AAAA,EACF;AACF;;;ACcO,SAAS,eACd,SACyB;AACzB,SAAO,aAAa,WAAW,UAAU,WAAW,EAAE,UAAU;AAClE;","names":[]}