@starcite/sdk 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -182
- package/dist/index.cjs +1642 -615
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +594 -203
- package/dist/index.d.ts +594 -203
- package/dist/index.js +1620 -611
- package/dist/index.js.map +1 -1
- package/package.json +15 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/errors.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n StarciteApiError,\n StarciteConnectionError,\n StarciteError,\n} from \"./errors\";\nimport type {\n AppendEventRequest,\n AppendEventResponse,\n CreateSessionInput,\n SessionAppendInput,\n SessionCreatorPrincipal,\n SessionEvent,\n SessionListOptions,\n SessionListPage,\n SessionRecord,\n SessionTailOptions,\n StarciteClientOptions,\n StarciteErrorPayload,\n StarciteWebSocket,\n StarciteWebSocketConnectOptions,\n TailEvent,\n} from \"./types\";\nimport {\n AppendEventRequestSchema,\n AppendEventResponseSchema,\n CreateSessionInputSchema,\n SessionAppendInputSchema,\n SessionCreatorPrincipalSchema,\n SessionListPageSchema,\n SessionRecordSchema,\n StarciteErrorPayloadSchema,\n TailEventSchema,\n} from \"./types\";\n\nconst DEFAULT_BASE_URL =\n typeof process !== \"undefined\" && process.env.STARCITE_BASE_URL\n ? process.env.STARCITE_BASE_URL\n : \"http://localhost:4000\";\nconst TRAILING_SLASHES_REGEX = /\\/+$/;\nconst BEARER_PREFIX_REGEX = /^bearer\\s+/i;\nconst DEFAULT_TAIL_RECONNECT_DELAY_MS = 3000;\nconst NORMAL_WEBSOCKET_CLOSE_CODE = 1000;\nconst SERVICE_TOKEN_SUB_ORG_PREFIX = \"org:\";\nconst SERVICE_TOKEN_SUB_AGENT_PREFIX = \"agent:\";\nconst SERVICE_TOKEN_SUB_USER_PREFIX = \"user:\";\n\nconst TailFrameSchema = z\n .string()\n .transform((frame, context): unknown => {\n try {\n return JSON.parse(frame) as unknown;\n } catch {\n context.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Tail frame was not valid JSON\",\n });\n return z.NEVER;\n }\n })\n .pipe(TailEventSchema);\n\nclass AsyncQueue<T> {\n private readonly items: Array<\n | { type: \"value\"; value: T }\n | { type: \"done\" }\n | { type: \"error\"; error: Error }\n > = [];\n private readonly waiters: Array<\n (\n item:\n | { type: \"value\"; value: T }\n | { type: \"done\" }\n | { type: \"error\"; error: Error }\n ) => void\n > = [];\n private settled = false;\n\n push(value: T): void {\n if (this.settled) {\n return;\n }\n\n this.enqueue({ type: \"value\", value });\n }\n\n close(): void {\n if (this.settled) {\n return;\n }\n\n this.settled = true;\n this.enqueue({ type: \"done\" });\n }\n\n fail(error: unknown): void {\n if (this.settled) {\n return;\n }\n\n this.settled = true;\n this.enqueue({ type: \"error\", error: toError(error) });\n }\n\n async next(): Promise<IteratorResult<T>> {\n const item =\n this.items.shift() ??\n (await new Promise<(typeof this.items)[number]>((resolve) => {\n this.waiters.push(resolve);\n }));\n\n if (item.type === \"value\") {\n return { value: item.value, done: false };\n }\n\n if (item.type === \"done\") {\n return { value: undefined, done: true };\n }\n\n throw item.error;\n }\n\n private enqueue(item: (typeof this.items)[number]): void {\n const waiter = this.waiters.shift();\n\n if (waiter) {\n waiter(item);\n return;\n }\n\n this.items.push(item);\n }\n}\n\n/**\n * Normalizes a Starcite base URL to the `/v1` API root used by this SDK.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim().replace(TRAILING_SLASHES_REGEX, \"\");\n return trimmed.endsWith(\"/v1\") ? trimmed : `${trimmed}/v1`;\n}\n\nfunction toWebSocketBaseUrl(apiBaseUrl: string): string {\n if (apiBaseUrl.startsWith(\"https://\")) {\n return `wss://${apiBaseUrl.slice(\"https://\".length)}`;\n }\n\n if (apiBaseUrl.startsWith(\"http://\")) {\n return `ws://${apiBaseUrl.slice(\"http://\".length)}`;\n }\n\n throw new StarciteError(\n `Invalid Starcite base URL '${apiBaseUrl}'. Use http:// or https://.`\n );\n}\n\nfunction defaultWebSocketFactory(\n url: string,\n options: StarciteWebSocketConnectOptions = {}\n): StarciteWebSocket {\n if (typeof WebSocket === \"undefined\") {\n throw new StarciteError(\n \"WebSocket is not available in this runtime. Provide websocketFactory in StarciteClientOptions.\"\n );\n }\n\n const headers = new Headers(options.headers);\n\n if (!hasAnyHeaders(headers)) {\n return new WebSocket(url) as unknown as StarciteWebSocket;\n }\n\n const headerObject = Object.fromEntries(headers.entries());\n\n try {\n return new (\n WebSocket as unknown as {\n new (\n websocketUrl: string,\n options: { headers: Record<string, string> }\n ): StarciteWebSocket;\n }\n )(url, { headers: headerObject });\n } catch {\n throw new StarciteError(\n \"This runtime cannot set WebSocket upgrade headers with the default factory. Provide websocketFactory in StarciteClientOptions.\"\n );\n }\n}\n\nfunction defaultFetch(\n input: RequestInfo | URL,\n init?: RequestInit\n): Promise<Response> {\n if (typeof fetch === \"undefined\") {\n throw new StarciteError(\n \"fetch is not available in this runtime. Provide fetch in StarciteClientOptions.\"\n );\n }\n\n return fetch(input, init);\n}\n\nfunction toError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(typeof error === \"string\" ? error : \"Unknown error\");\n}\n\nfunction hasAnyHeaders(headers: Headers): boolean {\n for (const _ of headers.keys()) {\n return true;\n }\n\n return false;\n}\n\nfunction formatAuthorizationHeader(apiKey: string): string {\n const normalized = apiKey.trim();\n\n if (normalized.length === 0) {\n throw new StarciteError(\"apiKey cannot be empty\");\n }\n\n if (BEARER_PREFIX_REGEX.test(normalized)) {\n return normalized;\n }\n\n return `Bearer ${normalized}`;\n}\n\nfunction firstNonEmptyString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction parseJwtSegment(segment: string): string | undefined {\n const base64 = segment\n .replace(/-/g, \"+\")\n .replace(/_/g, \"/\")\n .padEnd(segment.length + ((4 - (segment.length % 4)) % 4), \"=\");\n\n try {\n if (typeof atob === \"function\") {\n return atob(base64);\n }\n\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(base64, \"base64\").toString(\"utf8\");\n }\n } catch {\n return undefined;\n }\n\n return undefined;\n}\n\nfunction parseJwtClaims(apiKey: string): Record<string, unknown> | undefined {\n const token = apiKey.replace(BEARER_PREFIX_REGEX, \"\").trim();\n const parts = token.split(\".\");\n\n if (parts.length !== 3) {\n return undefined;\n }\n\n const [, payloadSegment] = parts;\n\n if (payloadSegment === undefined) {\n return undefined;\n }\n\n const payload = parseJwtSegment(payloadSegment);\n\n if (payload === undefined) {\n return undefined;\n }\n\n try {\n const decoded = JSON.parse(payload) as unknown;\n return decoded !== null && typeof decoded === \"object\"\n ? (decoded as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction parseClaimStrings(\n source: Record<string, unknown>,\n keys: string[]\n): string | undefined {\n for (const key of keys) {\n const value = firstNonEmptyString(source[key]);\n if (value) {\n return value;\n }\n }\n\n return undefined;\n}\n\nfunction parseActorIdentityFromSubject(\n subject: string\n): { id: string; type: \"agent\" | \"user\" } | undefined {\n if (subject.startsWith(SERVICE_TOKEN_SUB_AGENT_PREFIX)) {\n return { id: subject, type: \"agent\" };\n }\n\n if (subject.startsWith(SERVICE_TOKEN_SUB_USER_PREFIX)) {\n return { id: subject, type: \"user\" };\n }\n\n return undefined;\n}\n\nfunction parseTenantIdFromSubject(subject: string): string {\n const actorIdentity = parseActorIdentityFromSubject(subject);\n if (actorIdentity !== undefined) {\n return \"\";\n }\n\n if (subject.startsWith(SERVICE_TOKEN_SUB_ORG_PREFIX)) {\n return subject.slice(SERVICE_TOKEN_SUB_ORG_PREFIX.length).trim();\n }\n\n return subject;\n}\n\nfunction parseCreatorPrincipalFromClaims(\n claims: Record<string, unknown>\n): SessionCreatorPrincipal | undefined {\n const subject = firstNonEmptyString(claims.sub);\n const explicitPrincipal =\n claims.principal && typeof claims.principal === \"object\"\n ? (claims.principal as Record<string, unknown>)\n : undefined;\n const mergedClaims = explicitPrincipal\n ? { ...claims, ...explicitPrincipal }\n : claims;\n const actorFromSubject = subject\n ? parseActorIdentityFromSubject(subject)\n : undefined;\n const principalTypeFromClaims = parseClaimStrings(mergedClaims, [\n \"principal_type\",\n \"principalType\",\n \"type\",\n ]);\n const tenantId = parseClaimStrings(mergedClaims, [\"tenant_id\", \"tenantId\"]);\n const rawPrincipalId = parseClaimStrings(mergedClaims, [\n \"principal_id\",\n \"principalId\",\n \"id\",\n \"sub\",\n ]);\n const actorFromRawId = rawPrincipalId\n ? parseActorIdentityFromSubject(rawPrincipalId)\n : undefined;\n\n const principal = {\n tenant_id: tenantId ?? (subject ? parseTenantIdFromSubject(subject) : \"\"),\n id: rawPrincipalId ?? actorFromSubject?.id ?? \"\",\n type:\n principalTypeFromClaims === \"agent\" || principalTypeFromClaims === \"user\"\n ? principalTypeFromClaims\n : (actorFromSubject?.type ?? actorFromRawId?.type ?? \"user\"),\n };\n\n if (\n principal.tenant_id.length === 0 ||\n principal.id.length === 0 ||\n principal.type.length === 0\n ) {\n return undefined;\n }\n\n const result = SessionCreatorPrincipalSchema.safeParse(principal);\n\n return result.success ? result.data : undefined;\n}\n\nfunction parseCreatorPrincipalFromClaimsSafe(\n apiKey: string\n): SessionCreatorPrincipal | undefined {\n const claims = parseJwtClaims(apiKey);\n return claims ? parseCreatorPrincipalFromClaims(claims) : undefined;\n}\n\nfunction parseEventFrame(data: unknown): TailEvent {\n const result = TailFrameSchema.safeParse(data);\n\n if (!result.success) {\n const reason =\n result.error.issues[0]?.message ?? \"Tail frame did not match schema\";\n throw new StarciteConnectionError(reason);\n }\n\n return result.data;\n}\n\nfunction getEventData(event: unknown): unknown {\n if (event && typeof event === \"object\" && \"data\" in event) {\n return (event as { data?: unknown }).data;\n }\n\n return undefined;\n}\n\nfunction getCloseCode(event: unknown): number | undefined {\n if (event && typeof event === \"object\" && \"code\" in event) {\n const code = (event as { code?: unknown }).code;\n return typeof code === \"number\" ? code : undefined;\n }\n\n return undefined;\n}\n\nfunction getCloseReason(event: unknown): string | undefined {\n if (event && typeof event === \"object\" && \"reason\" in event) {\n const reason = (event as { reason?: unknown }).reason;\n return typeof reason === \"string\" && reason.length > 0 ? reason : undefined;\n }\n\n return undefined;\n}\n\nfunction describeClose(\n code: number | undefined,\n reason: string | undefined\n): string {\n const codeText = `code ${typeof code === \"number\" ? code : \"unknown\"}`;\n return reason ? `${codeText}, reason '${reason}'` : codeText;\n}\n\nasync function waitForDelay(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) {\n return;\n }\n\n await new Promise<void>((resolve) => {\n let settled = false;\n const timeout = setTimeout(() => {\n if (settled) {\n return;\n }\n\n settled = true;\n if (signal) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n resolve();\n }, ms);\n\n const onAbort = (): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n clearTimeout(timeout);\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n };\n\n if (signal) {\n if (signal.aborted) {\n onAbort();\n return;\n }\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n\nfunction agentFromActor(actor: string): string | undefined {\n if (actor.startsWith(\"agent:\")) {\n return actor.slice(\"agent:\".length);\n }\n\n return undefined;\n}\n\nfunction toSessionEvent(event: TailEvent): SessionEvent {\n const agent = agentFromActor(event.actor);\n const text =\n typeof event.payload.text === \"string\" ? event.payload.text : undefined;\n\n return {\n ...event,\n agent,\n text,\n };\n}\n\n/**\n * Session-scoped helper for append and tail operations.\n */\nexport class StarciteSession {\n /** Session identifier. */\n readonly id: string;\n /** Optional session record captured at creation time. */\n readonly record?: SessionRecord;\n\n private readonly client: StarciteClient;\n\n constructor(client: StarciteClient, id: string, record?: SessionRecord) {\n this.client = client;\n this.id = id;\n this.record = record;\n }\n\n /**\n * Appends a high-level agent event to this session.\n *\n * Automatically prefixes `agent` as `agent:<name>` when needed.\n */\n append(input: SessionAppendInput): Promise<AppendEventResponse> {\n const parsed = SessionAppendInputSchema.parse(input);\n const actor = parsed.agent.startsWith(\"agent:\")\n ? parsed.agent\n : `agent:${parsed.agent}`;\n\n return this.client.appendEvent(this.id, {\n type: parsed.type ?? \"content\",\n payload: parsed.payload ?? { text: parsed.text },\n actor,\n producer_id: parsed.producerId,\n producer_seq: parsed.producerSeq,\n source: parsed.source ?? \"agent\",\n metadata: parsed.metadata,\n refs: parsed.refs,\n idempotency_key: parsed.idempotencyKey,\n expected_seq: parsed.expectedSeq,\n });\n }\n\n /**\n * Appends a raw event payload as-is.\n */\n appendRaw(input: AppendEventRequest): Promise<AppendEventResponse> {\n return this.client.appendEvent(this.id, input);\n }\n\n /**\n * Streams transformed session events with SDK convenience fields (`agent`, `text`).\n */\n tail(options: SessionTailOptions = {}): AsyncIterable<SessionEvent> {\n return this.client.tailEvents(this.id, options);\n }\n\n /**\n * Streams raw tail events returned by the API.\n */\n tailRaw(options: SessionTailOptions = {}): AsyncIterable<TailEvent> {\n return this.client.tailRawEvents(this.id, options);\n }\n}\n\n/**\n * Starcite API client for HTTP and WebSocket session operations.\n */\nexport class StarciteClient {\n /** Normalized API base URL ending with `/v1`. */\n readonly baseUrl: string;\n\n private readonly inferredCreatorPrincipal?: SessionCreatorPrincipal;\n private readonly websocketBaseUrl: string;\n private readonly fetchFn: typeof fetch;\n private readonly headers: Headers;\n private readonly websocketFactory: (\n url: string,\n options?: StarciteWebSocketConnectOptions\n ) => StarciteWebSocket;\n\n /**\n * Creates a new client instance.\n */\n constructor(options: StarciteClientOptions = {}) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL);\n this.websocketBaseUrl = toWebSocketBaseUrl(this.baseUrl);\n this.fetchFn = options.fetch ?? defaultFetch;\n this.headers = new Headers(options.headers);\n\n if (options.apiKey !== undefined) {\n const authorization = formatAuthorizationHeader(options.apiKey);\n this.headers.set(\"authorization\", authorization);\n this.inferredCreatorPrincipal =\n parseCreatorPrincipalFromClaimsSafe(authorization);\n }\n\n this.websocketFactory = options.websocketFactory ?? defaultWebSocketFactory;\n }\n\n /**\n * Returns a session helper bound to an existing session id.\n */\n session(sessionId: string, record?: SessionRecord): StarciteSession {\n return new StarciteSession(this, sessionId, record);\n }\n\n /**\n * Creates a new session and returns a bound `StarciteSession` helper.\n */\n async create(input: CreateSessionInput = {}): Promise<StarciteSession> {\n const record = await this.createSession(input);\n return this.session(record.id, record);\n }\n\n /**\n * Creates a new session and returns the raw session record.\n */\n createSession(input: CreateSessionInput = {}): Promise<SessionRecord> {\n const payload = CreateSessionInputSchema.parse({\n ...input,\n creator_principal:\n input.creator_principal ?? this.inferredCreatorPrincipal,\n });\n\n return this.request(\n \"/sessions\",\n {\n method: \"POST\",\n body: JSON.stringify(payload),\n },\n SessionRecordSchema\n );\n }\n\n /**\n * Lists sessions from the archive-backed catalog.\n */\n listSessions(options: SessionListOptions = {}): Promise<SessionListPage> {\n const query = new URLSearchParams();\n\n if (options.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit <= 0) {\n throw new StarciteError(\n \"listSessions() limit must be a positive integer\"\n );\n }\n\n query.set(\"limit\", `${options.limit}`);\n }\n\n if (options.cursor !== undefined) {\n if (options.cursor.trim().length === 0) {\n throw new StarciteError(\"listSessions() cursor cannot be empty\");\n }\n\n query.set(\"cursor\", options.cursor);\n }\n\n if (options.metadata !== undefined) {\n for (const [key, value] of Object.entries(options.metadata)) {\n if (key.trim().length === 0 || value.trim().length === 0) {\n throw new StarciteError(\n \"listSessions() metadata filters must be non-empty strings\"\n );\n }\n\n query.set(`metadata.${key}`, value);\n }\n }\n\n const suffix = query.size > 0 ? `?${query.toString()}` : \"\";\n\n return this.request(\n `/sessions${suffix}`,\n {\n method: \"GET\",\n },\n SessionListPageSchema\n );\n }\n\n /**\n * Appends a raw event payload to a specific session.\n */\n appendEvent(\n sessionId: string,\n input: AppendEventRequest\n ): Promise<AppendEventResponse> {\n const payload = AppendEventRequestSchema.parse(input);\n\n return this.request(\n `/sessions/${encodeURIComponent(sessionId)}/append`,\n {\n method: \"POST\",\n body: JSON.stringify(payload),\n },\n AppendEventResponseSchema\n );\n }\n\n /**\n * Opens a WebSocket tail stream and yields raw events.\n */\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: single-loop reconnect state machine is intentionally explicit for stream correctness.\n async *tailRawEvents(\n sessionId: string,\n options: SessionTailOptions = {}\n ): AsyncGenerator<TailEvent> {\n const initialCursor = options.cursor ?? 0;\n const reconnectEnabled = options.reconnect ?? true;\n const reconnectDelayMs =\n options.reconnectDelayMs ?? DEFAULT_TAIL_RECONNECT_DELAY_MS;\n\n if (!Number.isInteger(initialCursor) || initialCursor < 0) {\n throw new StarciteError(\"tail() cursor must be a non-negative integer\");\n }\n\n if (!Number.isFinite(reconnectDelayMs) || reconnectDelayMs < 0) {\n throw new StarciteError(\n \"tail() reconnectDelayMs must be a non-negative number\"\n );\n }\n\n let cursor = initialCursor;\n\n while (true) {\n if (options.signal?.aborted) {\n return;\n }\n\n const wsUrl = `${this.websocketBaseUrl}/sessions/${encodeURIComponent(\n sessionId\n )}/tail?cursor=${cursor}`;\n\n const websocketHeaders = new Headers();\n const authorization = this.headers.get(\"authorization\");\n\n if (authorization) {\n websocketHeaders.set(\"authorization\", authorization);\n }\n\n let socket: StarciteWebSocket;\n\n try {\n socket = this.websocketFactory(\n wsUrl,\n hasAnyHeaders(websocketHeaders)\n ? {\n headers: websocketHeaders,\n }\n : undefined\n );\n } catch (error) {\n const rootCause = toError(error).message;\n\n if (!reconnectEnabled || options.signal?.aborted) {\n throw new StarciteConnectionError(\n `Tail connection failed for session '${sessionId}': ${rootCause}`\n );\n }\n\n await waitForDelay(reconnectDelayMs, options.signal);\n continue;\n }\n\n const queue = new AsyncQueue<TailEvent>();\n let sawTransportError = false;\n let closeCode: number | undefined;\n let closeReason: string | undefined;\n let abortRequested = false;\n\n const onMessage = (event: unknown): void => {\n try {\n const parsed = parseEventFrame(getEventData(event));\n cursor = Math.max(cursor, parsed.seq);\n\n if (options.agent && agentFromActor(parsed.actor) !== options.agent) {\n return;\n }\n\n queue.push(parsed);\n } catch (error) {\n queue.fail(error);\n }\n };\n\n const onError = (): void => {\n sawTransportError = true;\n queue.close();\n };\n\n const onClose = (event: unknown): void => {\n closeCode = getCloseCode(event);\n closeReason = getCloseReason(event);\n queue.close();\n };\n\n const onAbort = (): void => {\n abortRequested = true;\n queue.close();\n socket.close(NORMAL_WEBSOCKET_CLOSE_CODE, \"aborted\");\n };\n\n socket.addEventListener(\"message\", onMessage);\n socket.addEventListener(\"error\", onError);\n socket.addEventListener(\"close\", onClose);\n\n if (options.signal) {\n if (options.signal.aborted) {\n onAbort();\n } else {\n options.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n }\n\n let iterationError: Error | null = null;\n\n try {\n while (true) {\n const next = await queue.next();\n\n if (next.done) {\n break;\n }\n\n yield next.value;\n }\n } catch (error) {\n iterationError = toError(error);\n } finally {\n socket.removeEventListener(\"message\", onMessage);\n socket.removeEventListener(\"error\", onError);\n socket.removeEventListener(\"close\", onClose);\n\n if (options.signal) {\n options.signal.removeEventListener(\"abort\", onAbort);\n }\n\n socket.close(NORMAL_WEBSOCKET_CLOSE_CODE, \"finished\");\n }\n\n if (iterationError) {\n throw iterationError;\n }\n\n if (abortRequested || options.signal?.aborted) {\n return;\n }\n\n const gracefullyClosed =\n !sawTransportError && closeCode === NORMAL_WEBSOCKET_CLOSE_CODE;\n\n if (gracefullyClosed) {\n return;\n }\n\n if (!reconnectEnabled) {\n throw new StarciteConnectionError(\n `Tail connection dropped for session '${sessionId}' (${describeClose(\n closeCode,\n closeReason\n )})`\n );\n }\n\n await waitForDelay(reconnectDelayMs, options.signal);\n }\n }\n\n /**\n * Opens a WebSocket tail stream and yields transformed session events.\n */\n async *tailEvents(\n sessionId: string,\n options: SessionTailOptions = {}\n ): AsyncGenerator<SessionEvent> {\n for await (const rawEvent of this.tailRawEvents(sessionId, options)) {\n yield toSessionEvent(rawEvent);\n }\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n schema?: z.ZodType<T>\n ): Promise<T> {\n const headers = new Headers(this.headers);\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n if (init.headers) {\n const perRequestHeaders = new Headers(init.headers);\n for (const [key, value] of perRequestHeaders.entries()) {\n headers.set(key, value);\n }\n }\n\n let response: Response;\n\n try {\n response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...init,\n headers,\n });\n } catch (error) {\n const rootCause = toError(error).message;\n throw new StarciteConnectionError(\n `Failed to connect to Starcite at ${this.baseUrl}: ${rootCause}`\n );\n }\n\n if (!response.ok) {\n const payload = await tryParseJson(response);\n const code =\n typeof payload?.error === \"string\"\n ? payload.error\n : `http_${response.status}`;\n const message =\n typeof payload?.message === \"string\"\n ? payload.message\n : response.statusText;\n\n throw new StarciteApiError(message, response.status, code, payload);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const responseBody = (await response.json()) as unknown;\n\n if (!schema) {\n return responseBody as T;\n }\n\n const parsed = schema.safeParse(responseBody);\n if (!parsed.success) {\n const issue = parsed.error.issues[0]?.message ?? \"invalid response\";\n throw new StarciteConnectionError(\n `Received unexpected response payload from Starcite: ${issue}`\n );\n }\n\n return parsed.data;\n }\n}\n\nasync function tryParseJson(\n response: Response\n): Promise<StarciteErrorPayload | null> {\n try {\n const parsed = (await response.json()) as unknown;\n const result = StarciteErrorPayloadSchema.safeParse(parsed);\n return result.success ? result.data : null;\n } catch {\n return null;\n }\n}\n","import type { StarciteErrorPayload } from \"./types\";\n\n/**\n * Base error type for SDK-level failures.\n */\nexport class StarciteError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StarciteError\";\n }\n}\n\n/**\n * Thrown when the Starcite API responds with a non-2xx status code.\n */\nexport class StarciteApiError extends StarciteError {\n /** HTTP status code returned by the API. */\n readonly status: number;\n /** Stable API error code (or synthesized `http_<status>` fallback). */\n readonly code: string;\n /** Parsed API error payload when available. */\n readonly payload: StarciteErrorPayload | null;\n\n constructor(\n message: string,\n status: number,\n code: string,\n payload: StarciteErrorPayload | null\n ) {\n super(message);\n this.name = \"StarciteApiError\";\n this.status = status;\n this.code = code;\n this.payload = payload;\n }\n}\n\n/**\n * Thrown when the SDK cannot reach Starcite or receives invalid transport payloads.\n */\nexport class StarciteConnectionError extends StarciteError {\n constructor(message: string) {\n super(message);\n this.name = \"StarciteConnectionError\";\n }\n}\n","import { z } from \"zod\";\n\nconst ArbitraryObjectSchema = z.record(z.unknown());\n\nconst CreatorTypeSchema = z.union([z.literal(\"user\"), z.literal(\"agent\")]);\n\nexport const SessionCreatorPrincipalSchema = z.object({\n tenant_id: z.string().min(1),\n id: z.string().min(1),\n type: CreatorTypeSchema,\n});\n\nexport type SessionCreatorPrincipal = z.infer<\n typeof SessionCreatorPrincipalSchema\n>;\n\n/**\n * Request payload for creating a session.\n */\nexport const CreateSessionInputSchema = z.object({\n id: z.string().optional(),\n title: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n creator_principal: SessionCreatorPrincipalSchema.optional(),\n});\n\n/**\n * Inferred TypeScript type for {@link CreateSessionInputSchema}.\n */\nexport type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>;\n\n/**\n * Session record returned by the Starcite API.\n */\nexport const SessionRecordSchema = z.object({\n id: z.string(),\n title: z.string().nullable().optional(),\n metadata: ArbitraryObjectSchema,\n last_seq: z.number().int().nonnegative(),\n created_at: z.string(),\n updated_at: z.string(),\n});\n\n/**\n * Inferred TypeScript type for {@link SessionRecordSchema}.\n */\nexport type SessionRecord = z.infer<typeof SessionRecordSchema>;\n\n/**\n * Session item returned by the list endpoint.\n */\nexport const SessionListItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable().optional(),\n metadata: ArbitraryObjectSchema,\n created_at: z.string(),\n});\n\n/**\n * Inferred TypeScript type for {@link SessionListItemSchema}.\n */\nexport type SessionListItem = z.infer<typeof SessionListItemSchema>;\n\n/**\n * Paginated session list response.\n */\nexport const SessionListPageSchema = z.object({\n sessions: z.array(SessionListItemSchema),\n next_cursor: z.string().nullable(),\n});\n\n/**\n * Inferred TypeScript type for {@link SessionListPageSchema}.\n */\nexport type SessionListPage = z.infer<typeof SessionListPageSchema>;\n\n/**\n * Low-level request payload for appending an event to a session.\n */\nexport const AppendEventRequestSchema = z.object({\n type: z.string().min(1),\n payload: ArbitraryObjectSchema,\n actor: z.string().min(1),\n producer_id: z.string().min(1),\n producer_seq: z.number().int().positive(),\n source: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n refs: ArbitraryObjectSchema.optional(),\n idempotency_key: z.string().optional(),\n expected_seq: z.number().int().nonnegative().optional(),\n});\n\n/**\n * Inferred TypeScript type for {@link AppendEventRequestSchema}.\n */\nexport type AppendEventRequest = z.infer<typeof AppendEventRequestSchema>;\n\n/**\n * API response returned after appending an event.\n */\nexport const AppendEventResponseSchema = z.object({\n seq: z.number().int().nonnegative(),\n last_seq: z.number().int().nonnegative(),\n deduped: z.boolean(),\n});\n\n/**\n * Inferred TypeScript type for {@link AppendEventResponseSchema}.\n */\nexport type AppendEventResponse = z.infer<typeof AppendEventResponseSchema>;\n\n/**\n * Raw event frame shape emitted by the Starcite tail stream.\n */\nexport const TailEventSchema = z.object({\n seq: z.number().int().nonnegative(),\n type: z.string().min(1),\n payload: ArbitraryObjectSchema,\n actor: z.string().min(1),\n producer_id: z.string().min(1),\n producer_seq: z.number().int().positive(),\n source: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n refs: ArbitraryObjectSchema.optional(),\n idempotency_key: z.string().nullable().optional(),\n inserted_at: z.string().optional(),\n});\n\n/**\n * Inferred TypeScript type for {@link TailEventSchema}.\n */\nexport type TailEvent = z.infer<typeof TailEventSchema>;\n\n/**\n * Convenience tail event shape with SDK-derived fields (`agent`, `text`).\n */\nconst SessionEventInternalSchema = TailEventSchema.extend({\n agent: z.string().optional(),\n text: z.string().optional(),\n});\n\n/**\n * Inferred TypeScript type for the SDK-level enriched tail event.\n */\nexport type SessionEvent = z.infer<typeof SessionEventInternalSchema>;\n\n/**\n * High-level `session.append()` input.\n *\n * You must provide producer identity (`producerId`, `producerSeq`) and either\n * `text` or `payload`.\n */\nexport const SessionAppendInputSchema = z\n .object({\n agent: z.string().trim().min(1),\n producerId: z.string().trim().min(1),\n producerSeq: z.number().int().positive(),\n text: z.string().optional(),\n payload: ArbitraryObjectSchema.optional(),\n type: z.string().optional(),\n source: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n refs: ArbitraryObjectSchema.optional(),\n idempotencyKey: z.string().optional(),\n expectedSeq: z.number().int().nonnegative().optional(),\n })\n .refine((value) => !!(value.text || value.payload), {\n message: \"append() requires either 'text' or an object 'payload'\",\n });\n\n/**\n * Inferred TypeScript type for {@link SessionAppendInputSchema}.\n */\nexport type SessionAppendInput = z.infer<typeof SessionAppendInputSchema>;\n\n/**\n * Options for streaming events from a session.\n */\nexport interface SessionTailOptions {\n /**\n * Starting cursor (inclusive) in the event stream.\n */\n cursor?: number;\n /**\n * Optional filter for `agent:<name>` events.\n */\n agent?: string;\n /**\n * Automatically reconnect on transport failures and continue from the last observed sequence.\n *\n * Defaults to `true`.\n */\n reconnect?: boolean;\n /**\n * Delay between reconnect attempts in milliseconds.\n *\n * Defaults to `3000`.\n */\n reconnectDelayMs?: number;\n /**\n * Optional abort signal to close the stream.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for listing sessions.\n */\nexport interface SessionListOptions {\n /**\n * Maximum rows to return. Must be a positive integer.\n */\n limit?: number;\n /**\n * Optional cursor from the previous response.\n */\n cursor?: string;\n /**\n * Optional flat metadata exact-match filters.\n */\n metadata?: Record<string, string>;\n}\n\n/**\n * Minimal WebSocket contract required by the SDK.\n */\nexport interface StarciteWebSocket {\n addEventListener(type: string, listener: (event: unknown) => void): void;\n removeEventListener(type: string, listener: (event: unknown) => void): void;\n close(code?: number, reason?: string): void;\n}\n\n/**\n * Factory used to create the WebSocket connection for `tail`.\n */\nexport interface StarciteWebSocketConnectOptions {\n /**\n * Headers to include with the WebSocket handshake request.\n */\n headers?: HeadersInit;\n}\n\n/**\n * Factory used to create the WebSocket connection for `tail`.\n */\nexport type StarciteWebSocketFactory = (\n url: string,\n options?: StarciteWebSocketConnectOptions\n) => StarciteWebSocket;\n\n/**\n * Client construction options.\n */\nexport interface StarciteClientOptions {\n /**\n * Base API URL. Defaults to `process.env.STARCITE_BASE_URL` or `http://localhost:4000`.\n */\n baseUrl?: string;\n /**\n * Custom fetch implementation for non-standard runtimes.\n */\n fetch?: typeof fetch;\n /**\n * Headers applied to every HTTP request.\n */\n headers?: HeadersInit;\n /**\n * Service key / JWT token. When set, the SDK automatically sends\n * `Authorization: Bearer <token>` for HTTP requests and WebSocket upgrades.\n */\n apiKey?: string;\n /**\n * Custom WebSocket factory for non-browser runtimes.\n */\n websocketFactory?: StarciteWebSocketFactory;\n}\n\n/**\n * Error payload shape returned by non-2xx API responses.\n */\nexport const StarciteErrorPayloadSchema = z\n .object({\n error: z.string().optional(),\n message: z.string().optional(),\n })\n .catchall(z.unknown());\n\n/**\n * Inferred TypeScript type for {@link StarciteErrorPayloadSchema}.\n */\nexport type StarciteErrorPayload = z.infer<typeof StarciteErrorPayloadSchema>;\n","import { StarciteClient } from \"./client\";\nimport type { StarciteClientOptions } from \"./types\";\n\n// biome-ignore lint/performance/noBarrelFile: package entrypoint intentionally re-exports public API.\nexport { normalizeBaseUrl, StarciteClient, StarciteSession } from \"./client\";\nexport {\n StarciteApiError,\n StarciteConnectionError,\n StarciteError,\n} from \"./errors\";\nexport type {\n AppendEventRequest,\n AppendEventResponse,\n CreateSessionInput,\n SessionAppendInput,\n SessionEvent,\n SessionListItem,\n SessionListOptions,\n SessionListPage,\n SessionRecord,\n SessionTailOptions,\n StarciteClientOptions,\n StarciteErrorPayload,\n StarciteWebSocket,\n StarciteWebSocketConnectOptions,\n StarciteWebSocketFactory,\n TailEvent,\n} from \"./types\";\n/**\n * Creates a new {@link StarciteClient} instance.\n */\nexport function createStarciteClient(\n options: StarciteClientOptions = {}\n): StarciteClient {\n return new StarciteClient(options);\n}\n\n/**\n * Default singleton client using environment/default configuration.\n */\nexport const starcite = createStarciteClient();\n"],"mappings":";AAAA,SAAS,KAAAA,UAAS;;;ACKX,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,mBAAN,cAA+B,cAAc;AAAA;AAAA,EAEzC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YACE,SACA,QACA,MACA,SACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAKO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EACzD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;AC7CA,SAAS,SAAS;AAElB,IAAM,wBAAwB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAElD,IAAM,oBAAoB,EAAE,MAAM,CAAC,EAAE,QAAQ,MAAM,GAAG,EAAE,QAAQ,OAAO,CAAC,CAAC;AAElE,IAAM,gCAAgC,EAAE,OAAO;AAAA,EACpD,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC3B,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,MAAM;AACR,CAAC;AASM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,IAAI,EAAE,OAAO,EAAE,SAAS;AAAA,EACxB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAU,sBAAsB,SAAS;AAAA,EACzC,mBAAmB,8BAA8B,SAAS;AAC5D,CAAC;AAUM,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACtC,UAAU;AAAA,EACV,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACvC,YAAY,EAAE,OAAO;AAAA,EACrB,YAAY,EAAE,OAAO;AACvB,CAAC;AAUM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACtC,UAAU;AAAA,EACV,YAAY,EAAE,OAAO;AACvB,CAAC;AAUM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,UAAU,EAAE,MAAM,qBAAqB;AAAA,EACvC,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAUM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,SAAS;AAAA,EACT,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACxC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,UAAU,sBAAsB,SAAS;AAAA,EACzC,MAAM,sBAAsB,SAAS;AAAA,EACrC,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AACxD,CAAC;AAUM,IAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAClC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACvC,SAAS,EAAE,QAAQ;AACrB,CAAC;AAUM,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAClC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,SAAS;AAAA,EACT,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACxC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,UAAU,sBAAsB,SAAS;AAAA,EACzC,MAAM,sBAAsB,SAAS;AAAA,EACrC,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAUD,IAAM,6BAA6B,gBAAgB,OAAO;AAAA,EACxD,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,MAAM,EAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AAaM,IAAM,2BAA2B,EACrC,OAAO;AAAA,EACN,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC;AAAA,EAC9B,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC;AAAA,EACnC,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACvC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,SAAS,sBAAsB,SAAS;AAAA,EACxC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,UAAU,sBAAsB,SAAS;AAAA,EACzC,MAAM,sBAAsB,SAAS;AAAA,EACrC,gBAAgB,EAAE,OAAO,EAAE,SAAS;AAAA,EACpC,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AACvD,CAAC,EACA,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,EAClD,SAAS;AACX,CAAC;AAgHI,IAAM,6BAA6B,EACvC,OAAO;AAAA,EACN,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,SAAS,EAAE,OAAO,EAAE,SAAS;AAC/B,CAAC,EACA,SAAS,EAAE,QAAQ,CAAC;;;AF1PvB,IAAM,mBACJ,OAAO,YAAY,eAAe,QAAQ,IAAI,oBAC1C,QAAQ,IAAI,oBACZ;AACN,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB;AAC5B,IAAM,kCAAkC;AACxC,IAAM,8BAA8B;AACpC,IAAM,+BAA+B;AACrC,IAAM,iCAAiC;AACvC,IAAM,gCAAgC;AAEtC,IAAM,kBAAkBC,GACrB,OAAO,EACP,UAAU,CAAC,OAAO,YAAqB;AACtC,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,YAAQ,SAAS;AAAA,MACf,MAAMA,GAAE,aAAa;AAAA,MACrB,SAAS;AAAA,IACX,CAAC;AACD,WAAOA,GAAE;AAAA,EACX;AACF,CAAC,EACA,KAAK,eAAe;AAEvB,IAAM,aAAN,MAAoB;AAAA,EACD,QAIb,CAAC;AAAA,EACY,UAOb,CAAC;AAAA,EACG,UAAU;AAAA,EAElB,KAAK,OAAgB;AACnB,QAAI,KAAK,SAAS;AAChB;AAAA,IACF;AAEA,SAAK,QAAQ,EAAE,MAAM,SAAS,MAAM,CAAC;AAAA,EACvC;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,SAAS;AAChB;AAAA,IACF;AAEA,SAAK,UAAU;AACf,SAAK,QAAQ,EAAE,MAAM,OAAO,CAAC;AAAA,EAC/B;AAAA,EAEA,KAAK,OAAsB;AACzB,QAAI,KAAK,SAAS;AAChB;AAAA,IACF;AAEA,SAAK,UAAU;AACf,SAAK,QAAQ,EAAE,MAAM,SAAS,OAAO,QAAQ,KAAK,EAAE,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,OAAmC;AACvC,UAAM,OACJ,KAAK,MAAM,MAAM,KAChB,MAAM,IAAI,QAAqC,CAAC,YAAY;AAC3D,WAAK,QAAQ,KAAK,OAAO;AAAA,IAC3B,CAAC;AAEH,QAAI,KAAK,SAAS,SAAS;AACzB,aAAO,EAAE,OAAO,KAAK,OAAO,MAAM,MAAM;AAAA,IAC1C;AAEA,QAAI,KAAK,SAAS,QAAQ;AACxB,aAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAAA,IACxC;AAEA,UAAM,KAAK;AAAA,EACb;AAAA,EAEQ,QAAQ,MAAyC;AACvD,UAAM,SAAS,KAAK,QAAQ,MAAM;AAElC,QAAI,QAAQ;AACV,aAAO,IAAI;AACX;AAAA,IACF;AAEA,SAAK,MAAM,KAAK,IAAI;AAAA,EACtB;AACF;AAKO,SAAS,iBAAiB,SAAyB;AACxD,QAAM,UAAU,QAAQ,KAAK,EAAE,QAAQ,wBAAwB,EAAE;AACjE,SAAO,QAAQ,SAAS,KAAK,IAAI,UAAU,GAAG,OAAO;AACvD;AAEA,SAAS,mBAAmB,YAA4B;AACtD,MAAI,WAAW,WAAW,UAAU,GAAG;AACrC,WAAO,SAAS,WAAW,MAAM,WAAW,MAAM,CAAC;AAAA,EACrD;AAEA,MAAI,WAAW,WAAW,SAAS,GAAG;AACpC,WAAO,QAAQ,WAAW,MAAM,UAAU,MAAM,CAAC;AAAA,EACnD;AAEA,QAAM,IAAI;AAAA,IACR,8BAA8B,UAAU;AAAA,EAC1C;AACF;AAEA,SAAS,wBACP,KACA,UAA2C,CAAC,GACzB;AACnB,MAAI,OAAO,cAAc,aAAa;AACpC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAE3C,MAAI,CAAC,cAAc,OAAO,GAAG;AAC3B,WAAO,IAAI,UAAU,GAAG;AAAA,EAC1B;AAEA,QAAM,eAAe,OAAO,YAAY,QAAQ,QAAQ,CAAC;AAEzD,MAAI;AACF,WAAO,IACL,UAMA,KAAK,EAAE,SAAS,aAAa,CAAC;AAAA,EAClC,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,aACP,OACA,MACmB;AACnB,MAAI,OAAO,UAAU,aAAa;AAChC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,OAAO,IAAI;AAC1B;AAEA,SAAS,QAAQ,OAAuB;AACtC,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,EACT;AAEA,SAAO,IAAI,MAAM,OAAO,UAAU,WAAW,QAAQ,eAAe;AACtE;AAEA,SAAS,cAAc,SAA2B;AAChD,aAAW,KAAK,QAAQ,KAAK,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,0BAA0B,QAAwB;AACzD,QAAM,aAAa,OAAO,KAAK;AAE/B,MAAI,WAAW,WAAW,GAAG;AAC3B,UAAM,IAAI,cAAc,wBAAwB;AAAA,EAClD;AAEA,MAAI,oBAAoB,KAAK,UAAU,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,SAAO,UAAU,UAAU;AAC7B;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,IACtD,MAAM,KAAK,IACX;AACN;AAEA,SAAS,gBAAgB,SAAqC;AAC5D,QAAM,SAAS,QACZ,QAAQ,MAAM,GAAG,EACjB,QAAQ,MAAM,GAAG,EACjB,OAAO,QAAQ,UAAW,IAAK,QAAQ,SAAS,KAAM,GAAI,GAAG;AAEhE,MAAI;AACF,QAAI,OAAO,SAAS,YAAY;AAC9B,aAAO,KAAK,MAAM;AAAA,IACpB;AAEA,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,MAAM;AAAA,IACtD;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,QAAqD;AAC3E,QAAM,QAAQ,OAAO,QAAQ,qBAAqB,EAAE,EAAE,KAAK;AAC3D,QAAM,QAAQ,MAAM,MAAM,GAAG;AAE7B,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,EAAE,cAAc,IAAI;AAE3B,MAAI,mBAAmB,QAAW;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,gBAAgB,cAAc;AAE9C,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,OAAO;AAClC,WAAO,YAAY,QAAQ,OAAO,YAAY,WACzC,UACD;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBACP,QACA,MACoB;AACpB,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,oBAAoB,OAAO,GAAG,CAAC;AAC7C,QAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,8BACP,SACoD;AACpD,MAAI,QAAQ,WAAW,8BAA8B,GAAG;AACtD,WAAO,EAAE,IAAI,SAAS,MAAM,QAAQ;AAAA,EACtC;AAEA,MAAI,QAAQ,WAAW,6BAA6B,GAAG;AACrD,WAAO,EAAE,IAAI,SAAS,MAAM,OAAO;AAAA,EACrC;AAEA,SAAO;AACT;AAEA,SAAS,yBAAyB,SAAyB;AACzD,QAAM,gBAAgB,8BAA8B,OAAO;AAC3D,MAAI,kBAAkB,QAAW;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,WAAW,4BAA4B,GAAG;AACpD,WAAO,QAAQ,MAAM,6BAA6B,MAAM,EAAE,KAAK;AAAA,EACjE;AAEA,SAAO;AACT;AAEA,SAAS,gCACP,QACqC;AACrC,QAAM,UAAU,oBAAoB,OAAO,GAAG;AAC9C,QAAM,oBACJ,OAAO,aAAa,OAAO,OAAO,cAAc,WAC3C,OAAO,YACR;AACN,QAAM,eAAe,oBACjB,EAAE,GAAG,QAAQ,GAAG,kBAAkB,IAClC;AACJ,QAAM,mBAAmB,UACrB,8BAA8B,OAAO,IACrC;AACJ,QAAM,0BAA0B,kBAAkB,cAAc;AAAA,IAC9D;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,WAAW,kBAAkB,cAAc,CAAC,aAAa,UAAU,CAAC;AAC1E,QAAM,iBAAiB,kBAAkB,cAAc;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,iBAAiB,iBACnB,8BAA8B,cAAc,IAC5C;AAEJ,QAAM,YAAY;AAAA,IAChB,WAAW,aAAa,UAAU,yBAAyB,OAAO,IAAI;AAAA,IACtE,IAAI,kBAAkB,kBAAkB,MAAM;AAAA,IAC9C,MACE,4BAA4B,WAAW,4BAA4B,SAC/D,0BACC,kBAAkB,QAAQ,gBAAgB,QAAQ;AAAA,EAC3D;AAEA,MACE,UAAU,UAAU,WAAW,KAC/B,UAAU,GAAG,WAAW,KACxB,UAAU,KAAK,WAAW,GAC1B;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,8BAA8B,UAAU,SAAS;AAEhE,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;AAEA,SAAS,oCACP,QACqC;AACrC,QAAM,SAAS,eAAe,MAAM;AACpC,SAAO,SAAS,gCAAgC,MAAM,IAAI;AAC5D;AAEA,SAAS,gBAAgB,MAA0B;AACjD,QAAM,SAAS,gBAAgB,UAAU,IAAI;AAE7C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,SACJ,OAAO,MAAM,OAAO,CAAC,GAAG,WAAW;AACrC,UAAM,IAAI,wBAAwB,MAAM;AAAA,EAC1C;AAEA,SAAO,OAAO;AAChB;AAEA,SAAS,aAAa,OAAyB;AAC7C,MAAI,SAAS,OAAO,UAAU,YAAY,UAAU,OAAO;AACzD,WAAQ,MAA6B;AAAA,EACvC;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,OAAoC;AACxD,MAAI,SAAS,OAAO,UAAU,YAAY,UAAU,OAAO;AACzD,UAAM,OAAQ,MAA6B;AAC3C,WAAO,OAAO,SAAS,WAAW,OAAO;AAAA,EAC3C;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,OAAoC;AAC1D,MAAI,SAAS,OAAO,UAAU,YAAY,YAAY,OAAO;AAC3D,UAAM,SAAU,MAA+B;AAC/C,WAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS;AAAA,EACpE;AAEA,SAAO;AACT;AAEA,SAAS,cACP,MACA,QACQ;AACR,QAAM,WAAW,QAAQ,OAAO,SAAS,WAAW,OAAO,SAAS;AACpE,SAAO,SAAS,GAAG,QAAQ,aAAa,MAAM,MAAM;AACtD;AAEA,eAAe,aAAa,IAAY,QAAqC;AAC3E,MAAI,MAAM,GAAG;AACX;AAAA,EACF;AAEA,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,QAAI,UAAU;AACd,UAAM,UAAU,WAAW,MAAM;AAC/B,UAAI,SAAS;AACX;AAAA,MACF;AAEA,gBAAU;AACV,UAAI,QAAQ;AACV,eAAO,oBAAoB,SAAS,OAAO;AAAA,MAC7C;AACA,cAAQ;AAAA,IACV,GAAG,EAAE;AAEL,UAAM,UAAU,MAAY;AAC1B,UAAI,SAAS;AACX;AAAA,MACF;AAEA,gBAAU;AACV,mBAAa,OAAO;AACpB,cAAQ,oBAAoB,SAAS,OAAO;AAC5C,cAAQ;AAAA,IACV;AAEA,QAAI,QAAQ;AACV,UAAI,OAAO,SAAS;AAClB,gBAAQ;AACR;AAAA,MACF;AAEA,aAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IAC1D;AAAA,EACF,CAAC;AACH;AAEA,SAAS,eAAe,OAAmC;AACzD,MAAI,MAAM,WAAW,QAAQ,GAAG;AAC9B,WAAO,MAAM,MAAM,SAAS,MAAM;AAAA,EACpC;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,OAAgC;AACtD,QAAM,QAAQ,eAAe,MAAM,KAAK;AACxC,QAAM,OACJ,OAAO,MAAM,QAAQ,SAAS,WAAW,MAAM,QAAQ,OAAO;AAEhE,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;AAKO,IAAM,kBAAN,MAAsB;AAAA;AAAA,EAElB;AAAA;AAAA,EAEA;AAAA,EAEQ;AAAA,EAEjB,YAAY,QAAwB,IAAY,QAAwB;AACtE,SAAK,SAAS;AACd,SAAK,KAAK;AACV,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,OAAyD;AAC9D,UAAM,SAAS,yBAAyB,MAAM,KAAK;AACnD,UAAM,QAAQ,OAAO,MAAM,WAAW,QAAQ,IAC1C,OAAO,QACP,SAAS,OAAO,KAAK;AAEzB,WAAO,KAAK,OAAO,YAAY,KAAK,IAAI;AAAA,MACtC,MAAM,OAAO,QAAQ;AAAA,MACrB,SAAS,OAAO,WAAW,EAAE,MAAM,OAAO,KAAK;AAAA,MAC/C;AAAA,MACA,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,QAAQ,OAAO,UAAU;AAAA,MACzB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,iBAAiB,OAAO;AAAA,MACxB,cAAc,OAAO;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAyD;AACjE,WAAO,KAAK,OAAO,YAAY,KAAK,IAAI,KAAK;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,UAA8B,CAAC,GAAgC;AAClE,WAAO,KAAK,OAAO,WAAW,KAAK,IAAI,OAAO;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,UAA8B,CAAC,GAA6B;AAClE,WAAO,KAAK,OAAO,cAAc,KAAK,IAAI,OAAO;AAAA,EACnD;AACF;AAKO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAEjB;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAQjB,YAAY,UAAiC,CAAC,GAAG;AAC/C,SAAK,UAAU,iBAAiB,QAAQ,WAAW,gBAAgB;AACnE,SAAK,mBAAmB,mBAAmB,KAAK,OAAO;AACvD,SAAK,UAAU,QAAQ,SAAS;AAChC,SAAK,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAE1C,QAAI,QAAQ,WAAW,QAAW;AAChC,YAAM,gBAAgB,0BAA0B,QAAQ,MAAM;AAC9D,WAAK,QAAQ,IAAI,iBAAiB,aAAa;AAC/C,WAAK,2BACH,oCAAoC,aAAa;AAAA,IACrD;AAEA,SAAK,mBAAmB,QAAQ,oBAAoB;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,WAAmB,QAAyC;AAClE,WAAO,IAAI,gBAAgB,MAAM,WAAW,MAAM;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,QAA4B,CAAC,GAA6B;AACrE,UAAM,SAAS,MAAM,KAAK,cAAc,KAAK;AAC7C,WAAO,KAAK,QAAQ,OAAO,IAAI,MAAM;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,QAA4B,CAAC,GAA2B;AACpE,UAAM,UAAU,yBAAyB,MAAM;AAAA,MAC7C,GAAG;AAAA,MACH,mBACE,MAAM,qBAAqB,KAAK;AAAA,IACpC,CAAC;AAED,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAA8B,CAAC,GAA6B;AACvE,UAAM,QAAQ,IAAI,gBAAgB;AAElC,QAAI,QAAQ,UAAU,QAAW;AAC/B,UAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,KAAK,QAAQ,SAAS,GAAG;AAC1D,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,IAAI,SAAS,GAAG,QAAQ,KAAK,EAAE;AAAA,IACvC;AAEA,QAAI,QAAQ,WAAW,QAAW;AAChC,UAAI,QAAQ,OAAO,KAAK,EAAE,WAAW,GAAG;AACtC,cAAM,IAAI,cAAc,uCAAuC;AAAA,MACjE;AAEA,YAAM,IAAI,UAAU,QAAQ,MAAM;AAAA,IACpC;AAEA,QAAI,QAAQ,aAAa,QAAW;AAClC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG;AAC3D,YAAI,IAAI,KAAK,EAAE,WAAW,KAAK,MAAM,KAAK,EAAE,WAAW,GAAG;AACxD,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,cAAM,IAAI,YAAY,GAAG,IAAI,KAAK;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,OAAO,IAAI,IAAI,MAAM,SAAS,CAAC,KAAK;AAEzD,WAAO,KAAK;AAAA,MACV,YAAY,MAAM;AAAA,MAClB;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YACE,WACA,OAC8B;AAC9B,UAAM,UAAU,yBAAyB,MAAM,KAAK;AAEpD,WAAO,KAAK;AAAA,MACV,aAAa,mBAAmB,SAAS,CAAC;AAAA,MAC1C;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,cACL,WACA,UAA8B,CAAC,GACJ;AAC3B,UAAM,gBAAgB,QAAQ,UAAU;AACxC,UAAM,mBAAmB,QAAQ,aAAa;AAC9C,UAAM,mBACJ,QAAQ,oBAAoB;AAE9B,QAAI,CAAC,OAAO,UAAU,aAAa,KAAK,gBAAgB,GAAG;AACzD,YAAM,IAAI,cAAc,8CAA8C;AAAA,IACxE;AAEA,QAAI,CAAC,OAAO,SAAS,gBAAgB,KAAK,mBAAmB,GAAG;AAC9D,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS;AAEb,WAAO,MAAM;AACX,UAAI,QAAQ,QAAQ,SAAS;AAC3B;AAAA,MACF;AAEA,YAAM,QAAQ,GAAG,KAAK,gBAAgB,aAAa;AAAA,QACjD;AAAA,MACF,CAAC,gBAAgB,MAAM;AAEvB,YAAM,mBAAmB,IAAI,QAAQ;AACrC,YAAM,gBAAgB,KAAK,QAAQ,IAAI,eAAe;AAEtD,UAAI,eAAe;AACjB,yBAAiB,IAAI,iBAAiB,aAAa;AAAA,MACrD;AAEA,UAAI;AAEJ,UAAI;AACF,iBAAS,KAAK;AAAA,UACZ;AAAA,UACA,cAAc,gBAAgB,IAC1B;AAAA,YACE,SAAS;AAAA,UACX,IACA;AAAA,QACN;AAAA,MACF,SAAS,OAAO;AACd,cAAM,YAAY,QAAQ,KAAK,EAAE;AAEjC,YAAI,CAAC,oBAAoB,QAAQ,QAAQ,SAAS;AAChD,gBAAM,IAAI;AAAA,YACR,uCAAuC,SAAS,MAAM,SAAS;AAAA,UACjE;AAAA,QACF;AAEA,cAAM,aAAa,kBAAkB,QAAQ,MAAM;AACnD;AAAA,MACF;AAEA,YAAM,QAAQ,IAAI,WAAsB;AACxC,UAAI,oBAAoB;AACxB,UAAI;AACJ,UAAI;AACJ,UAAI,iBAAiB;AAErB,YAAM,YAAY,CAAC,UAAyB;AAC1C,YAAI;AACF,gBAAM,SAAS,gBAAgB,aAAa,KAAK,CAAC;AAClD,mBAAS,KAAK,IAAI,QAAQ,OAAO,GAAG;AAEpC,cAAI,QAAQ,SAAS,eAAe,OAAO,KAAK,MAAM,QAAQ,OAAO;AACnE;AAAA,UACF;AAEA,gBAAM,KAAK,MAAM;AAAA,QACnB,SAAS,OAAO;AACd,gBAAM,KAAK,KAAK;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,UAAU,MAAY;AAC1B,4BAAoB;AACpB,cAAM,MAAM;AAAA,MACd;AAEA,YAAM,UAAU,CAAC,UAAyB;AACxC,oBAAY,aAAa,KAAK;AAC9B,sBAAc,eAAe,KAAK;AAClC,cAAM,MAAM;AAAA,MACd;AAEA,YAAM,UAAU,MAAY;AAC1B,yBAAiB;AACjB,cAAM,MAAM;AACZ,eAAO,MAAM,6BAA6B,SAAS;AAAA,MACrD;AAEA,aAAO,iBAAiB,WAAW,SAAS;AAC5C,aAAO,iBAAiB,SAAS,OAAO;AACxC,aAAO,iBAAiB,SAAS,OAAO;AAExC,UAAI,QAAQ,QAAQ;AAClB,YAAI,QAAQ,OAAO,SAAS;AAC1B,kBAAQ;AAAA,QACV,OAAO;AACL,kBAAQ,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,QAClE;AAAA,MACF;AAEA,UAAI,iBAA+B;AAEnC,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,OAAO,MAAM,MAAM,KAAK;AAE9B,cAAI,KAAK,MAAM;AACb;AAAA,UACF;AAEA,gBAAM,KAAK;AAAA,QACb;AAAA,MACF,SAAS,OAAO;AACd,yBAAiB,QAAQ,KAAK;AAAA,MAChC,UAAE;AACA,eAAO,oBAAoB,WAAW,SAAS;AAC/C,eAAO,oBAAoB,SAAS,OAAO;AAC3C,eAAO,oBAAoB,SAAS,OAAO;AAE3C,YAAI,QAAQ,QAAQ;AAClB,kBAAQ,OAAO,oBAAoB,SAAS,OAAO;AAAA,QACrD;AAEA,eAAO,MAAM,6BAA6B,UAAU;AAAA,MACtD;AAEA,UAAI,gBAAgB;AAClB,cAAM;AAAA,MACR;AAEA,UAAI,kBAAkB,QAAQ,QAAQ,SAAS;AAC7C;AAAA,MACF;AAEA,YAAM,mBACJ,CAAC,qBAAqB,cAAc;AAEtC,UAAI,kBAAkB;AACpB;AAAA,MACF;AAEA,UAAI,CAAC,kBAAkB;AACrB,cAAM,IAAI;AAAA,UACR,wCAAwC,SAAS,MAAM;AAAA,YACrD;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,aAAa,kBAAkB,QAAQ,MAAM;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WACL,WACA,UAA8B,CAAC,GACD;AAC9B,qBAAiB,YAAY,KAAK,cAAc,WAAW,OAAO,GAAG;AACnE,YAAM,eAAe,QAAQ;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAc,QACZ,MACA,MACA,QACY;AACZ,UAAM,UAAU,IAAI,QAAQ,KAAK,OAAO;AAExC,QAAI,CAAC,QAAQ,IAAI,cAAc,GAAG;AAChC,cAAQ,IAAI,gBAAgB,kBAAkB;AAAA,IAChD;AAEA,QAAI,KAAK,SAAS;AAChB,YAAM,oBAAoB,IAAI,QAAQ,KAAK,OAAO;AAClD,iBAAW,CAAC,KAAK,KAAK,KAAK,kBAAkB,QAAQ,GAAG;AACtD,gBAAQ,IAAI,KAAK,KAAK;AAAA,MACxB;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AACF,iBAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QACtD,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,YAAY,QAAQ,KAAK,EAAE;AACjC,YAAM,IAAI;AAAA,QACR,oCAAoC,KAAK,OAAO,KAAK,SAAS;AAAA,MAChE;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,UAAU,MAAM,aAAa,QAAQ;AAC3C,YAAM,OACJ,OAAO,SAAS,UAAU,WACtB,QAAQ,QACR,QAAQ,SAAS,MAAM;AAC7B,YAAM,UACJ,OAAO,SAAS,YAAY,WACxB,QAAQ,UACR,SAAS;AAEf,YAAM,IAAI,iBAAiB,SAAS,SAAS,QAAQ,MAAM,OAAO;AAAA,IACpE;AAEA,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,eAAgB,MAAM,SAAS,KAAK;AAE1C,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,OAAO,UAAU,YAAY;AAC5C,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,QAAQ,OAAO,MAAM,OAAO,CAAC,GAAG,WAAW;AACjD,YAAM,IAAI;AAAA,QACR,uDAAuD,KAAK;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO,OAAO;AAAA,EAChB;AACF;AAEA,eAAe,aACb,UACsC;AACtC,MAAI;AACF,UAAM,SAAU,MAAM,SAAS,KAAK;AACpC,UAAM,SAAS,2BAA2B,UAAU,MAAM;AAC1D,WAAO,OAAO,UAAU,OAAO,OAAO;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AG75BO,SAAS,qBACd,UAAiC,CAAC,GAClB;AAChB,SAAO,IAAI,eAAe,OAAO;AACnC;AAKO,IAAM,WAAW,qBAAqB;","names":["z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth.ts","../src/identity.ts","../src/errors.ts","../src/session.ts","../src/session-log.ts","../src/tail/frame.ts","../src/types.ts","../src/tail/managed-websocket.ts","../src/tail/stream.ts","../src/transport.ts","../src/session-store.ts","../src/client.ts","../src/cursor-store.ts"],"sourcesContent":["import { decodeJwt } from \"jose\";\nimport { z } from \"zod\";\nimport { PrincipalTypeSchema, StarciteIdentity } from \"./identity\";\n\nconst ApiKeyClaimsSchema = z.object({\n iss: z.string().min(1).optional(),\n sub: z.string().min(1).optional(),\n tenant_id: z.string().min(1).optional(),\n principal_id: z.string().min(1).optional(),\n principal_type: PrincipalTypeSchema.optional(),\n});\n\nconst SessionTokenClaimsSchema = z.object({\n session_id: z.string().min(1).optional(),\n sub: z.string().min(1).optional(),\n tenant_id: z.string().min(1),\n principal_id: z.string().min(1).optional(),\n principal_type: PrincipalTypeSchema.optional(),\n});\n\n/**\n * Extracts the issuer authority (protocol + host) from an API key JWT.\n */\nexport function inferIssuerAuthorityFromApiKey(\n apiKey: string\n): string | undefined {\n const claims = ApiKeyClaimsSchema.parse(decodeJwt(apiKey));\n if (!claims.iss) {\n return undefined;\n }\n const url = new URL(claims.iss);\n return url.origin;\n}\n\n/**\n * Infers caller identity from API key JWT claims.\n */\nexport function inferIdentityFromApiKey(\n apiKey: string\n): StarciteIdentity | undefined {\n const claims = ApiKeyClaimsSchema.parse(decodeJwt(apiKey));\n\n const id = claims.principal_id ?? claims.sub;\n const tenantId = claims.tenant_id;\n\n if (!(tenantId && id && claims.principal_type)) {\n return undefined;\n }\n\n return new StarciteIdentity({\n tenantId,\n id,\n type: claims.principal_type,\n });\n}\n\n/**\n * Decodes session token JWT claims and returns the session ID and identity.\n */\nexport function decodeSessionToken(token: string): {\n sessionId?: string;\n identity: StarciteIdentity;\n} {\n const claims = SessionTokenClaimsSchema.parse(decodeJwt(token));\n const principalId = claims.principal_id ?? claims.sub ?? \"session-user\";\n const principalType = claims.principal_type ?? \"user\";\n\n return {\n sessionId: claims.session_id,\n identity: new StarciteIdentity({\n tenantId: claims.tenant_id,\n id: principalId,\n type: principalType,\n }),\n };\n}\n","import { z } from \"zod\";\n\nconst AGENT_PREFIX = \"agent:\";\nconst USER_PREFIX = \"user:\";\n\nexport const PrincipalTypeSchema = z.enum([\"user\", \"agent\"]);\nexport type PrincipalType = z.infer<typeof PrincipalTypeSchema>;\n\nexport const SessionCreatorPrincipalSchema = z.object({\n tenant_id: z.string().min(1),\n id: z.string().min(1),\n type: PrincipalTypeSchema,\n});\n\nexport type SessionCreatorPrincipal = z.infer<\n typeof SessionCreatorPrincipalSchema\n>;\n\nexport const SessionTokenPrincipalSchema = z.object({\n type: PrincipalTypeSchema,\n id: z.string().min(1),\n});\n\nexport type SessionTokenPrincipal = z.infer<typeof SessionTokenPrincipalSchema>;\n\n/**\n * Represents a resolved caller identity with tenant, principal id, and type.\n */\nexport class StarciteIdentity {\n readonly tenantId: string;\n readonly id: string;\n readonly type: PrincipalType;\n\n constructor(options: {\n tenantId: string;\n id: string;\n type: PrincipalType;\n }) {\n this.tenantId = options.tenantId;\n this.id = options.id;\n this.type = options.type;\n }\n\n /**\n * Serializes to the `creator_principal` wire format expected by the API.\n */\n toCreatorPrincipal(): SessionCreatorPrincipal {\n return { tenant_id: this.tenantId, id: this.id, type: this.type };\n }\n\n /**\n * Serializes to the `principal` wire format used in session token requests.\n */\n toTokenPrincipal(): SessionTokenPrincipal {\n return { id: this.id, type: this.type };\n }\n\n /**\n * Returns the actor string derived from this identity (e.g. `agent:planner`, `user:alice`).\n */\n toActor(): string {\n if (this.id.startsWith(AGENT_PREFIX) || this.id.startsWith(USER_PREFIX)) {\n return this.id;\n }\n return `${this.type}:${this.id}`;\n }\n}\n\n/**\n * Extracts the agent name from an actor value like `agent:planner`.\n */\nexport function agentFromActor(actor: string): string | undefined {\n return actor.startsWith(AGENT_PREFIX)\n ? actor.slice(AGENT_PREFIX.length)\n : undefined;\n}\n","import type { StarciteErrorPayload } from \"./types\";\n\n/**\n * Base error type for SDK-level failures.\n */\nexport class StarciteError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StarciteError\";\n }\n}\n\n/**\n * Thrown when the Starcite API responds with a non-2xx status code.\n */\nexport class StarciteApiError extends StarciteError {\n /** HTTP status code returned by the API. */\n readonly status: number;\n /** Stable API error code (or synthesized `http_<status>` fallback). */\n readonly code: string;\n /** Parsed API error payload when available. */\n readonly payload: StarciteErrorPayload | null;\n\n constructor(\n message: string,\n status: number,\n code: string,\n payload: StarciteErrorPayload | null\n ) {\n super(message);\n this.name = \"StarciteApiError\";\n this.status = status;\n this.code = code;\n this.payload = payload;\n }\n}\n\n/**\n * Thrown when the SDK cannot reach Starcite or receives invalid transport payloads.\n */\nexport class StarciteConnectionError extends StarciteError {\n constructor(message: string) {\n super(message);\n this.name = \"StarciteConnectionError\";\n }\n}\n\nexport type StarciteTailErrorStage =\n | \"connect\"\n | \"stream\"\n | \"retry_limit\"\n | \"consumer_backpressure\";\n\n/**\n * Thrown for tail-stream failures with structured stage/context fields.\n */\nexport class StarciteTailError extends StarciteConnectionError {\n /** Session id tied to this tail stream. */\n readonly sessionId: string;\n /** Failure stage in the tail lifecycle. */\n readonly stage: StarciteTailErrorStage;\n /** Reconnect attempts observed before failing. */\n readonly attempts: number;\n /** WebSocket close code when available. */\n readonly closeCode?: number;\n /** WebSocket close reason when available. */\n readonly closeReason?: string;\n\n constructor(\n message: string,\n options: {\n sessionId: string;\n stage: StarciteTailErrorStage;\n attempts?: number;\n closeCode?: number;\n closeReason?: string;\n }\n ) {\n super(message);\n this.name = \"StarciteTailError\";\n this.sessionId = options.sessionId;\n this.stage = options.stage;\n this.attempts = options.attempts ?? 0;\n this.closeCode = options.closeCode;\n this.closeReason = options.closeReason;\n }\n}\n\n/**\n * Thrown when the tail WebSocket is closed with code 4001 (token expired).\n *\n * Callers should re-issue a session token and reconnect from the last cursor.\n */\nexport class StarciteTokenExpiredError extends StarciteTailError {\n constructor(\n message: string,\n options: {\n sessionId: string;\n attempts?: number;\n closeCode?: number;\n closeReason?: string;\n }\n ) {\n super(message, { ...options, stage: \"stream\" });\n this.name = \"StarciteTokenExpiredError\";\n }\n}\n\n/**\n * Thrown when the tail consumer falls behind and exceeds the buffered batch limit.\n */\nexport class StarciteBackpressureError extends StarciteTailError {\n constructor(\n message: string,\n options: {\n sessionId: string;\n attempts?: number;\n }\n ) {\n super(message, { ...options, stage: \"consumer_backpressure\" });\n this.name = \"StarciteBackpressureError\";\n }\n}\n\n/**\n * Thrown when tail reconnect attempts exceed the configured limit.\n */\nexport class StarciteRetryLimitError extends StarciteTailError {\n constructor(\n message: string,\n options: {\n sessionId: string;\n attempts: number;\n closeCode?: number;\n closeReason?: string;\n }\n ) {\n super(message, { ...options, stage: \"retry_limit\" });\n this.name = \"StarciteRetryLimitError\";\n }\n}\n","import EventEmitter from \"eventemitter3\";\nimport { StarciteError } from \"./errors\";\nimport type { StarciteIdentity } from \"./identity\";\nimport { SessionLog, SessionLogGapError } from \"./session-log\";\nimport { TailStream } from \"./tail/stream\";\nimport type { TransportConfig } from \"./transport\";\nimport { request } from \"./transport\";\nimport type {\n AppendEventRequest,\n AppendEventResponse,\n AppendResult,\n RequestOptions,\n SessionAppendInput,\n SessionConsumeOptions,\n SessionEvent,\n SessionLogOptions,\n SessionRecord,\n SessionSnapshot,\n SessionStore,\n SessionTailOptions,\n TailEvent,\n} from \"./types\";\nimport { AppendEventResponseSchema, SessionAppendInputSchema } from \"./types\";\n\n/**\n * Construction options for a `StarciteSession`.\n */\nexport interface StarciteSessionOptions {\n id: string;\n token: string;\n identity: StarciteIdentity;\n transport: TransportConfig;\n store: SessionStore;\n record?: SessionRecord;\n logOptions?: SessionLogOptions;\n}\n\ntype SessionEventListener = (event: SessionEvent) => void;\n\ninterface SessionLifecycleEvents {\n error: (error: Error) => void;\n}\n\n/**\n * Session-scoped client bound to a specific identity and session token.\n *\n * All operations use the session token for auth — not the parent client's API key.\n */\nexport class StarciteSession {\n /** Session identifier. */\n readonly id: string;\n /** The session JWT used for auth. Extract this for frontend handoff. */\n readonly token: string;\n /** Identity bound to this session. */\n readonly identity: StarciteIdentity;\n /** Optional session record captured at creation time. */\n readonly record?: SessionRecord;\n\n private readonly transport: TransportConfig;\n private readonly producerId: string;\n private producerSeq = 0;\n\n readonly log: SessionLog;\n private readonly store: SessionStore;\n private readonly lifecycle = new EventEmitter<SessionLifecycleEvents>();\n private readonly eventSubscriptions = new Map<\n SessionEventListener,\n () => void\n >();\n private liveSyncController: AbortController | undefined;\n private liveSyncTask: Promise<void> | undefined;\n\n constructor(options: StarciteSessionOptions) {\n this.id = options.id;\n this.token = options.token;\n this.identity = options.identity;\n this.transport = options.transport;\n this.record = options.record;\n this.producerId = crypto.randomUUID();\n this.store = options.store;\n this.log = new SessionLog(options.logOptions);\n\n const storedState = this.store.load(this.id);\n if (storedState) {\n this.log.hydrate(storedState);\n }\n }\n\n /**\n * Appends an event to this session.\n *\n * The SDK manages `actor`, `producer_id`, and `producer_seq` automatically.\n */\n async append(\n input: SessionAppendInput,\n options?: RequestOptions\n ): Promise<AppendResult> {\n const parsed = SessionAppendInputSchema.parse(input);\n this.producerSeq += 1;\n\n const result = await this.appendRaw(\n {\n type: parsed.type ?? \"content\",\n payload: parsed.payload ?? { text: parsed.text },\n actor: parsed.actor ?? this.identity.toActor(),\n producer_id: this.producerId,\n producer_seq: this.producerSeq,\n source: parsed.source ?? \"agent\",\n metadata: parsed.metadata,\n refs: parsed.refs,\n idempotency_key: parsed.idempotencyKey,\n expected_seq: parsed.expectedSeq,\n },\n options\n );\n\n return {\n seq: result.seq,\n deduped: result.deduped,\n };\n }\n\n /**\n * Appends a raw event payload as-is. Caller manages all fields.\n */\n appendRaw(\n input: AppendEventRequest,\n options?: RequestOptions\n ): Promise<AppendEventResponse> {\n return request(\n this.transport,\n `/sessions/${encodeURIComponent(this.id)}/append`,\n {\n method: \"POST\",\n body: JSON.stringify(input),\n signal: options?.signal,\n },\n AppendEventResponseSchema\n );\n }\n\n /**\n * Subscribes to canonical session events and lifecycle errors.\n */\n on(eventName: \"event\", listener: SessionEventListener): () => void;\n on(eventName: \"error\", listener: (error: Error) => void): () => void;\n on(\n eventName: \"event\" | \"error\",\n listener: SessionEventListener | ((error: Error) => void)\n ): () => void {\n if (eventName === \"event\") {\n const eventListener = listener as SessionEventListener;\n if (!this.eventSubscriptions.has(eventListener)) {\n const unsubscribe = this.log.subscribe(eventListener, { replay: true });\n this.eventSubscriptions.set(eventListener, unsubscribe);\n }\n\n this.ensureLiveSync();\n return () => {\n this.off(\"event\", eventListener);\n };\n }\n\n if (eventName === \"error\") {\n const errorListener = listener as (error: Error) => void;\n this.lifecycle.on(\"error\", errorListener);\n return () => {\n this.off(\"error\", errorListener);\n };\n }\n\n throw new StarciteError(`Unsupported event name '${eventName}'`);\n }\n\n /**\n * Removes a previously registered listener.\n */\n off(eventName: \"event\", listener: SessionEventListener): void;\n off(eventName: \"error\", listener: (error: Error) => void): void;\n off(\n eventName: \"event\" | \"error\",\n listener: SessionEventListener | ((error: Error) => void)\n ): void {\n if (eventName === \"event\") {\n const eventListener = listener as SessionEventListener;\n const unsubscribe = this.eventSubscriptions.get(eventListener);\n if (!unsubscribe) {\n return;\n }\n\n this.eventSubscriptions.delete(eventListener);\n unsubscribe();\n\n if (this.eventSubscriptions.size === 0) {\n this.liveSyncController?.abort();\n }\n return;\n }\n\n if (eventName === \"error\") {\n this.lifecycle.off(\"error\", listener as (error: Error) => void);\n return;\n }\n\n throw new StarciteError(`Unsupported event name '${eventName}'`);\n }\n\n /**\n * Stops live syncing and removes listeners registered via `on()`.\n */\n disconnect(): void {\n this.liveSyncController?.abort();\n\n for (const unsubscribe of this.eventSubscriptions.values()) {\n unsubscribe();\n }\n this.eventSubscriptions.clear();\n this.lifecycle.removeAllListeners();\n }\n\n /**\n * Backwards-compatible alias for `disconnect()`.\n */\n close(): void {\n this.disconnect();\n }\n\n /**\n * Updates in-memory session log retention.\n */\n setLogOptions(options: SessionLogOptions): void {\n this.log.setMaxEvents(options.maxEvents);\n this.persistLogState();\n }\n\n /**\n * Returns a stable snapshot of the current canonical in-memory log.\n */\n getSnapshot(): SessionSnapshot {\n return this.log.getSnapshot(this.liveSyncTask !== undefined);\n }\n\n /**\n * Streams tail events one at a time via callback.\n */\n async tail(\n onEvent: (event: TailEvent) => void | Promise<void>,\n options: SessionTailOptions = {}\n ): Promise<void> {\n await this.tailBatches(async (batch) => {\n for (const event of batch) {\n await onEvent(event);\n }\n }, options);\n }\n\n /**\n * Streams tail event batches grouped by incoming frame via callback.\n */\n async tailBatches(\n onBatch: (batch: TailEvent[]) => void | Promise<void>,\n options: SessionTailOptions = {}\n ): Promise<void> {\n await new TailStream({\n sessionId: this.id,\n token: this.token,\n websocketBaseUrl: this.transport.websocketBaseUrl,\n websocketFactory: this.transport.websocketFactory,\n options,\n }).subscribe(onBatch);\n }\n\n /**\n * Durably consumes events and checkpoints `event.seq` after each successful handler invocation.\n */\n async consume(options: SessionConsumeOptions): Promise<void> {\n const {\n cursorStore,\n handler,\n cursor: requestedCursor,\n ...tailOptions\n } = options;\n\n let cursor: number;\n\n if (requestedCursor !== undefined) {\n cursor = requestedCursor;\n } else {\n try {\n cursor = (await cursorStore.load(this.id)) ?? 0;\n } catch (error) {\n throw new StarciteError(\n `consume() failed to load cursor for session '${this.id}': ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n const stream = new TailStream({\n sessionId: this.id,\n token: this.token,\n websocketBaseUrl: this.transport.websocketBaseUrl,\n websocketFactory: this.transport.websocketFactory,\n options: {\n ...tailOptions,\n cursor,\n },\n });\n\n await stream.subscribe(async (batch) => {\n for (const event of batch) {\n await handler(event);\n\n try {\n await cursorStore.save(this.id, event.seq);\n } catch (error) {\n throw new StarciteError(\n `consume() failed to save cursor for session '${this.id}': ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n });\n }\n\n private emitStreamError(error: unknown): void {\n const streamError =\n error instanceof Error\n ? error\n : new StarciteError(`Session stream failed: ${String(error)}`);\n\n if (this.lifecycle.listenerCount(\"error\") > 0) {\n this.lifecycle.emit(\"error\", streamError);\n return;\n }\n\n queueMicrotask(() => {\n throw streamError;\n });\n }\n\n private ensureLiveSync(): void {\n if (this.liveSyncTask || this.eventSubscriptions.size === 0) {\n return;\n }\n\n const controller = new AbortController();\n this.liveSyncController = controller;\n\n this.liveSyncTask = this.runLiveSync(controller.signal)\n .catch((error) => {\n if (!controller.signal.aborted) {\n this.emitStreamError(error);\n }\n })\n .finally(() => {\n this.liveSyncTask = undefined;\n this.liveSyncController = undefined;\n });\n }\n\n private async runLiveSync(signal: AbortSignal): Promise<void> {\n while (!signal.aborted && this.eventSubscriptions.size > 0) {\n const stream = new TailStream({\n sessionId: this.id,\n token: this.token,\n websocketBaseUrl: this.transport.websocketBaseUrl,\n websocketFactory: this.transport.websocketFactory,\n options: {\n cursor: this.log.lastSeq,\n signal,\n },\n });\n\n try {\n await stream.subscribe((batch) => {\n const appliedEvents = this.log.applyBatch(batch);\n if (appliedEvents.length > 0) {\n this.persistLogState();\n }\n });\n } catch (error) {\n if (signal.aborted) {\n return;\n }\n\n if (error instanceof SessionLogGapError) {\n continue;\n }\n\n throw error;\n }\n }\n }\n\n private persistLogState(): void {\n this.store.save(this.id, {\n cursor: this.log.cursor,\n events: [...this.log.events],\n });\n }\n}\n","import EventEmitter from \"eventemitter3\";\nimport { StarciteError } from \"./errors\";\nimport type {\n SessionLogOptions,\n SessionSnapshot,\n SessionStoreState,\n TailEvent,\n} from \"./types\";\n\ninterface SessionLogEvents {\n event: (event: TailEvent) => void;\n}\n\nexport class SessionLogGapError extends StarciteError {\n constructor(message: string) {\n super(message);\n this.name = \"SessionLogGapError\";\n }\n}\n\nexport class SessionLogConflictError extends StarciteError {\n constructor(message: string) {\n super(message);\n this.name = \"SessionLogConflictError\";\n }\n}\n\n/**\n * Canonical in-memory log for one session.\n *\n * Invariants:\n * - Applies events in strict contiguous `seq` order.\n * - Treats repeated identical events as idempotent no-ops.\n * - Rejects conflicting duplicates and sequence gaps.\n */\nexport class SessionLog {\n private readonly history: TailEvent[] = [];\n private readonly emitter = new EventEmitter<SessionLogEvents>();\n private readonly canonicalBySeq = new Map<number, string>();\n private maxEvents: number | undefined;\n private appliedSeq = 0;\n\n constructor(options: SessionLogOptions = {}) {\n this.setMaxEvents(options.maxEvents);\n }\n\n setMaxEvents(maxEvents: number | undefined): void {\n if (\n maxEvents !== undefined &&\n (!Number.isInteger(maxEvents) || maxEvents <= 0)\n ) {\n throw new StarciteError(\n \"Session log maxEvents must be a positive integer\"\n );\n }\n\n this.maxEvents = maxEvents;\n this.enforceRetention();\n }\n\n applyBatch(batch: TailEvent[]): TailEvent[] {\n const applied: TailEvent[] = [];\n\n for (const event of batch) {\n if (this.apply(event)) {\n applied.push(event);\n this.emitter.emit(\"event\", event);\n }\n }\n\n return applied;\n }\n\n hydrate(state: SessionStoreState): void {\n if (!Number.isInteger(state.cursor) || state.cursor < 0) {\n throw new StarciteError(\n \"Session store cursor must be a non-negative integer\"\n );\n }\n\n this.history.length = 0;\n this.canonicalBySeq.clear();\n this.appliedSeq = state.cursor;\n\n let previousSeq: number | undefined;\n for (const event of state.events) {\n if (event.seq > state.cursor) {\n throw new StarciteError(\n `Session store contains event seq ${event.seq} above cursor ${state.cursor}`\n );\n }\n\n if (previousSeq !== undefined && event.seq !== previousSeq + 1) {\n throw new StarciteError(\n `Session store events must be contiguous; saw seq ${event.seq} after ${previousSeq}`\n );\n }\n\n this.history.push(event);\n this.canonicalBySeq.set(event.seq, JSON.stringify(event));\n previousSeq = event.seq;\n }\n\n this.enforceRetention();\n }\n\n subscribe(\n listener: (event: TailEvent) => void,\n options: { replay?: boolean } = {}\n ): () => void {\n const shouldReplay = options.replay ?? true;\n if (shouldReplay) {\n for (const event of this.history) {\n listener(event);\n }\n }\n\n this.emitter.on(\"event\", listener);\n return () => {\n this.emitter.off(\"event\", listener);\n };\n }\n\n private apply(event: TailEvent): boolean {\n const existingCanonical = this.canonicalBySeq.get(event.seq);\n\n if (event.seq <= this.appliedSeq) {\n const incomingCanonical = JSON.stringify(event);\n if (!existingCanonical) {\n const oldestRetainedSeq = this.history[0]?.seq;\n if (oldestRetainedSeq === undefined || event.seq < oldestRetainedSeq) {\n return false;\n }\n\n throw new SessionLogConflictError(\n `Session log has no canonical payload for retained seq ${event.seq}`\n );\n }\n\n if (incomingCanonical !== existingCanonical) {\n throw new SessionLogConflictError(\n `Session log conflict for seq ${event.seq}: received different payload for an already-applied event`\n );\n }\n\n return false;\n }\n\n const expectedSeq = this.appliedSeq + 1;\n if (event.seq !== expectedSeq) {\n throw new SessionLogGapError(\n `Session log gap detected: expected seq ${expectedSeq} but received ${event.seq}`\n );\n }\n\n this.history.push(event);\n this.canonicalBySeq.set(event.seq, JSON.stringify(event));\n this.appliedSeq = event.seq;\n this.enforceRetention();\n return true;\n }\n\n getSnapshot(syncing: boolean): SessionSnapshot {\n return {\n events: this.history.slice(),\n lastSeq: this.appliedSeq,\n syncing,\n };\n }\n\n get events(): readonly TailEvent[] {\n return this.history.slice();\n }\n\n get cursor(): number {\n return this.appliedSeq;\n }\n\n get lastSeq(): number {\n return this.appliedSeq;\n }\n\n private enforceRetention(): void {\n if (this.maxEvents === undefined) {\n return;\n }\n\n while (this.history.length > this.maxEvents) {\n const removed = this.history.shift();\n if (!removed) {\n return;\n }\n\n this.canonicalBySeq.delete(removed.seq);\n }\n }\n}\n","import { z } from \"zod\";\nimport { StarciteConnectionError } from \"../errors\";\nimport type { TailEvent } from \"../types\";\nimport { TailEventSchema } from \"../types\";\n\n/**\n * Minimum allowed replay batch size accepted by the API.\n */\nexport const MIN_TAIL_BATCH_SIZE = 1;\n/**\n * Maximum allowed replay batch size accepted by the API.\n */\nexport const MAX_TAIL_BATCH_SIZE = 1000;\n\nconst TailFramePayloadSchema = z.union([\n TailEventSchema,\n z.array(TailEventSchema).min(MIN_TAIL_BATCH_SIZE),\n]);\n\n/**\n * Converts websocket message payloads to UTF-8 text for JSON parsing.\n */\nfunction toFrameText(data: unknown): string | undefined {\n if (typeof data === \"string\") {\n return data;\n }\n\n if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {\n return new TextDecoder().decode(data);\n }\n\n return undefined;\n}\n\n/**\n * Parses one websocket tail frame into a normalized event batch.\n */\nexport function parseTailFrame(data: unknown): TailEvent[] {\n const frameText = toFrameText(data);\n\n if (!frameText) {\n throw new StarciteConnectionError(\n \"Tail frame payload must be a UTF-8 string or binary buffer\"\n );\n }\n\n let framePayload: unknown;\n\n try {\n framePayload = JSON.parse(frameText) as unknown;\n } catch {\n throw new StarciteConnectionError(\"Tail frame was not valid JSON\");\n }\n\n const result = TailFramePayloadSchema.safeParse(framePayload);\n\n if (!result.success) {\n const reason =\n result.error.issues[0]?.message ?? \"Tail frame did not match schema\";\n throw new StarciteConnectionError(reason);\n }\n\n return Array.isArray(result.data) ? result.data : [result.data];\n}\n","import { z } from \"zod\";\nimport {\n SessionCreatorPrincipalSchema as SessionCreatorPrincipalSchemaValue,\n SessionTokenPrincipalSchema as SessionTokenPrincipalSchemaValue,\n} from \"./identity\";\n\nexport const SessionCreatorPrincipalSchema = SessionCreatorPrincipalSchemaValue;\nexport const SessionTokenPrincipalSchema = SessionTokenPrincipalSchemaValue;\n\nconst ArbitraryObjectSchema = z.record(z.unknown());\n\nconst SessionTokenScopeSchema = z.enum([\"session:read\", \"session:append\"]);\n\nexport type SessionTokenScope = z.infer<typeof SessionTokenScopeSchema>;\n\n/**\n * Request payload for minting a session token from the auth issuer service.\n */\nexport const IssueSessionTokenInputSchema = z.object({\n session_id: z.string().min(1),\n principal: SessionTokenPrincipalSchema,\n scopes: z.array(SessionTokenScopeSchema).min(1),\n ttl_seconds: z\n .number()\n .int()\n .positive()\n .max(24 * 60 * 60)\n .optional(),\n});\n\nexport type IssueSessionTokenInput = z.infer<\n typeof IssueSessionTokenInputSchema\n>;\n\n/**\n * Response payload returned by the auth issuer service when minting a session token.\n */\nexport const IssueSessionTokenResponseSchema = z.object({\n token: z.string().min(1),\n expires_in: z.number().int().positive(),\n});\n\nexport type IssueSessionTokenResponse = z.infer<\n typeof IssueSessionTokenResponseSchema\n>;\n\n/**\n * Request payload for creating a session.\n */\nexport const CreateSessionInputSchema = z.object({\n id: z.string().optional(),\n title: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n creator_principal: SessionCreatorPrincipalSchema.optional(),\n});\n\n/**\n * Inferred TypeScript type for {@link CreateSessionInputSchema}.\n */\nexport type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>;\n\n/**\n * Session record returned by the Starcite API.\n */\nexport const SessionRecordSchema = z.object({\n id: z.string(),\n title: z.string().nullable().optional(),\n metadata: ArbitraryObjectSchema,\n last_seq: z.number().int().nonnegative(),\n created_at: z.string(),\n updated_at: z.string(),\n});\n\n/**\n * Inferred TypeScript type for {@link SessionRecordSchema}.\n */\nexport type SessionRecord = z.infer<typeof SessionRecordSchema>;\n\n/**\n * Session item returned by the list endpoint.\n */\nexport const SessionListItemSchema = z.object({\n id: z.string(),\n title: z.string().nullable().optional(),\n metadata: ArbitraryObjectSchema,\n created_at: z.string(),\n});\n\n/**\n * Inferred TypeScript type for {@link SessionListItemSchema}.\n */\nexport type SessionListItem = z.infer<typeof SessionListItemSchema>;\n\n/**\n * Paginated session list response.\n */\nexport const SessionListPageSchema = z.object({\n sessions: z.array(SessionListItemSchema),\n next_cursor: z.string().nullable(),\n});\n\n/**\n * Inferred TypeScript type for {@link SessionListPageSchema}.\n */\nexport type SessionListPage = z.infer<typeof SessionListPageSchema>;\n\n/**\n * Low-level request payload for appending an event to a session.\n */\nexport const AppendEventRequestSchema = z.object({\n type: z.string().min(1),\n payload: ArbitraryObjectSchema,\n actor: z.string().min(1).optional(),\n producer_id: z.string().min(1),\n producer_seq: z.number().int().positive(),\n source: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n refs: ArbitraryObjectSchema.optional(),\n idempotency_key: z.string().optional(),\n expected_seq: z.number().int().nonnegative().optional(),\n});\n\n/**\n * Inferred TypeScript type for {@link AppendEventRequestSchema}.\n */\nexport type AppendEventRequest = z.infer<typeof AppendEventRequestSchema>;\n\n/**\n * API response returned after appending an event.\n */\nexport const AppendEventResponseSchema = z.object({\n seq: z.number().int().nonnegative(),\n last_seq: z.number().int().nonnegative(),\n deduped: z.boolean(),\n});\n\n/**\n * Inferred TypeScript type for {@link AppendEventResponseSchema}.\n */\nexport type AppendEventResponse = z.infer<typeof AppendEventResponseSchema>;\n\n/**\n * High-level append result returned by `session.append()`.\n */\nexport interface AppendResult {\n seq: number;\n deduped: boolean;\n}\n\n/**\n * Raw event frame shape emitted by the Starcite tail stream.\n */\nexport const TailEventSchema = z.object({\n seq: z.number().int().nonnegative(),\n type: z.string().min(1),\n payload: ArbitraryObjectSchema,\n actor: z.string().min(1),\n producer_id: z.string().min(1),\n producer_seq: z.number().int().positive(),\n source: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n refs: ArbitraryObjectSchema.optional(),\n idempotency_key: z.string().nullable().optional(),\n inserted_at: z.string().optional(),\n});\n\n/**\n * Inferred TypeScript type for {@link TailEventSchema}.\n */\nexport type TailEvent = z.infer<typeof TailEventSchema>;\n\n/**\n * Canonical session event surfaced by the SDK.\n */\nexport type SessionEvent = TailEvent;\n/**\n * Raw tail event batch grouped by a single WebSocket frame.\n */\nexport type TailEventBatch = TailEvent[];\n\n/**\n * Retention options for a session's in-memory canonical log.\n */\nexport interface SessionLogOptions {\n /**\n * Maximum number of events retained in memory.\n *\n * When omitted, the log keeps all applied events for the current runtime.\n */\n maxEvents?: number;\n}\n\n/**\n * Snapshot of a session's canonical in-memory log state.\n */\nexport interface SessionSnapshot {\n /**\n * Ordered events currently retained in memory.\n */\n events: TailEvent[];\n /**\n * Highest contiguous sequence applied to the log.\n */\n lastSeq: number;\n /**\n * Indicates whether the session is actively streaming tail updates.\n */\n syncing: boolean;\n}\n\n/**\n * Serializable persisted state for one session log.\n */\nexport interface SessionStoreState {\n /**\n * Highest contiguous sequence applied for this session.\n */\n cursor: number;\n /**\n * Retained events snapshot used for immediate replay.\n */\n events: TailEvent[];\n}\n\n/**\n * Persistence interface for session cursor + retained events.\n */\nexport interface SessionStore {\n load(sessionId: string): SessionStoreState | undefined;\n save(sessionId: string, state: SessionStoreState): void;\n clear?(sessionId: string): void;\n}\n\n/**\n * High-level `session.append()` input.\n *\n * The SDK manages `actor`, `producer_id`, and `producer_seq` automatically.\n * Just provide `text` or `payload`.\n */\nexport const SessionAppendInputSchema = z\n .object({\n text: z.string().optional(),\n payload: ArbitraryObjectSchema.optional(),\n type: z.string().optional(),\n actor: z.string().trim().min(1).optional(),\n source: z.string().optional(),\n metadata: ArbitraryObjectSchema.optional(),\n refs: ArbitraryObjectSchema.optional(),\n idempotencyKey: z.string().optional(),\n expectedSeq: z.number().int().nonnegative().optional(),\n })\n .refine((value) => !!(value.text || value.payload), {\n message: \"append() requires either 'text' or an object 'payload'\",\n });\n\n/**\n * Inferred TypeScript type for {@link SessionAppendInputSchema}.\n */\nexport type SessionAppendInput = z.infer<typeof SessionAppendInputSchema>;\n\n/**\n * Options for streaming events from a session.\n */\nexport interface SessionTailOptions {\n /**\n * Starting cursor (inclusive) in the event stream.\n */\n cursor?: number;\n /**\n * Tail frame batch size (`1..1000`).\n *\n * When greater than `1`, Starcite may emit batched WebSocket frames.\n */\n batchSize?: number;\n /**\n * Optional filter for `agent:<name>` events.\n */\n agent?: string;\n /**\n * Idle window in milliseconds used for replay-only tails (`follow=false`) before auto-close.\n *\n * Defaults to `1000`.\n */\n catchUpIdleMs?: number;\n /**\n * Automatically reconnect on transport failures and continue from the last observed sequence.\n *\n * Defaults to `true`.\n */\n reconnect?: boolean;\n /**\n * Reconnect policy for transport failures.\n */\n reconnectPolicy?: TailReconnectPolicy;\n /**\n * When `false`, exit after replaying stored events instead of streaming live.\n *\n * Defaults to `true`.\n */\n follow?: boolean;\n /**\n * Optional abort signal to close the stream.\n */\n signal?: AbortSignal;\n /**\n * Maximum number of tail batches buffered in-memory while the consumer is busy.\n *\n * Defaults to `1024`. When exceeded, the stream fails with `StarciteTailError`.\n */\n maxBufferedBatches?: number;\n /**\n * Optional lifecycle callback invoked for reconnect/drop/terminal stream state changes.\n */\n onLifecycleEvent?: (event: TailLifecycleEvent) => void;\n /**\n * Maximum time to wait for websocket handshake/open before reconnecting or failing.\n *\n * Defaults to `4000`.\n */\n connectionTimeoutMs?: number;\n /**\n * Optional inactivity watchdog. When set, the stream reconnects when no messages\n * arrive within this duration.\n */\n inactivityTimeoutMs?: number;\n}\n\n/**\n * Tail reconnect tuning knobs.\n */\nexport interface TailReconnectPolicy {\n /**\n * Reconnect mode. `fixed` retries at the same delay, `exponential` increases delay after repeated failures.\n *\n * Defaults to `exponential`.\n */\n mode?: \"fixed\" | \"exponential\";\n /**\n * Initial reconnect delay in milliseconds.\n *\n * Defaults to `500`.\n */\n initialDelayMs?: number;\n /**\n * Maximum reconnect delay in milliseconds.\n *\n * Defaults to `15000`.\n */\n maxDelayMs?: number;\n /**\n * Exponential growth factor applied after each failed reconnect attempt.\n *\n * Defaults to `2`.\n */\n multiplier?: number;\n /**\n * Optional jitter ratio (`0..1`) applied around the computed delay.\n *\n * Defaults to `0.2`.\n */\n jitterRatio?: number;\n /**\n * Maximum number of reconnect attempts before failing.\n *\n * Defaults to unlimited retries.\n */\n maxAttempts?: number;\n}\n\n/**\n * Stream lifecycle event emitted by `tail*()` APIs.\n */\nexport type TailLifecycleEvent =\n | {\n type: \"connect_attempt\";\n sessionId: string;\n attempt: number;\n cursor: number;\n }\n | {\n type: \"reconnect_scheduled\";\n sessionId: string;\n attempt: number;\n delayMs: number;\n trigger: \"connect_failed\" | \"dropped\";\n closeCode?: number;\n closeReason?: string;\n }\n | {\n type: \"stream_dropped\";\n sessionId: string;\n attempt: number;\n closeCode?: number;\n closeReason?: string;\n }\n | {\n type: \"stream_ended\";\n sessionId: string;\n reason: \"aborted\" | \"caught_up\" | \"graceful\";\n };\n\n/**\n * Storage adapter used by `session.consume*()` to persist the last processed cursor.\n */\nexport interface SessionCursorStore {\n /**\n * Loads the last processed cursor for a session.\n *\n * Return `undefined` when no cursor has been stored yet.\n */\n load(sessionId: string): number | undefined | Promise<number | undefined>;\n /**\n * Persists the last processed cursor for a session.\n */\n save(sessionId: string, cursor: number): void | Promise<void>;\n}\n\n/**\n * Durable tail consumption options with automatic cursor checkpointing.\n */\nexport interface SessionConsumeOptions\n extends Omit<SessionTailOptions, \"cursor\"> {\n /**\n * Optional explicit starting cursor. When omitted, the SDK loads it from `cursorStore`.\n */\n cursor?: number;\n /**\n * Cursor storage adapter used for resume-safe processing.\n */\n cursorStore: SessionCursorStore;\n /**\n * Event handler. The cursor is checkpointed only after this handler succeeds.\n */\n handler: (event: TailEvent) => void | Promise<void>;\n}\n\n/**\n * Options for listing sessions.\n */\nexport const SessionListOptionsSchema = z.object({\n limit: z.number().int().positive().optional(),\n cursor: z.string().trim().min(1).optional(),\n metadata: z\n .record(z.string().trim().min(1), z.string().trim().min(1))\n .optional(),\n});\n\nexport type SessionListOptions = z.input<typeof SessionListOptionsSchema>;\n\n/**\n * Minimal WebSocket contract required by the SDK.\n */\nexport interface StarciteWebSocketMessageEvent {\n data: unknown;\n}\n\nexport interface StarciteWebSocketCloseEvent {\n code?: number;\n reason?: string;\n}\n\nexport interface StarciteWebSocketEventMap {\n open: unknown;\n message: StarciteWebSocketMessageEvent;\n error: unknown;\n close: StarciteWebSocketCloseEvent;\n}\n\nexport interface StarciteWebSocket {\n addEventListener<TType extends keyof StarciteWebSocketEventMap>(\n type: TType,\n listener: (event: StarciteWebSocketEventMap[TType]) => void\n ): void;\n removeEventListener<TType extends keyof StarciteWebSocketEventMap>(\n type: TType,\n listener: (event: StarciteWebSocketEventMap[TType]) => void\n ): void;\n close(code?: number, reason?: string): void;\n}\n\n/**\n * Factory used to create the WebSocket connection for `tail`.\n */\nexport type StarciteWebSocketFactory = (url: string) => StarciteWebSocket;\n\n/**\n * Options forwarded to individual HTTP requests.\n */\nexport interface RequestOptions {\n /**\n * Optional abort signal to cancel the request.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Client construction options.\n */\nexport interface StarciteOptions {\n /**\n * Base API URL. Defaults to `process.env.STARCITE_BASE_URL` or `http://localhost:4000`.\n */\n baseUrl?: string;\n /**\n * Custom fetch implementation for non-standard runtimes.\n */\n fetch?: typeof fetch;\n /**\n * Headers applied to every HTTP request.\n */\n headers?: HeadersInit;\n /**\n * Service key / JWT token. When set, the SDK automatically sends\n * `Authorization: Bearer <token>` for HTTP requests.\n */\n apiKey?: string;\n /**\n * Auth issuer URL used to mint session tokens. When omitted, the SDK derives\n * this from API key JWT `iss` (issuer authority) or `STARCITE_AUTH_URL`.\n */\n authUrl?: string;\n /**\n * Custom WebSocket factory for non-browser runtimes.\n */\n websocketFactory?: StarciteWebSocketFactory;\n /**\n * Session store used for cursor + retained event persistence.\n *\n * Defaults to an in-memory store.\n */\n store?: SessionStore;\n}\n\n/**\n * Error payload shape returned by non-2xx API responses.\n */\nexport type StarciteErrorPayload = Record<string, unknown>;\n","import EventEmitter from \"eventemitter3\";\nimport type {\n StarciteWebSocket,\n StarciteWebSocketCloseEvent,\n StarciteWebSocketEventMap,\n StarciteWebSocketFactory,\n StarciteWebSocketMessageEvent,\n} from \"../types\";\n\nconst NORMAL_CLOSE_CODE = 1000;\nconst INACTIVITY_CLOSE_CODE = 4000;\nconst CONNECTION_TIMEOUT_CLOSE_CODE = 4100;\n\ntype ConnectTrigger = \"connect_failed\" | \"dropped\";\n\ninterface ReconnectPolicy {\n initialDelayMs: number;\n maxDelayMs: number;\n multiplier: number;\n jitterRatio: number;\n maxAttempts: number;\n}\n\nexport interface ManagedWebSocketEvents {\n connect_attempt: (event: { attempt: number }) => void;\n connect_failed: (event: { attempt: number; rootCause: string }) => void;\n reconnect_scheduled: (event: {\n attempt: number;\n delayMs: number;\n trigger: ConnectTrigger;\n closeCode?: number;\n closeReason?: string;\n rootCause?: string;\n }) => void;\n dropped: (event: {\n attempt: number;\n closeCode?: number;\n closeReason?: string;\n }) => void;\n retry_limit: (event: {\n attempt: number;\n trigger: ConnectTrigger;\n closeCode?: number;\n closeReason?: string;\n rootCause?: string;\n }) => void;\n open: () => void;\n message: (data: unknown) => void;\n fatal: (error: unknown) => void;\n closed: (event: {\n closeCode?: number;\n closeReason?: string;\n aborted: boolean;\n graceful: boolean;\n }) => void;\n}\n\nexport interface ManagedWebSocketOptions {\n // Re-evaluated for each connect attempt so reconnects use the latest cursor\n // held by `TailStream`, without `TailStream` managing reconnect internals.\n url: () => string;\n websocketFactory: StarciteWebSocketFactory;\n signal?: AbortSignal;\n shouldReconnect: boolean;\n reconnectPolicy: ReconnectPolicy;\n connectionTimeoutMs: number;\n inactivityTimeoutMs?: number;\n}\n\ninterface SocketRunResult {\n closeCode?: number;\n closeReason?: string;\n sawTransportError: boolean;\n aborted: boolean;\n listenerError?: unknown;\n}\n\ninterface FinalState {\n closeCode?: number;\n closeReason?: string;\n aborted: boolean;\n graceful: boolean;\n}\n\n/**\n * Managed websocket loop with reconnect + timeout controls.\n *\n * `waitForClose()` returns one shared completion promise for all callers.\n * Connect/drop/retry decisions are emitted as lifecycle events.\n * Listener exceptions are treated as fatal (fail-fast over silent corruption).\n *\n * This powers `TailStream` so transport behavior is centralized in one place.\n */\nexport class ManagedWebSocket extends EventEmitter<ManagedWebSocketEvents> {\n private readonly options: ManagedWebSocketOptions;\n private socket: StarciteWebSocket | undefined;\n private cancelReconnectWait: (() => void) | undefined;\n // Set while a socket run is active so `close()` can synchronously settle it.\n private forceCloseSocket:\n | ((code: number, reason: string, aborted?: boolean) => void)\n | undefined;\n private started = false;\n private closed = false;\n // Tracks reconnect attempts for backoff and retry-limit accounting.\n private reconnectAttempts = 0;\n // Shared deferred completion for all callers of waitForClose(), even late ones.\n private readonly donePromise: Promise<void>;\n // Set to `undefined` after resolution so finish() remains idempotent.\n private resolveDone: (() => void) | undefined;\n\n constructor(options: ManagedWebSocketOptions) {\n super();\n this.options = options;\n this.donePromise = new Promise<void>((resolve) => {\n this.resolveDone = resolve;\n });\n }\n\n close(code = NORMAL_CLOSE_CODE, reason = \"closed\"): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.cancelReconnectWait?.();\n this.cancelReconnectWait = undefined;\n\n if (!this.started) {\n this.finish({\n closeCode: code,\n closeReason: reason,\n aborted: this.options.signal?.aborted ?? false,\n graceful: code === NORMAL_CLOSE_CODE,\n });\n return;\n }\n\n if (this.forceCloseSocket) {\n this.forceCloseSocket(code, reason);\n return;\n }\n this.socket?.close(code, reason);\n }\n\n resetReconnectAttempts(): void {\n // Called by `TailStream` once useful data has been consumed.\n this.reconnectAttempts = 0;\n }\n\n waitForClose(): Promise<void> {\n // Construction is side-effect free; transport starts when someone awaits closure.\n this.start();\n return this.donePromise;\n }\n\n private start(): void {\n if (this.started || this.resolveDone === undefined) {\n return;\n }\n\n this.started = true;\n this.run().catch((error) => {\n this.emitSafe(\"fatal\", error);\n this.finish({\n closeCode: undefined,\n closeReason: \"run failed\",\n aborted: this.options.signal?.aborted ?? false,\n graceful: false,\n });\n });\n }\n\n private async run(): Promise<void> {\n const finalState: FinalState = {\n closeCode: undefined,\n closeReason: undefined,\n aborted: this.options.signal?.aborted ?? false,\n graceful: false,\n };\n\n // Keep running attempts until a terminal condition wins:\n // graceful close, abort/explicit close, retry limit, or fatal listener error.\n while (!this.closed) {\n if (this.options.signal?.aborted) {\n this.closed = true;\n finalState.aborted = true;\n break;\n }\n\n const attempt = this.reconnectAttempts + 1;\n // Lifecycle listeners can intentionally stop the run by throwing.\n if (!this.emitSafe(\"connect_attempt\", { attempt })) {\n this.closed = true;\n break;\n }\n if (this.closed) {\n break;\n }\n\n let socket: StarciteWebSocket;\n try {\n // Resolve URL per attempt so reconnect uses latest producer cursor state.\n const url = this.options.url();\n socket = this.options.websocketFactory(url);\n } catch (error) {\n // Connect failures use the same retry policy path as dropped sockets.\n const shouldContinue = await this.handleConnectFailure(attempt, error);\n if (shouldContinue) {\n continue;\n }\n break;\n }\n\n if (this.closed) {\n // Close was requested between socket creation and run loop registration.\n closeQuietly(socket, NORMAL_CLOSE_CODE, \"closed\");\n break;\n }\n\n const result = await this.runSocket(socket);\n const shouldContinue = await this.handleSocketResult(\n attempt,\n result,\n finalState\n );\n if (shouldContinue) {\n continue;\n }\n\n break;\n }\n\n this.finish(finalState);\n }\n\n private async handleConnectFailure(\n attempt: number,\n error: unknown\n ): Promise<boolean> {\n const rootCause = toErrorMessage(error);\n if (!this.emitSafe(\"connect_failed\", { attempt, rootCause })) {\n this.closed = true;\n return false;\n }\n\n return await this.scheduleReconnect({\n attempt,\n trigger: \"connect_failed\",\n rootCause,\n });\n }\n\n private async handleSocketResult(\n attempt: number,\n result: SocketRunResult,\n finalState: FinalState\n ): Promise<boolean> {\n // Preserve terminal metadata so `TailStream` can classify why the stream ended.\n finalState.closeCode = result.closeCode;\n finalState.closeReason = result.closeReason;\n finalState.aborted =\n result.aborted || (this.options.signal?.aborted ?? false);\n finalState.graceful =\n !result.sawTransportError && result.closeCode === NORMAL_CLOSE_CODE;\n\n if (result.listenerError !== undefined) {\n // Listener failures are fatal to avoid continuing with inconsistent consumer state.\n this.emitSafe(\"fatal\", result.listenerError);\n this.closed = true;\n return false;\n }\n\n if (this.closed || finalState.aborted || finalState.graceful) {\n return false;\n }\n\n if (\n !this.emitSafe(\"dropped\", {\n attempt,\n closeCode: result.closeCode,\n closeReason: result.closeReason,\n })\n ) {\n this.closed = true;\n return false;\n }\n\n return await this.scheduleReconnect({\n attempt,\n trigger: \"dropped\",\n closeCode: result.closeCode,\n closeReason: result.closeReason,\n });\n }\n\n private async scheduleReconnect(input: {\n attempt: number;\n trigger: ConnectTrigger;\n closeCode?: number;\n closeReason?: string;\n rootCause?: string;\n }): Promise<boolean> {\n // Single policy gate for retries so connect and dropped failures behave identically.\n if (\n !this.options.shouldReconnect ||\n this.closed ||\n this.options.signal?.aborted\n ) {\n this.closed = true;\n return false;\n }\n\n if (input.attempt > this.options.reconnectPolicy.maxAttempts) {\n this.emitSafe(\"retry_limit\", {\n attempt: input.attempt,\n trigger: input.trigger,\n closeCode: input.closeCode,\n closeReason: input.closeReason,\n rootCause: input.rootCause,\n });\n this.closed = true;\n return false;\n }\n\n const delayMs = reconnectDelayForAttempt(\n input.attempt,\n this.options.reconnectPolicy\n );\n if (\n !this.emitSafe(\"reconnect_scheduled\", {\n attempt: input.attempt,\n delayMs,\n trigger: input.trigger,\n closeCode: input.closeCode,\n closeReason: input.closeReason,\n rootCause: input.rootCause,\n })\n ) {\n this.closed = true;\n return false;\n }\n\n this.reconnectAttempts = input.attempt;\n const reconnectWait = waitForDelay(delayMs, this.options.signal);\n this.cancelReconnectWait = reconnectWait.cancel;\n await reconnectWait.promise;\n if (this.cancelReconnectWait === reconnectWait.cancel) {\n this.cancelReconnectWait = undefined;\n }\n\n return !(this.closed || (this.options.signal?.aborted ?? false));\n }\n\n private runSocket(socket: StarciteWebSocket): Promise<SocketRunResult> {\n // Owns one socket lifetime and resolves to a classified outcome.\n return new Promise((resolve) => {\n this.socket = socket;\n let settled = false;\n let socketOpen = false;\n let sawTransportError = false;\n let aborted = false;\n let listenerError: unknown;\n let closeCode: number | undefined;\n let closeReason: string | undefined;\n\n let connectionTimeout: ReturnType<typeof setTimeout> | undefined;\n let inactivityTimeout: ReturnType<typeof setTimeout> | undefined;\n\n const clearTimers = (): void => {\n if (connectionTimeout) {\n clearTimeout(connectionTimeout);\n connectionTimeout = undefined;\n }\n if (inactivityTimeout) {\n clearTimeout(inactivityTimeout);\n inactivityTimeout = undefined;\n }\n };\n\n const armConnectionTimeout = (): void => {\n clearTimeout(connectionTimeout);\n if (this.options.connectionTimeoutMs <= 0) {\n return;\n }\n connectionTimeout = setTimeout(() => {\n if (settled || socketOpen || this.closed) {\n return;\n }\n closeAndSettle(CONNECTION_TIMEOUT_CLOSE_CODE, \"connection timeout\");\n }, this.options.connectionTimeoutMs);\n };\n\n const armInactivityTimeout = (): void => {\n clearTimeout(inactivityTimeout);\n const timeoutMs = this.options.inactivityTimeoutMs;\n if (!timeoutMs || timeoutMs <= 0 || this.closed) {\n return;\n }\n inactivityTimeout = setTimeout(() => {\n if (settled || this.closed) {\n return;\n }\n closeAndSettle(INACTIVITY_CLOSE_CODE, \"inactivity timeout\");\n }, timeoutMs);\n };\n\n const closeAndSettle = (\n code: number,\n reason: string,\n markAborted = false\n ): void => {\n if (settled) {\n return;\n }\n\n aborted = aborted || markAborted;\n closeCode = code;\n closeReason = reason;\n try {\n socket.close(code, reason);\n } catch {\n // Ignore close transport errors and settle locally.\n }\n settle();\n };\n\n const settle = (): void => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimers();\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"message\", onMessage);\n socket.removeEventListener(\"error\", onError);\n socket.removeEventListener(\"close\", onClose);\n this.options.signal?.removeEventListener(\"abort\", onAbort);\n\n if (this.socket === socket) {\n this.socket = undefined;\n }\n this.forceCloseSocket = undefined;\n\n resolve({\n closeCode,\n closeReason,\n sawTransportError,\n aborted,\n listenerError,\n });\n };\n\n const onOpen = (): void => {\n socketOpen = true;\n clearTimeout(connectionTimeout);\n armInactivityTimeout();\n if (!this.emitSafe(\"open\")) {\n listenerError = new Error(\"Managed websocket open listener failed\");\n closeAndSettle(NORMAL_CLOSE_CODE, \"listener failed\");\n }\n };\n\n const onMessage = (event: StarciteWebSocketMessageEvent): void => {\n armInactivityTimeout();\n if (!this.emitSafe(\"message\", event.data)) {\n listenerError = new Error(\n \"Managed websocket message listener failed\"\n );\n closeAndSettle(NORMAL_CLOSE_CODE, \"listener failed\");\n }\n };\n\n const onError = (_event: StarciteWebSocketEventMap[\"error\"]): void => {\n // Browsers may dispatch `error` before `close`; mark transport as non-graceful.\n sawTransportError = true;\n };\n\n const onClose = (event: StarciteWebSocketCloseEvent): void => {\n closeCode = event.code;\n closeReason = event.reason;\n settle();\n };\n\n const onAbort = (): void => {\n // Abort is treated as local shutdown and ends reconnect attempts immediately.\n this.closed = true;\n closeAndSettle(NORMAL_CLOSE_CODE, \"aborted\", true);\n };\n\n this.forceCloseSocket = (code, reason, markAborted) => {\n closeAndSettle(code, reason, markAborted ?? false);\n };\n\n socket.addEventListener(\"open\", onOpen);\n socket.addEventListener(\"message\", onMessage);\n socket.addEventListener(\"error\", onError);\n socket.addEventListener(\"close\", onClose);\n this.options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n armConnectionTimeout();\n });\n }\n\n private emitSafe(\n eventName: keyof ManagedWebSocketEvents,\n payload?: unknown\n ): boolean {\n // Keep this cast local: EventEmitter3's generic typing does not model\n // dynamic keyed payload tuples well for this usage.\n const emitter = this as unknown as EventEmitter<\n Record<string, (...args: unknown[]) => void>\n >;\n\n try {\n if (payload === undefined) {\n emitter.emit(eventName);\n } else {\n emitter.emit(eventName, payload);\n }\n return true;\n } catch (error) {\n if (eventName !== \"fatal\") {\n emitter.emit(\"fatal\", error);\n }\n return false;\n }\n }\n\n private finish(event: {\n closeCode?: number;\n closeReason?: string;\n aborted: boolean;\n graceful: boolean;\n }): void {\n if (this.resolveDone === undefined) {\n return;\n }\n\n // Emit final state before cleanup so `TailStream` can observe close reason.\n this.emit(\"closed\", event);\n this.removeAllListeners();\n const resolve = this.resolveDone;\n this.resolveDone = undefined;\n resolve();\n }\n}\n\nfunction reconnectDelayForAttempt(\n attempt: number,\n policy: ReconnectPolicy\n): number {\n const exponent = Math.max(0, attempt - 1);\n const baseDelay = policy.initialDelayMs * policy.multiplier ** exponent;\n const clamped = Math.min(policy.maxDelayMs, baseDelay);\n\n if (policy.jitterRatio <= 0) {\n return clamped;\n }\n\n const spread = clamped * policy.jitterRatio;\n const min = Math.max(0, clamped - spread);\n const max = clamped + spread;\n return min + Math.random() * (max - min);\n}\n\nfunction waitForDelay(\n ms: number,\n signal: AbortSignal | undefined\n): { promise: Promise<void>; cancel: () => void } {\n if (ms <= 0 || signal?.aborted) {\n return {\n promise: Promise.resolve(),\n cancel: () => undefined,\n };\n }\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let settled = false;\n let resolvePromise: (() => void) | undefined;\n\n const onAbort = (): void => {\n finish();\n };\n\n const finish = (): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n signal?.removeEventListener(\"abort\", onAbort);\n resolvePromise?.();\n resolvePromise = undefined;\n };\n\n const promise = new Promise<void>((resolve) => {\n resolvePromise = resolve;\n\n // Reconnect backoff is abortable so shutdown does not wait out timers.\n timer = setTimeout(() => {\n finish();\n }, ms);\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n return {\n promise,\n cancel: finish,\n };\n}\n\nfunction closeQuietly(\n socket: StarciteWebSocket,\n code: number,\n reason: string\n): void {\n try {\n socket.close(code, reason);\n } catch {\n // Ignore close transport errors during shutdown.\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import {\n StarciteBackpressureError,\n StarciteRetryLimitError,\n StarciteTailError,\n StarciteTokenExpiredError,\n} from \"../errors\";\nimport { agentFromActor } from \"../identity\";\nimport type {\n SessionTailOptions,\n StarciteWebSocket,\n TailEvent,\n TailLifecycleEvent,\n} from \"../types\";\nimport { parseTailFrame } from \"./frame\";\nimport { ManagedWebSocket } from \"./managed-websocket\";\n\nconst NORMAL_CLOSE_CODE = 1000;\n\ninterface ResolvedReconnectPolicy {\n mode: \"fixed\" | \"exponential\";\n initialDelayMs: number;\n maxDelayMs: number;\n multiplier: number;\n jitterRatio: number;\n maxAttempts: number;\n}\n\n/**\n * Stateful tail runner powered by a managed websocket loop.\n *\n * `cursor` is the reconnect checkpoint and advances with every parsed event.\n * Agent filtering affects emitted batches, not cursor advancement.\n * In non-follow mode, stream auto-closes after `catchUpIdleMs` of inactivity.\n */\nexport class TailStream {\n private readonly sessionId: string;\n private readonly token: string | undefined;\n private readonly websocketBaseUrl: string;\n private readonly websocketFactory: (url: string) => StarciteWebSocket;\n\n private readonly batchSize: number | undefined;\n private readonly agent: string | undefined;\n private readonly follow: boolean;\n private readonly shouldReconnect: boolean;\n private readonly reconnectPolicy: ResolvedReconnectPolicy;\n private readonly catchUpIdleMs: number;\n private readonly connectionTimeoutMs: number;\n private readonly inactivityTimeoutMs: number | undefined;\n private readonly maxBufferedBatches: number;\n private readonly signal: AbortSignal | undefined;\n private readonly onLifecycleEvent:\n | ((event: TailLifecycleEvent) => void)\n | undefined;\n\n private cursor: number;\n\n constructor(input: {\n sessionId: string;\n token: string | undefined;\n websocketBaseUrl: string;\n websocketFactory: (url: string) => StarciteWebSocket;\n options: SessionTailOptions;\n }) {\n const opts = input.options;\n const follow = opts.follow ?? true;\n const policy = opts.reconnectPolicy;\n const mode: \"fixed\" | \"exponential\" =\n policy?.mode === \"fixed\" ? \"fixed\" : \"exponential\";\n const initialDelayMs = policy?.initialDelayMs ?? 500;\n\n this.sessionId = input.sessionId;\n this.token = input.token;\n this.websocketBaseUrl = input.websocketBaseUrl;\n this.websocketFactory = input.websocketFactory;\n\n this.cursor = opts.cursor ?? 0;\n this.batchSize = opts.batchSize;\n this.agent = opts.agent?.trim();\n this.follow = follow;\n // Catch-up mode (`follow: false`) is single-pass and never reconnects.\n this.shouldReconnect = follow ? (opts.reconnect ?? true) : false;\n this.catchUpIdleMs = opts.catchUpIdleMs ?? 1000;\n this.connectionTimeoutMs = opts.connectionTimeoutMs ?? 4000;\n this.inactivityTimeoutMs = opts.inactivityTimeoutMs;\n this.maxBufferedBatches = opts.maxBufferedBatches ?? 1024;\n this.signal = opts.signal;\n this.onLifecycleEvent = opts.onLifecycleEvent;\n\n this.reconnectPolicy = {\n mode,\n initialDelayMs,\n maxDelayMs:\n policy?.maxDelayMs ??\n (mode === \"fixed\" ? initialDelayMs : Math.max(initialDelayMs, 15_000)),\n multiplier: mode === \"fixed\" ? 1 : (policy?.multiplier ?? 2),\n jitterRatio: policy?.jitterRatio ?? 0.2,\n maxAttempts: policy?.maxAttempts ?? Number.POSITIVE_INFINITY,\n };\n }\n\n /**\n * Pushes batches to a callback, enabling emitter-style consumers.\n */\n async subscribe(\n onBatch: (batch: TailEvent[]) => void | Promise<void>\n ): Promise<void> {\n await this.subscribeWithSignal(onBatch, this.signal);\n }\n\n private async subscribeWithSignal(\n onBatch: (batch: TailEvent[]) => void | Promise<void>,\n signal: AbortSignal | undefined\n ): Promise<void> {\n // Shared run state: one terminal error + one terminal reason for the whole subscription.\n let streamError: unknown;\n let streamReason: \"aborted\" | \"caught_up\" | \"graceful\" = this.follow\n ? \"graceful\"\n : \"caught_up\";\n let queuedBatches = 0;\n let catchUpTimer: ReturnType<typeof setTimeout> | undefined;\n let dispatchChain: Promise<void> = Promise.resolve();\n\n const stream = new ManagedWebSocket({\n // URL is re-read per attempt by `ManagedWebSocket` and reflects current cursor.\n url: () => this.buildTailUrl(),\n websocketFactory: this.websocketFactory,\n signal,\n shouldReconnect: this.shouldReconnect,\n reconnectPolicy: {\n initialDelayMs: this.reconnectPolicy.initialDelayMs,\n maxDelayMs: this.reconnectPolicy.maxDelayMs,\n multiplier: this.reconnectPolicy.multiplier,\n jitterRatio: this.reconnectPolicy.jitterRatio,\n maxAttempts: this.reconnectPolicy.maxAttempts,\n },\n connectionTimeoutMs: this.connectionTimeoutMs,\n inactivityTimeoutMs: this.inactivityTimeoutMs,\n });\n\n const fail = (error: unknown): void => {\n // First terminal error wins; subsequent errors are ignored.\n if (streamError !== undefined) {\n return;\n }\n streamError = error;\n stream.close(NORMAL_CLOSE_CODE, \"stream failed\");\n };\n\n const emitLifecycle = (event: TailLifecycleEvent): void => {\n if (!this.onLifecycleEvent) {\n return;\n }\n\n try {\n // Lifecycle callbacks are part of control flow; failures are terminal.\n this.onLifecycleEvent(event);\n } catch (error) {\n fail(error);\n }\n };\n\n const clearCatchUpTimer = (): void => {\n if (catchUpTimer) {\n clearTimeout(catchUpTimer);\n catchUpTimer = undefined;\n }\n };\n\n const scheduleCatchUpClose = (): void => {\n if (this.follow) {\n return;\n }\n\n // Non-follow mode closes once no frames arrive for `catchUpIdleMs`.\n clearCatchUpTimer();\n catchUpTimer = setTimeout(() => {\n streamReason = \"caught_up\";\n stream.close(NORMAL_CLOSE_CODE, \"caught up\");\n }, this.catchUpIdleMs);\n };\n\n const dispatchBatch = (batch: TailEvent[]): void => {\n if (streamError !== undefined) {\n return;\n }\n\n // Backpressure is measured as unresolved consumer callbacks.\n if (\n this.maxBufferedBatches > 0 &&\n queuedBatches > this.maxBufferedBatches\n ) {\n fail(\n new StarciteBackpressureError(\n `Tail consumer for session '${this.sessionId}' fell behind after buffering ${this.maxBufferedBatches} batch(es)`,\n { sessionId: this.sessionId, attempts: 0 }\n )\n );\n return;\n }\n\n queuedBatches += 1;\n // Serialize consumer callbacks: preserves order and keeps backpressure measurable.\n dispatchChain = dispatchChain\n .then(async () => {\n try {\n await onBatch(batch);\n } finally {\n queuedBatches -= 1;\n }\n })\n .catch((error) => {\n fail(error);\n });\n };\n\n // Translate low-level transport lifecycle into SDK lifecycle + domain errors.\n const onConnectAttempt = (event: { attempt: number }): void => {\n emitLifecycle({\n type: \"connect_attempt\",\n sessionId: this.sessionId,\n attempt: event.attempt,\n cursor: this.cursor,\n });\n };\n\n const onConnectFailed = (event: {\n attempt: number;\n rootCause: string;\n }): void => {\n // Without reconnect, first dial failure is terminal for the subscription.\n if (!this.shouldReconnect) {\n fail(\n new StarciteTailError(\n `Tail connection failed for session '${this.sessionId}': ${event.rootCause}`,\n {\n sessionId: this.sessionId,\n stage: \"connect\",\n attempts: event.attempt - 1,\n }\n )\n );\n }\n };\n\n const onReconnectScheduled = (event: {\n attempt: number;\n delayMs: number;\n trigger: \"connect_failed\" | \"dropped\";\n closeCode?: number;\n closeReason?: string;\n }): void => {\n emitLifecycle({\n type: \"reconnect_scheduled\",\n sessionId: this.sessionId,\n attempt: event.attempt,\n delayMs: event.delayMs,\n trigger: event.trigger,\n closeCode: event.closeCode,\n closeReason: event.closeReason,\n });\n };\n\n const onDropped = (event: {\n attempt: number;\n closeCode?: number;\n closeReason?: string;\n }): void => {\n // Auth expiry is non-recoverable with current token; surface explicit domain error.\n if (event.closeCode === 4001 || event.closeReason === \"token_expired\") {\n fail(\n new StarciteTokenExpiredError(\n `Tail token expired for session '${this.sessionId}'. Re-issue a session token and reconnect from the last processed cursor.`,\n {\n sessionId: this.sessionId,\n attempts: event.attempt,\n closeCode: event.closeCode,\n closeReason: event.closeReason,\n }\n )\n );\n return;\n }\n\n emitLifecycle({\n type: \"stream_dropped\",\n sessionId: this.sessionId,\n attempt: event.attempt,\n closeCode: event.closeCode,\n closeReason: event.closeReason,\n });\n\n if (!this.shouldReconnect) {\n // In no-reconnect mode, any drop is terminal and includes close metadata.\n fail(\n new StarciteTailError(\n `Tail connection dropped for session '${this.sessionId}' (${describeClose(event.closeCode, event.closeReason)})`,\n {\n sessionId: this.sessionId,\n stage: \"stream\",\n attempts: event.attempt - 1,\n closeCode: event.closeCode,\n closeReason: event.closeReason,\n }\n )\n );\n }\n };\n\n const onRetryLimit = (event: {\n attempt: number;\n trigger: \"connect_failed\" | \"dropped\";\n closeCode?: number;\n closeReason?: string;\n rootCause?: string;\n }): void => {\n // Retry limit unifies terminal error reporting for both connect and drop failures.\n const message =\n event.trigger === \"connect_failed\"\n ? `Tail connection failed for session '${this.sessionId}' after ${this.reconnectPolicy.maxAttempts} reconnect attempt(s): ${event.rootCause ?? \"Unknown error\"}`\n : `Tail connection dropped for session '${this.sessionId}' after ${this.reconnectPolicy.maxAttempts} reconnect attempt(s) (${describeClose(event.closeCode, event.closeReason)})`;\n\n fail(\n new StarciteRetryLimitError(message, {\n sessionId: this.sessionId,\n attempts: event.attempt,\n closeCode: event.closeCode,\n closeReason: event.closeReason,\n })\n );\n };\n\n const onOpen = (): void => {\n // Re-arm catch-up detection after each successful (re)connect.\n scheduleCatchUpClose();\n };\n\n const onMessage = (data: unknown): void => {\n try {\n const parsedEvents = parseTailFrame(data);\n const matchingEvents: TailEvent[] = [];\n\n for (const parsedEvent of parsedEvents) {\n // Cursor advances for every parsed event, even if filtered out by agent.\n this.cursor = Math.max(this.cursor, parsedEvent.seq);\n\n if (this.agent && agentFromActor(parsedEvent.actor) !== this.agent) {\n continue;\n }\n\n matchingEvents.push(parsedEvent);\n }\n\n if (matchingEvents.length > 0) {\n // A successfully delivered batch proves the stream is healthy again.\n stream.resetReconnectAttempts();\n dispatchBatch(matchingEvents);\n }\n\n scheduleCatchUpClose();\n } catch (error) {\n fail(error);\n }\n };\n\n const onFatal = (error: unknown): void => {\n fail(error);\n };\n\n const onClosed = (event: { aborted: boolean; graceful: boolean }): void => {\n clearCatchUpTimer();\n // Map transport terminal state into SDK-level stream reason.\n if (event.aborted) {\n streamReason = \"aborted\";\n return;\n }\n\n if (!this.follow) {\n streamReason = \"caught_up\";\n return;\n }\n\n if (event.graceful) {\n streamReason = \"graceful\";\n }\n };\n\n stream.on(\"connect_attempt\", onConnectAttempt);\n stream.on(\"connect_failed\", onConnectFailed);\n stream.on(\"reconnect_scheduled\", onReconnectScheduled);\n stream.on(\"dropped\", onDropped);\n stream.on(\"retry_limit\", onRetryLimit);\n stream.on(\"open\", onOpen);\n stream.on(\"message\", onMessage);\n stream.on(\"fatal\", onFatal);\n stream.on(\"closed\", onClosed);\n\n try {\n await stream.waitForClose();\n clearCatchUpTimer();\n // Drain in-flight consumer callbacks before returning/throwing.\n await dispatchChain;\n\n // Transport finished, but callback processing may already have failed.\n if (streamError !== undefined) {\n throw streamError;\n }\n\n emitLifecycle({\n type: \"stream_ended\",\n sessionId: this.sessionId,\n reason: streamReason,\n });\n\n // Lifecycle callbacks can fail and convert clean transport completion into failure.\n if (streamError !== undefined) {\n throw streamError;\n }\n } finally {\n clearCatchUpTimer();\n stream.off(\"connect_attempt\", onConnectAttempt);\n stream.off(\"connect_failed\", onConnectFailed);\n stream.off(\"reconnect_scheduled\", onReconnectScheduled);\n stream.off(\"dropped\", onDropped);\n stream.off(\"retry_limit\", onRetryLimit);\n stream.off(\"open\", onOpen);\n stream.off(\"message\", onMessage);\n stream.off(\"fatal\", onFatal);\n stream.off(\"closed\", onClosed);\n stream.close(NORMAL_CLOSE_CODE, \"finished\");\n }\n }\n\n private buildTailUrl(): string {\n // Cursor is always included so reconnect resumes from last observed sequence.\n const query = new URLSearchParams({ cursor: `${this.cursor}` });\n\n if (this.batchSize !== undefined) {\n query.set(\"batch_size\", `${this.batchSize}`);\n }\n\n if (this.token) {\n query.set(\"access_token\", this.token);\n }\n\n return `${this.websocketBaseUrl}/sessions/${encodeURIComponent(\n this.sessionId\n )}/tail?${query.toString()}`;\n }\n}\n\nfunction describeClose(\n code: number | undefined,\n reason: string | undefined\n): string {\n const codeText = `code ${code ?? \"unknown\"}`;\n return reason ? `${codeText}, reason '${reason}'` : codeText;\n}\n","import type { z } from \"zod\";\nimport {\n StarciteApiError,\n StarciteConnectionError,\n StarciteError,\n} from \"./errors\";\nimport type { StarciteWebSocket } from \"./types\";\n\nconst TRAILING_SLASHES_REGEX = /\\/+$/;\n\n/**\n * Shared HTTP + WebSocket transport configuration.\n *\n * Both `Starcite` (API-key auth) and `StarciteSession` (session-token auth)\n * hold their own `TransportConfig` and pass it to the free functions below.\n */\nexport interface TransportConfig {\n readonly baseUrl: string;\n readonly websocketBaseUrl: string;\n readonly authorization: string | null;\n readonly fetchFn: typeof fetch;\n readonly headers: Headers;\n readonly websocketFactory: (url: string) => StarciteWebSocket;\n}\n\n/**\n * Validates and normalizes an absolute HTTP URL used for SDK endpoints.\n */\nexport function normalizeAbsoluteHttpUrl(\n value: string,\n context: string\n): string {\n const parsed = new URL(value);\n\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw new StarciteError(`${context} must use http:// or https://`);\n }\n\n // Strip trailing slashes for consistent path joining.\n return parsed.toString().replace(TRAILING_SLASHES_REGEX, \"\");\n}\n\n/**\n * Converts a Starcite base URL to the `/v1` API root used by this SDK.\n */\nexport function toApiBaseUrl(baseUrl: string): string {\n const normalized = normalizeAbsoluteHttpUrl(baseUrl, \"baseUrl\");\n return normalized.endsWith(\"/v1\") ? normalized : `${normalized}/v1`;\n}\n\n/**\n * Converts HTTP API base URL to its websocket equivalent.\n */\nexport function toWebSocketBaseUrl(apiBaseUrl: string): string {\n const url = new URL(apiBaseUrl);\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return url.toString().replace(TRAILING_SLASHES_REGEX, \"\");\n}\n\n/**\n * Default websocket connector used when no custom factory is provided.\n */\nexport function defaultWebSocketFactory(url: string): StarciteWebSocket {\n if (typeof WebSocket === \"undefined\") {\n throw new StarciteError(\n \"WebSocket is not available in this runtime. Provide websocketFactory in StarciteOptions.\"\n );\n }\n\n return new WebSocket(url);\n}\n\n/**\n * Makes an HTTP request against the transport's base URL.\n */\nexport function request<T>(\n transport: TransportConfig,\n path: string,\n init: RequestInit,\n schema: z.ZodType<T>\n): Promise<T> {\n return requestWithBaseUrl(transport, transport.baseUrl, path, init, schema);\n}\n\n/**\n * Makes an HTTP request against an arbitrary base URL using the transport's shared config.\n */\nexport async function requestWithBaseUrl<T>(\n transport: TransportConfig,\n baseUrl: string,\n path: string,\n init: RequestInit,\n schema: z.ZodType<T>\n): Promise<T> {\n const headers = new Headers(transport.headers);\n\n if (transport.authorization) {\n headers.set(\"authorization\", transport.authorization);\n }\n\n if (init.body !== undefined && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n if (init.headers) {\n const perRequestHeaders = new Headers(init.headers);\n for (const [key, value] of perRequestHeaders.entries()) {\n headers.set(key, value);\n }\n }\n\n let response: Response;\n\n try {\n response = await transport.fetchFn(`${baseUrl}${path}`, {\n ...init,\n headers,\n });\n } catch (error) {\n throw new StarciteConnectionError(\n `Failed to connect to Starcite at ${baseUrl}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!response.ok) {\n let payload: Record<string, unknown> | null = null;\n try {\n payload = (await response.json()) as Record<string, unknown>;\n } catch {\n // Non-JSON error response — fall through with null payload.\n }\n\n const code =\n typeof payload?.error === \"string\"\n ? payload.error\n : `http_${response.status}`;\n const message =\n typeof payload?.message === \"string\"\n ? payload.message\n : response.statusText;\n\n throw new StarciteApiError(message, response.status, code, payload);\n }\n\n if (response.status === 204) {\n return schema.parse(undefined);\n }\n\n let body: unknown;\n try {\n body = await response.json();\n } catch (error) {\n throw new StarciteConnectionError(\n `Received invalid JSON from Starcite: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n return schema.parse(body);\n}\n","import type { SessionStore, SessionStoreState, TailEvent } from \"./types\";\n\nfunction cloneEvents(events: readonly TailEvent[]): TailEvent[] {\n // Store boundaries should not share mutable arrays across callers.\n return events.map((event) => structuredClone(event));\n}\n\nfunction cloneState(state: SessionStoreState): SessionStoreState {\n return {\n cursor: state.cursor,\n events: cloneEvents(state.events),\n };\n}\n\n/**\n * Default in-memory session store.\n *\n * Persists both cursor and retained events for each session so late subscribers\n * can replay immediately after process-local reconnect/rebind.\n */\nexport class MemoryStore implements SessionStore {\n private readonly sessions = new Map<string, SessionStoreState>();\n\n load(sessionId: string): SessionStoreState | undefined {\n const stored = this.sessions.get(sessionId);\n return stored ? cloneState(stored) : undefined;\n }\n\n save(sessionId: string, state: SessionStoreState): void {\n this.sessions.set(sessionId, cloneState(state));\n }\n\n clear(sessionId: string): void {\n this.sessions.delete(sessionId);\n }\n}\n","import {\n decodeSessionToken,\n inferIdentityFromApiKey,\n inferIssuerAuthorityFromApiKey,\n} from \"./auth\";\nimport { StarciteError } from \"./errors\";\nimport { StarciteIdentity } from \"./identity\";\nimport { StarciteSession } from \"./session\";\nimport { MemoryStore } from \"./session-store\";\nimport type { TransportConfig } from \"./transport\";\nimport {\n defaultWebSocketFactory,\n normalizeAbsoluteHttpUrl,\n request,\n requestWithBaseUrl,\n toApiBaseUrl,\n toWebSocketBaseUrl,\n} from \"./transport\";\nimport type {\n IssueSessionTokenInput,\n RequestOptions,\n SessionListOptions,\n SessionListPage,\n SessionLogOptions,\n SessionRecord,\n SessionStore,\n StarciteOptions,\n} from \"./types\";\nimport {\n IssueSessionTokenResponseSchema,\n SessionListOptionsSchema,\n SessionListPageSchema,\n SessionRecordSchema,\n} from \"./types\";\n\nconst DEFAULT_BASE_URL =\n globalThis.process?.env?.STARCITE_BASE_URL ?? \"http://localhost:4000\";\nconst DEFAULT_AUTH_URL = globalThis.process?.env?.STARCITE_AUTH_URL;\n\n/**\n * Resolves auth issuer base URL in this order:\n * explicit option -> env -> API key JWT issuer authority.\n */\nfunction resolveAuthBaseUrl(\n explicitAuthUrl: string | undefined,\n apiKey: string | undefined\n): string | undefined {\n if (explicitAuthUrl) {\n return normalizeAbsoluteHttpUrl(explicitAuthUrl, \"authUrl\");\n }\n\n if (DEFAULT_AUTH_URL) {\n return normalizeAbsoluteHttpUrl(DEFAULT_AUTH_URL, \"STARCITE_AUTH_URL\");\n }\n\n if (apiKey) {\n return inferIssuerAuthorityFromApiKey(apiKey);\n }\n\n return undefined;\n}\n\n/**\n * Tenant-scoped Starcite client.\n *\n * Create identities with {@link user} / {@link agent}, then bind them to\n * sessions with {@link session}.\n */\nexport class Starcite {\n /** Normalized API base URL ending with `/v1`. */\n readonly baseUrl: string;\n\n private readonly transport: TransportConfig;\n private readonly authBaseUrl?: string;\n private readonly inferredIdentity?: StarciteIdentity;\n private readonly store: SessionStore;\n\n constructor(options: StarciteOptions = {}) {\n const baseUrl = toApiBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL);\n this.baseUrl = baseUrl;\n\n const userFetch = options.fetch;\n const fetchFn: typeof fetch = userFetch\n ? (input, init) => userFetch(input, init)\n : (input, init) => fetch(input, init);\n const headers = new Headers(options.headers);\n const apiKey = options.apiKey?.trim();\n let authorization: string | undefined;\n\n if (apiKey) {\n authorization = `Bearer ${apiKey}`;\n this.inferredIdentity = inferIdentityFromApiKey(apiKey);\n }\n\n this.authBaseUrl = resolveAuthBaseUrl(options.authUrl, apiKey);\n\n const websocketFactory =\n options.websocketFactory ?? defaultWebSocketFactory;\n this.store = options.store ?? new MemoryStore();\n\n this.transport = {\n baseUrl,\n websocketBaseUrl: toWebSocketBaseUrl(baseUrl),\n authorization: authorization ?? null,\n fetchFn,\n headers,\n websocketFactory,\n };\n }\n\n /**\n * Creates a user identity bound to this client's tenant.\n */\n user(options: { id: string }): StarciteIdentity {\n return new StarciteIdentity({\n tenantId: this.requireTenantId(\"user()\"),\n id: options.id,\n type: \"user\",\n });\n }\n\n /**\n * Creates an agent identity bound to this client's tenant.\n */\n agent(options: { id: string }): StarciteIdentity {\n return new StarciteIdentity({\n tenantId: this.requireTenantId(\"agent()\"),\n id: options.id,\n type: \"agent\",\n });\n }\n\n /**\n * Creates or binds to a session.\n *\n * **With identity** (backend): creates a new session and/or mints a session\n * token for the given identity. Pass `id` to bind to an existing session.\n *\n * **With token** (frontend): wraps an existing session token. The identity\n * and session id are decoded from the JWT.\n */\n session(input: {\n token: string;\n logOptions?: SessionLogOptions;\n }): StarciteSession;\n session(input: {\n identity: StarciteIdentity;\n id?: string;\n title?: string;\n metadata?: Record<string, unknown>;\n logOptions?: SessionLogOptions;\n }): Promise<StarciteSession>;\n session(\n input:\n | { token: string; logOptions?: SessionLogOptions }\n | {\n identity: StarciteIdentity;\n id?: string;\n title?: string;\n metadata?: Record<string, unknown>;\n logOptions?: SessionLogOptions;\n }\n ): StarciteSession | Promise<StarciteSession> {\n if (\"token\" in input) {\n return this.sessionFromToken(input.token, input.logOptions);\n }\n\n return this.sessionFromIdentity(input);\n }\n\n /**\n * Lists sessions from the archive-backed catalog.\n */\n listSessions(\n options: SessionListOptions = {},\n requestOptions?: RequestOptions\n ): Promise<SessionListPage> {\n const parsed = SessionListOptionsSchema.parse(options);\n const query = new URLSearchParams();\n\n if (parsed.limit !== undefined) {\n query.set(\"limit\", `${parsed.limit}`);\n }\n\n if (parsed.cursor !== undefined) {\n query.set(\"cursor\", parsed.cursor);\n }\n\n if (parsed.metadata !== undefined) {\n for (const [key, value] of Object.entries(parsed.metadata)) {\n query.set(`metadata.${key}`, value);\n }\n }\n\n const suffix = query.size > 0 ? `?${query.toString()}` : \"\";\n\n return request(\n this.transport,\n `/sessions${suffix}`,\n {\n method: \"GET\",\n signal: requestOptions?.signal,\n },\n SessionListPageSchema\n );\n }\n\n private async sessionFromIdentity(input: {\n identity: StarciteIdentity;\n id?: string;\n title?: string;\n metadata?: Record<string, unknown>;\n logOptions?: SessionLogOptions;\n }): Promise<StarciteSession> {\n let sessionId = input.id;\n let record: SessionRecord | undefined;\n\n if (!sessionId) {\n record = await this.createSession({\n creator_principal: input.identity.toCreatorPrincipal(),\n title: input.title,\n metadata: input.metadata,\n });\n sessionId = record.id;\n }\n\n const tokenResponse = await this.issueSessionToken({\n session_id: sessionId,\n principal: input.identity.toTokenPrincipal(),\n scopes: [\"session:read\", \"session:append\"],\n });\n\n return new StarciteSession({\n id: sessionId,\n token: tokenResponse.token,\n identity: input.identity,\n transport: this.buildSessionTransport(tokenResponse.token),\n store: this.store,\n record,\n logOptions: input.logOptions,\n });\n }\n\n private sessionFromToken(\n token: string,\n logOptions?: SessionLogOptions\n ): StarciteSession {\n const decoded = decodeSessionToken(token);\n const sessionId = decoded.sessionId;\n\n if (!sessionId) {\n throw new StarciteError(\n \"session({ token }) requires a token with a session_id claim.\"\n );\n }\n\n return new StarciteSession({\n id: sessionId,\n token,\n identity: decoded.identity,\n transport: this.buildSessionTransport(token),\n store: this.store,\n logOptions,\n });\n }\n\n private buildSessionTransport(token: string): TransportConfig {\n return {\n ...this.transport,\n authorization: `Bearer ${token}`,\n };\n }\n\n private createSession(input: {\n creator_principal?: { tenant_id: string; id: string; type: string };\n title?: string;\n metadata?: Record<string, unknown>;\n }): Promise<SessionRecord> {\n return request(\n this.transport,\n \"/sessions\",\n {\n method: \"POST\",\n body: JSON.stringify(input),\n },\n SessionRecordSchema\n );\n }\n\n private issueSessionToken(\n input: IssueSessionTokenInput\n ): Promise<{ token: string; expires_in: number }> {\n if (!this.transport.authorization) {\n throw new StarciteError(\n \"session() with identity requires apiKey. Set StarciteOptions.apiKey.\"\n );\n }\n\n if (!this.authBaseUrl) {\n throw new StarciteError(\n \"session() could not resolve auth issuer URL. Set StarciteOptions.authUrl, STARCITE_AUTH_URL, or use an API key JWT with an 'iss' claim.\"\n );\n }\n\n return requestWithBaseUrl(\n this.transport,\n this.authBaseUrl,\n \"/api/v1/session-tokens\",\n {\n method: \"POST\",\n headers: {\n \"cache-control\": \"no-store\",\n },\n body: JSON.stringify(input),\n },\n IssueSessionTokenResponseSchema\n );\n }\n\n private requireTenantId(method: string): string {\n const tenantId = this.inferredIdentity?.tenantId;\n if (!tenantId) {\n throw new StarciteError(`${method} requires apiKey to determine tenant.`);\n }\n return tenantId;\n }\n}\n","import { StarciteError } from \"./errors\";\nimport type { SessionCursorStore } from \"./types\";\n\nconst DEFAULT_KEY_PREFIX = \"starcite\";\n\n/**\n * Minimal Web Storage contract used by {@link WebStorageCursorStore}.\n */\nexport interface StarciteWebStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\n/**\n * Key customization options for storage-backed cursor stores.\n */\nexport interface CursorStoreOptions {\n /**\n * Prefix used when deriving storage keys.\n *\n * Defaults to `\"starcite\"`.\n */\n keyPrefix?: string;\n /**\n * Custom key resolver. When provided it overrides `keyPrefix`.\n */\n keyForSession?: (sessionId: string) => string;\n}\n\n/**\n * In-memory cursor store (useful for workers/tests).\n */\nexport class InMemoryCursorStore implements SessionCursorStore {\n private readonly cursors: Map<string, number>;\n\n constructor(initial: Record<string, number> = {}) {\n this.cursors = new Map(Object.entries(initial));\n }\n\n load(sessionId: string): number | undefined {\n return this.cursors.get(sessionId);\n }\n\n save(sessionId: string, cursor: number): void {\n this.cursors.set(sessionId, cursor);\n }\n}\n\n/**\n * Cursor store backed by a Web Storage-compatible object.\n */\nexport class WebStorageCursorStore implements SessionCursorStore {\n private readonly storage: StarciteWebStorage;\n private readonly keyForSession: (sessionId: string) => string;\n\n constructor(storage: StarciteWebStorage, options: CursorStoreOptions = {}) {\n this.storage = storage;\n const prefix = options.keyPrefix?.trim() || DEFAULT_KEY_PREFIX;\n this.keyForSession =\n options.keyForSession ??\n ((sessionId) => `${prefix}:${sessionId}:lastSeq`);\n }\n\n load(sessionId: string): number | undefined {\n const raw = this.storage.getItem(this.keyForSession(sessionId));\n if (raw === null) {\n return undefined;\n }\n const parsed = Number.parseInt(raw, 10);\n return Number.isInteger(parsed) && parsed >= 0 ? parsed : undefined;\n }\n\n save(sessionId: string, cursor: number): void {\n this.storage.setItem(this.keyForSession(sessionId), `${cursor}`);\n }\n}\n\n/**\n * Cursor store backed by `globalThis.localStorage`.\n */\nexport class LocalStorageCursorStore extends WebStorageCursorStore {\n constructor(options: CursorStoreOptions = {}) {\n if (typeof localStorage === \"undefined\") {\n throw new StarciteError(\n \"localStorage is not available in this runtime. Use WebStorageCursorStore with a custom storage adapter.\"\n );\n }\n super(localStorage, options);\n }\n}\n"],"mappings":"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","names":["z","z","EventEmitter","z","z","SessionCreatorPrincipalSchema","SessionTokenPrincipalSchema","z","z","EventEmitter","shouldContinue","NORMAL_CLOSE_CODE","EventEmitter"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starcite/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "TypeScript SDK for Starcite",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://starcite.ai",
|
|
@@ -37,22 +37,34 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"clean": "rm -rf dist",
|
|
39
39
|
"build": "tsup",
|
|
40
|
-
"test": "vitest run",
|
|
40
|
+
"test": "vitest run --config vitest.config.ts",
|
|
41
|
+
"test:live": "vitest run --config vitest.config.ts test/live.api.integration.test.ts",
|
|
42
|
+
"test:browser": "vitest run --config vitest.browser.config.ts --browser.name=chromium",
|
|
43
|
+
"test:browser:chromium": "vitest run --config vitest.browser.config.ts --browser.name=chromium",
|
|
44
|
+
"test:browser:firefox": "vitest run --config vitest.browser.config.ts --browser.name=firefox",
|
|
45
|
+
"test:browser:webkit": "vitest run --config vitest.browser.config.ts --browser.name=webkit",
|
|
46
|
+
"test:browser:all": "bun run test:browser:chromium && bun run test:browser:firefox && bun run test:browser:webkit",
|
|
41
47
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
42
48
|
"prepublishOnly": "bun run clean && bun run build",
|
|
43
49
|
"publish:dry": "bun publish --dry-run --access public",
|
|
44
50
|
"lint": "ultracite check src test package.json tsconfig.json tsup.config.ts README.md",
|
|
45
51
|
"format": "ultracite fix src test package.json tsconfig.json tsup.config.ts README.md",
|
|
46
|
-
"check": "bun run lint && bun run typecheck && bun run test"
|
|
52
|
+
"check": "bun run lint && bun run typecheck && bun run test",
|
|
53
|
+
"check:browser": "bun run typecheck && bun run test && bun run test:browser",
|
|
54
|
+
"check:browser:all": "bun run typecheck && bun run test && bun run test:browser:all"
|
|
47
55
|
},
|
|
48
56
|
"devDependencies": {
|
|
49
57
|
"@types/node": "^22.15.30",
|
|
58
|
+
"@vitest/browser": "2.1.9",
|
|
59
|
+
"playwright": "^1.58.2",
|
|
50
60
|
"tsup": "^8.5.0",
|
|
51
61
|
"typescript": "^5.8.3",
|
|
52
62
|
"vitest": "^2.1.9",
|
|
53
63
|
"ws": "^8.19.0"
|
|
54
64
|
},
|
|
55
65
|
"dependencies": {
|
|
66
|
+
"eventemitter3": "^5.0.1",
|
|
67
|
+
"jose": "^6.1.3",
|
|
56
68
|
"zod": "^3.25.76"
|
|
57
69
|
}
|
|
58
70
|
}
|