@tipsy-studio/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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bridge.ts","../src/react.ts"],"names":["createContext","useMemo","useState","useRef","useEffect","createElement","useContext"],"mappings":"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","file":"react.cjs","sourcesContent":["export const TIPSY_BRIDGE_PROTOCOL = \"tipsy-bridge-v1\";\nexport const TIPSY_INIT_RETRY_MS = 500;\nexport const CHAT_COMPLETIONS_METHOD = \"chat.completions\";\n\ntype TipsyBridgeMessageType =\n | \"tipsy:init\"\n | \"tipsy:init:ack\"\n | \"tipsy:request\"\n | \"tipsy:stream\"\n | \"tipsy:response\"\n | \"tipsy:error\"\n | \"tipsy:abort\";\n\ntype TipsyRole = \"system\" | \"user\" | \"assistant\";\n\nexport type TipsyChatMessage = {\n role: TipsyRole;\n content: string;\n};\n\nexport type TipsyChatCompletionInput = {\n messages: TipsyChatMessage[];\n stream: true;\n};\n\nexport type TipsyChatCompletionRawChunk = {\n type?: string;\n choices?: Array<{\n delta?: {\n content?: string;\n reasoning?: string;\n };\n }>;\n isFinished?: boolean;\n [key: string]: unknown;\n};\n\nexport type TipsyChatCompletionChunk = {\n type: \"stream\";\n chunk: string;\n raw: TipsyChatCompletionRawChunk;\n isFinished: false;\n};\n\nexport type TipsyChatCompletionResult = {\n type: \"done\";\n raw: TipsyChatCompletionRawChunk;\n isFinished: true;\n};\n\nexport type TipsyBridgeErrorCode =\n | \"UNAUTHORIZED\"\n | \"BAD_REQUEST\"\n | \"NETWORK_ERROR\"\n | \"STREAM_PARSE_ERROR\"\n | \"ORIGIN_MISMATCH\"\n | \"UNSUPPORTED_METHOD\"\n | \"INTERNAL_ERROR\";\n\nexport type TipsyBridgeError = {\n code: TipsyBridgeErrorCode;\n message: string;\n};\n\nexport type TipsyBridgeRequestMap = {\n [CHAT_COMPLETIONS_METHOD]: TipsyChatCompletionInput;\n};\n\nexport type TipsyBridgeResponseMap = {\n [CHAT_COMPLETIONS_METHOD]: TipsyChatCompletionResult;\n};\n\nexport type TipsyInitMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:init\";\n};\n\ntype TipsyInitAckMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:init:ack\";\n};\n\nexport type TipsyRequestMessage<M extends keyof TipsyBridgeRequestMap> = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:request\";\n requestId: string;\n method: M;\n payload: TipsyBridgeRequestMap[M];\n};\n\ntype TipsyStreamMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:stream\";\n requestId: string;\n payload: TipsyChatCompletionChunk;\n};\n\ntype TipsyResponseMessage<M extends keyof TipsyBridgeResponseMap> = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:response\";\n requestId: string;\n payload: TipsyBridgeResponseMap[M];\n};\n\ntype TipsyErrorMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:error\";\n requestId?: string;\n error: TipsyBridgeError;\n};\n\nexport type TipsyAbortMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:abort\";\n requestId: string;\n};\n\nexport type TipsyBridgeMessage =\n | TipsyInitMessage\n | TipsyInitAckMessage\n | TipsyRequestMessage<keyof TipsyBridgeRequestMap>\n | TipsyStreamMessage\n | TipsyResponseMessage<keyof TipsyBridgeResponseMap>\n | TipsyErrorMessage\n | TipsyAbortMessage;\n\nexport type TipsyRequestController = {\n signal?: AbortSignal;\n};\n\nexport type TipsyChatCompletionController = TipsyRequestController & {\n onData?: (chunk: TipsyChatCompletionChunk) => void;\n onComplete?: (result: TipsyChatCompletionResult) => void;\n};\n\nexport class TipsyBridgeClientError extends Error {\n code: TipsyBridgeErrorCode;\n\n constructor(error: TipsyBridgeError) {\n super(error.message);\n this.name = \"TipsyBridgeClientError\";\n this.code = error.code;\n }\n}\n\nexport function getParentOriginFromReferrer(): string | null {\n if (typeof document === \"undefined\" || !document.referrer) {\n return null;\n }\n\n try {\n return new URL(document.referrer).origin;\n } catch {\n return null;\n }\n}\n\nexport function normalizeTargetOrigin(value?: string): string {\n if (value && value.trim()) {\n return value;\n }\n\n return getParentOriginFromReferrer() ?? \"*\";\n}\n\nexport function isBridgeMessage(value: unknown): value is TipsyBridgeMessage {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<TipsyBridgeMessage>;\n if (candidate.protocol !== TIPSY_BRIDGE_PROTOCOL) {\n return false;\n }\n\n const validTypes = new Set<TipsyBridgeMessageType>([\n \"tipsy:init\",\n \"tipsy:init:ack\",\n \"tipsy:request\",\n \"tipsy:stream\",\n \"tipsy:response\",\n \"tipsy:error\",\n \"tipsy:abort\",\n ]);\n\n return typeof candidate.type === \"string\" && validTypes.has(candidate.type);\n}\n\nexport function createRequestId() {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n\n return `tipsy_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n}\n","import {\n createElement,\n createContext,\n type PropsWithChildren,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n CHAT_COMPLETIONS_METHOD,\n TIPSY_BRIDGE_PROTOCOL,\n TIPSY_INIT_RETRY_MS,\n type TipsyAbortMessage,\n type TipsyBridgeError,\n type TipsyBridgeRequestMap,\n type TipsyBridgeResponseMap,\n type TipsyInitMessage,\n type TipsyRequestController,\n type TipsyRequestMessage,\n TipsyBridgeClientError,\n type TipsyChatCompletionChunk,\n type TipsyChatCompletionController,\n type TipsyChatCompletionInput,\n type TipsyChatCompletionResult,\n createRequestId,\n isBridgeMessage,\n normalizeTargetOrigin,\n} from \"./bridge\";\nexport {\n CHAT_COMPLETIONS_METHOD,\n TIPSY_BRIDGE_PROTOCOL,\n TipsyBridgeClientError,\n type TipsyAbortMessage,\n type TipsyBridgeError,\n type TipsyBridgeMessage,\n type TipsyBridgeRequestMap,\n type TipsyBridgeResponseMap,\n type TipsyChatCompletionChunk,\n type TipsyChatCompletionController,\n type TipsyChatCompletionInput,\n type TipsyChatCompletionRawChunk,\n type TipsyChatCompletionResult,\n type TipsyChatMessage,\n} from \"./bridge\";\n\nexport type TipsyStudioProviderProps = PropsWithChildren<{\n targetOrigin?: string;\n}>;\n\ntype PendingRequest = {\n method: keyof TipsyBridgeRequestMap;\n resolve: (value: TipsyChatCompletionResult) => void;\n reject: (reason?: unknown) => void;\n onData?: (chunk: TipsyChatCompletionChunk) => void;\n onComplete?: (result: TipsyChatCompletionResult) => void;\n};\n\ntype TipsyStudioContextValue = {\n isReady: boolean;\n targetOrigin: string;\n call: <M extends keyof TipsyBridgeRequestMap>(\n method: M,\n payload: TipsyBridgeRequestMap[M],\n controller?: M extends \"chat.completions\"\n ? TipsyChatCompletionController\n : TipsyRequestController,\n ) => Promise<TipsyBridgeResponseMap[M]>;\n};\n\nconst TipsyStudioContext = createContext<TipsyStudioContextValue | null>(null);\n\nexport function TipsyStudioProvider({\n children,\n targetOrigin,\n}: TipsyStudioProviderProps) {\n const resolvedTargetOrigin = useMemo(\n () => normalizeTargetOrigin(targetOrigin),\n [targetOrigin],\n );\n const [isReady, setIsReady] = useState(false);\n const pendingRef = useRef<Map<string, PendingRequest>>(new Map());\n const readyRef = useRef(false);\n const targetOriginRef = useRef(resolvedTargetOrigin);\n\n useEffect(() => {\n targetOriginRef.current = resolvedTargetOrigin;\n }, [resolvedTargetOrigin]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n let cancelled = false;\n\n const rejectPending = (error: TipsyBridgeError) => {\n const pendingRequests = Array.from(pendingRef.current.values());\n pendingRef.current.clear();\n for (const pending of pendingRequests) {\n pending.reject(new TipsyBridgeClientError(error));\n }\n };\n\n const postInit = () => {\n if (cancelled || readyRef.current || window.parent === window) {\n return;\n }\n\n const initMessage: TipsyInitMessage = {\n protocol: TIPSY_BRIDGE_PROTOCOL,\n type: \"tipsy:init\",\n };\n\n window.parent.postMessage(initMessage, targetOriginRef.current);\n };\n\n const intervalId = window.setInterval(postInit, TIPSY_INIT_RETRY_MS);\n postInit();\n\n const handleMessage = (event: MessageEvent) => {\n if (window.parent === window || event.source !== window.parent) {\n return;\n }\n\n if (\n targetOriginRef.current !== \"*\" &&\n event.origin !== targetOriginRef.current\n ) {\n return;\n }\n\n if (!isBridgeMessage(event.data)) {\n return;\n }\n\n if (event.data.type === \"tipsy:init:ack\") {\n readyRef.current = true;\n setIsReady(true);\n return;\n }\n\n if (event.data.type === \"tipsy:error\") {\n if (!event.data.requestId) {\n return;\n }\n\n const pending = pendingRef.current.get(event.data.requestId);\n if (!pending) {\n return;\n }\n\n pendingRef.current.delete(event.data.requestId);\n pending.reject(new TipsyBridgeClientError(event.data.error));\n return;\n }\n\n if (event.data.type === \"tipsy:stream\") {\n const pending = pendingRef.current.get(event.data.requestId);\n if (!pending || pending.method !== CHAT_COMPLETIONS_METHOD) {\n return;\n }\n\n pending.onData?.(event.data.payload);\n return;\n }\n\n if (event.data.type === \"tipsy:response\") {\n const pending = pendingRef.current.get(event.data.requestId);\n if (!pending) {\n return;\n }\n\n pendingRef.current.delete(event.data.requestId);\n pending.onComplete?.(event.data.payload as TipsyChatCompletionResult);\n pending.resolve(event.data.payload as TipsyChatCompletionResult);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n\n return () => {\n cancelled = true;\n readyRef.current = false;\n setIsReady(false);\n window.clearInterval(intervalId);\n window.removeEventListener(\"message\", handleMessage);\n rejectPending({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge was disconnected.\",\n });\n };\n }, []);\n\n const contextValue = useMemo<TipsyStudioContextValue>(() => {\n return {\n isReady,\n targetOrigin: resolvedTargetOrigin,\n call(method, payload, controller) {\n if (typeof window === \"undefined\" || window.parent === window) {\n return Promise.reject(\n new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge is only available inside an iframe.\",\n }),\n );\n }\n\n if (!readyRef.current) {\n return Promise.reject(\n new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge is not ready.\",\n }),\n );\n }\n\n const requestId = createRequestId();\n\n return new Promise<TipsyBridgeResponseMap[typeof method]>(\n (resolve, reject) => {\n const pending: PendingRequest = {\n method,\n resolve: (value) =>\n resolve(value as TipsyBridgeResponseMap[typeof method]),\n reject,\n onData:\n method === CHAT_COMPLETIONS_METHOD\n ? (controller as TipsyChatCompletionController | undefined)\n ?.onData\n : undefined,\n onComplete:\n method === CHAT_COMPLETIONS_METHOD\n ? (controller as TipsyChatCompletionController | undefined)\n ?.onComplete\n : undefined,\n };\n\n pendingRef.current.set(requestId, pending);\n\n const abortSignal = controller?.signal;\n const handleAbort = () => {\n if (!pendingRef.current.has(requestId)) {\n return;\n }\n\n pendingRef.current.delete(requestId);\n const abortMessage: TipsyAbortMessage = {\n protocol: TIPSY_BRIDGE_PROTOCOL,\n type: \"tipsy:abort\",\n requestId,\n };\n window.parent.postMessage(abortMessage, targetOriginRef.current);\n reject(\n new DOMException(\"The operation was aborted.\", \"AbortError\"),\n );\n };\n\n if (abortSignal?.aborted) {\n handleAbort();\n return;\n }\n\n abortSignal?.addEventListener(\"abort\", handleAbort, { once: true });\n\n const requestMessage: TipsyRequestMessage<typeof method> = {\n protocol: TIPSY_BRIDGE_PROTOCOL,\n type: \"tipsy:request\",\n requestId,\n method,\n payload,\n };\n\n window.parent.postMessage(requestMessage, targetOriginRef.current);\n },\n );\n },\n };\n }, [isReady, resolvedTargetOrigin]);\n\n return createElement(\n TipsyStudioContext.Provider,\n { value: contextValue },\n children,\n );\n}\n\nexport function useTipsyStudio() {\n const context = useContext(TipsyStudioContext);\n\n if (!context) {\n throw new Error(\"useTipsyStudio must be used within TipsyStudioProvider.\");\n }\n\n return context;\n}\n\nexport function useTipsyChat() {\n const studio = useTipsyStudio();\n\n return useMemo(() => {\n return {\n completions(\n input: TipsyChatCompletionInput,\n controller?: TipsyChatCompletionController,\n ) {\n return studio.call(CHAT_COMPLETIONS_METHOD, input, controller);\n },\n };\n }, [studio]);\n}\n"]}
1
+ {"version":3,"sources":["../src/bridge.ts","../src/client.ts","../src/react.ts"],"names":["createContext","useMemo","useState","useEffect","createElement","useContext"],"mappings":"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","file":"react.cjs","sourcesContent":["export const TIPSY_BRIDGE_PROTOCOL = \"tipsy-bridge-v1\";\nexport const TIPSY_INIT_RETRY_MS = 500;\nexport const RESPOND_METHOD = \"sdk.respond\";\n\ntype TipsyBridgeMessageType =\n | \"tipsy:init\"\n | \"tipsy:init:ack\"\n | \"tipsy:request\"\n | \"tipsy:stream\"\n | \"tipsy:response\"\n | \"tipsy:error\"\n | \"tipsy:abort\";\n\nexport type TipsyRole = \"system\" | \"user\" | \"assistant\";\n\nexport type TipsyMessage = {\n role: TipsyRole;\n content: string;\n};\n\nexport type TipsyUsage = {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n};\n\nexport type TipsyTextResponseFormat = {\n type: \"text\";\n};\n\nexport type TipsyJsonSchemaResponseFormat = {\n type: \"json_schema\";\n name: string;\n schema: Record<string, unknown>;\n};\n\nexport type TipsyRespondResponseFormat =\n | TipsyTextResponseFormat\n | TipsyJsonSchemaResponseFormat;\n\ntype TipsyRespondRequestBase = {\n messages: TipsyMessage[];\n model_id?: string | null;\n response_format: TipsyRespondResponseFormat;\n};\n\nexport type TipsyRespondStreamRequest = TipsyRespondRequestBase & {\n stream: true;\n};\n\nexport type TipsyRespondNonStreamRequest = TipsyRespondRequestBase & {\n stream: false;\n};\n\nexport type TipsyRespondRequest =\n | TipsyRespondStreamRequest\n | TipsyRespondNonStreamRequest;\n\nexport type TipsyRespondEnvelope<T = unknown> = {\n code: number;\n msg: string;\n trace_id: string;\n data: {\n message_id: string;\n result: T;\n response_format:\n | TipsyTextResponseFormat\n | {\n type: \"json_schema\";\n name: string;\n };\n usage: TipsyUsage;\n };\n};\n\nexport type TipsyRespondTextStreamEvent = {\n type: \"delta\";\n delta: string;\n};\n\nexport type TipsyRespondJsonStreamEvent<T = unknown> = {\n type: \"delta\";\n snapshot: Partial<T> | T;\n};\n\nexport type TipsyRespondMetaEvent = {\n type: \"meta\";\n message_id: string;\n usage: TipsyUsage;\n trace_id: string;\n};\n\nexport type TipsyRespondStreamEvent<T = unknown> =\n | TipsyRespondTextStreamEvent\n | TipsyRespondJsonStreamEvent<T>\n | TipsyRespondMetaEvent;\n\nexport type TipsyRespondResult<T = unknown> = {\n message_id: string;\n result: T;\n response_format:\n | TipsyTextResponseFormat\n | {\n type: \"json_schema\";\n name: string;\n };\n};\n\nexport type TipsyBridgeErrorCode =\n | \"UNAUTHORIZED\"\n | \"BAD_REQUEST\"\n | \"NETWORK_ERROR\"\n | \"STREAM_PARSE_ERROR\"\n | \"ORIGIN_MISMATCH\"\n | \"UNSUPPORTED_METHOD\"\n | \"INTERNAL_ERROR\";\n\nexport type TipsyBridgeError = {\n code: TipsyBridgeErrorCode;\n message: string;\n};\n\nexport type TipsyBridgeRequestMap = {\n [RESPOND_METHOD]: TipsyRespondRequest;\n};\n\nexport type TipsyBridgeStreamMap = {\n [RESPOND_METHOD]: TipsyRespondStreamEvent;\n};\n\nexport type TipsyBridgeResponseMap = {\n [RESPOND_METHOD]: TipsyRespondEnvelope | TipsyRespondResult;\n};\n\nexport type TipsyInitMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:init\";\n};\n\ntype TipsyInitAckMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:init:ack\";\n};\n\nexport type TipsyRequestMessage<M extends keyof TipsyBridgeRequestMap> = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:request\";\n requestId: string;\n method: M;\n params: TipsyBridgeRequestMap[M];\n};\n\ntype TipsyStreamMessage<M extends keyof TipsyBridgeStreamMap> = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:stream\";\n requestId: string;\n payload: {\n method: M;\n event: TipsyBridgeStreamMap[M];\n };\n};\n\ntype TipsyResponseMessage<M extends keyof TipsyBridgeResponseMap> = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:response\";\n requestId: string;\n payload: {\n method: M;\n result: TipsyBridgeResponseMap[M];\n };\n};\n\ntype TipsyErrorMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:error\";\n requestId?: string;\n error: TipsyBridgeError;\n};\n\nexport type TipsyAbortMessage = {\n protocol: typeof TIPSY_BRIDGE_PROTOCOL;\n type: \"tipsy:abort\";\n requestId: string;\n};\n\nexport type TipsyBridgeMessage =\n | TipsyInitMessage\n | TipsyInitAckMessage\n | TipsyRequestMessage<keyof TipsyBridgeRequestMap>\n | TipsyStreamMessage<keyof TipsyBridgeStreamMap>\n | TipsyResponseMessage<keyof TipsyBridgeResponseMap>\n | TipsyErrorMessage\n | TipsyAbortMessage;\n\nexport type TipsyRequestController<M extends keyof TipsyBridgeRequestMap> = {\n signal?: AbortSignal;\n onEvent?: (event: TipsyBridgeStreamMap[M]) => void;\n};\n\nexport type TipsyRespondController<T = unknown> = {\n signal?: AbortSignal;\n onEvent?: (event: TipsyRespondStreamEvent<T>) => void;\n};\n\nexport class TipsyBridgeClientError extends Error {\n code: TipsyBridgeErrorCode;\n\n constructor(error: TipsyBridgeError) {\n super(error.message);\n this.name = \"TipsyBridgeClientError\";\n this.code = error.code;\n }\n}\n\nexport function getParentOriginFromReferrer(): string | null {\n if (typeof document === \"undefined\" || !document.referrer) {\n return null;\n }\n\n try {\n return new URL(document.referrer).origin;\n } catch {\n return null;\n }\n}\n\nexport function normalizeTargetOrigin(value?: string): string {\n if (value && value.trim()) {\n return value;\n }\n\n return getParentOriginFromReferrer() ?? \"*\";\n}\n\nexport function isBridgeMessage(value: unknown): value is TipsyBridgeMessage {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<TipsyBridgeMessage>;\n if (candidate.protocol !== TIPSY_BRIDGE_PROTOCOL) {\n return false;\n }\n\n const validTypes = new Set<TipsyBridgeMessageType>([\n \"tipsy:init\",\n \"tipsy:init:ack\",\n \"tipsy:request\",\n \"tipsy:stream\",\n \"tipsy:response\",\n \"tipsy:error\",\n \"tipsy:abort\",\n ]);\n\n return typeof candidate.type === \"string\" && validTypes.has(candidate.type);\n}\n\nexport function createRequestId() {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.randomUUID === \"function\"\n ) {\n return crypto.randomUUID();\n }\n\n return `tipsy_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n}\n","import {\n RESPOND_METHOD,\n TIPSY_BRIDGE_PROTOCOL,\n TIPSY_INIT_RETRY_MS,\n type TipsyAbortMessage,\n type TipsyBridgeError,\n TipsyBridgeClientError,\n type TipsyBridgeRequestMap,\n type TipsyBridgeResponseMap,\n type TipsyBridgeStreamMap,\n type TipsyInitMessage,\n type TipsyRequestController,\n type TipsyRequestMessage,\n type TipsyRespondController,\n type TipsyRespondEnvelope,\n type TipsyRespondNonStreamRequest,\n type TipsyRespondRequest,\n type TipsyRespondResult,\n type TipsyRespondStreamRequest,\n isBridgeMessage,\n normalizeTargetOrigin,\n createRequestId,\n} from \"./bridge\";\n\nconst TIPSY_READY_WAIT_RETRY_COUNT = 6;\n\ntype PendingRequest = {\n method: keyof TipsyBridgeRequestMap;\n resolve: (value: TipsyBridgeResponseMap[keyof TipsyBridgeResponseMap]) => void;\n reject: (reason?: unknown) => void;\n onEvent?: (event: any) => void;\n cleanupAbortListener?: () => void;\n};\n\nexport type TipsyStudioClientOptions = {\n targetOrigin?: string;\n sourceWindow?: Window;\n targetWindow?: Window;\n};\n\nexport type TipsyStudioClient = {\n isReady: () => boolean;\n subscribe: (listener: (isReady: boolean) => void) => () => void;\n waitForReady: (signal?: AbortSignal) => Promise<void>;\n call: <M extends keyof TipsyBridgeRequestMap>(\n method: M,\n params: TipsyBridgeRequestMap[M],\n controller?: TipsyRequestController<M>,\n ) => Promise<TipsyBridgeResponseMap[M]>;\n respond<T = string>(\n request: TipsyRespondNonStreamRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondEnvelope<T>>;\n respond<T = string>(\n request: TipsyRespondStreamRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondResult<T>>;\n respond<T = string>(\n request: TipsyRespondRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondEnvelope<T> | TipsyRespondResult<T>>;\n destroy: () => void;\n};\n\nexport function createTipsyStudioClient(\n options: TipsyStudioClientOptions = {},\n): TipsyStudioClient {\n const sourceWindow =\n options.sourceWindow ?? (typeof window !== \"undefined\" ? window : undefined);\n const targetWindow =\n options.targetWindow ??\n (sourceWindow && sourceWindow.parent !== sourceWindow\n ? sourceWindow.parent\n : undefined);\n const targetOrigin = normalizeTargetOrigin(options.targetOrigin);\n\n const pendingRequests = new Map<string, PendingRequest>();\n const readyWaiters = new Set<() => void>();\n const listeners = new Set<(isReady: boolean) => void>();\n\n let isDestroyed = false;\n let isConnected = false;\n let isReady = false;\n let initIntervalId: number | null = null;\n\n const emitReadyChange = (nextReady: boolean) => {\n if (isReady === nextReady) {\n return;\n }\n\n isReady = nextReady;\n for (const listener of listeners) {\n listener(isReady);\n }\n };\n\n const resolveReadyWaiters = () => {\n const waiters = Array.from(readyWaiters.values());\n readyWaiters.clear();\n for (const resolve of waiters) {\n resolve();\n }\n };\n\n const rejectPending = (error: TipsyBridgeError) => {\n const requests = Array.from(pendingRequests.values());\n pendingRequests.clear();\n for (const pending of requests) {\n pending.cleanupAbortListener?.();\n pending.reject(new TipsyBridgeClientError(error));\n }\n };\n\n const postMessageToTarget = (\n message:\n | TipsyInitMessage\n | TipsyAbortMessage\n | TipsyRequestMessage<keyof TipsyBridgeRequestMap>,\n ) => {\n targetWindow?.postMessage(message, targetOrigin);\n };\n\n const postInit = () => {\n if (isDestroyed || isReady || !targetWindow) {\n return;\n }\n\n postMessageToTarget({\n protocol: TIPSY_BRIDGE_PROTOCOL,\n type: \"tipsy:init\",\n });\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (isDestroyed || event.source !== targetWindow) {\n return;\n }\n\n if (targetOrigin !== \"*\" && event.origin !== targetOrigin) {\n return;\n }\n\n if (!isBridgeMessage(event.data)) {\n return;\n }\n\n if (event.data.type === \"tipsy:init:ack\") {\n emitReadyChange(true);\n resolveReadyWaiters();\n return;\n }\n\n if (event.data.type === \"tipsy:error\") {\n if (!event.data.requestId) {\n return;\n }\n\n const pending = pendingRequests.get(event.data.requestId);\n if (!pending) {\n return;\n }\n\n pendingRequests.delete(event.data.requestId);\n pending.cleanupAbortListener?.();\n pending.reject(new TipsyBridgeClientError(event.data.error));\n return;\n }\n\n if (event.data.type === \"tipsy:stream\") {\n const pending = pendingRequests.get(event.data.requestId);\n if (!pending || pending.method !== event.data.payload.method) {\n return;\n }\n\n pending.onEvent?.(event.data.payload.event);\n return;\n }\n\n if (event.data.type === \"tipsy:response\") {\n const pending = pendingRequests.get(event.data.requestId);\n if (!pending || pending.method !== event.data.payload.method) {\n return;\n }\n\n pendingRequests.delete(event.data.requestId);\n pending.cleanupAbortListener?.();\n pending.resolve(event.data.payload.result);\n }\n };\n\n const ensureConnected = () => {\n if (isDestroyed || isConnected || !sourceWindow) {\n return;\n }\n\n sourceWindow.addEventListener(\"message\", handleMessage);\n initIntervalId = sourceWindow.setInterval(postInit, TIPSY_INIT_RETRY_MS);\n isConnected = true;\n postInit();\n };\n\n const ensureBridgeAvailable = () => {\n if (!sourceWindow || !targetWindow) {\n throw new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge is only available inside an iframe.\",\n });\n }\n };\n\n const waitForReady = async (signal?: AbortSignal) => {\n if (isDestroyed) {\n throw new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge was disconnected.\",\n });\n }\n\n ensureBridgeAvailable();\n ensureConnected();\n const activeSourceWindow = sourceWindow;\n\n if (!activeSourceWindow) {\n throw new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge is only available inside an iframe.\",\n });\n }\n\n if (isReady) {\n return;\n }\n\n for (let attempt = 0; attempt < TIPSY_READY_WAIT_RETRY_COUNT; attempt += 1) {\n if (signal?.aborted) {\n throw new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n\n postInit();\n\n await new Promise<void>((resolve, reject) => {\n let timeoutId = 0;\n\n const handleReady = () => {\n activeSourceWindow.clearTimeout(timeoutId);\n signal?.removeEventListener(\"abort\", handleAbort);\n readyWaiters.delete(handleReady);\n resolve();\n };\n\n const handleAbort = () => {\n activeSourceWindow.clearTimeout(timeoutId);\n readyWaiters.delete(handleReady);\n signal?.removeEventListener(\"abort\", handleAbort);\n reject(new DOMException(\"The operation was aborted.\", \"AbortError\"));\n };\n\n readyWaiters.add(handleReady);\n timeoutId = activeSourceWindow.setTimeout(() => {\n readyWaiters.delete(handleReady);\n signal?.removeEventListener(\"abort\", handleAbort);\n resolve();\n }, TIPSY_INIT_RETRY_MS);\n\n signal?.addEventListener(\"abort\", handleAbort, { once: true });\n });\n\n if (isReady) {\n return;\n }\n }\n\n throw new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge is not ready.\",\n });\n };\n\n function respond<T = string>(\n request: TipsyRespondNonStreamRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondEnvelope<T>>;\n function respond<T = string>(\n request: TipsyRespondStreamRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondResult<T>>;\n function respond<T = string>(\n request: TipsyRespondRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondEnvelope<T> | TipsyRespondResult<T>> {\n return client.call(RESPOND_METHOD, request, {\n signal: controller?.signal,\n onEvent: controller?.onEvent as\n | ((event: TipsyBridgeStreamMap[typeof RESPOND_METHOD]) => void)\n | undefined,\n }) as Promise<TipsyRespondEnvelope<T> | TipsyRespondResult<T>>;\n }\n\n const client: TipsyStudioClient = {\n isReady: () => isReady,\n subscribe(listener) {\n listeners.add(listener);\n listener(isReady);\n ensureConnected();\n\n return () => {\n listeners.delete(listener);\n };\n },\n async waitForReady(signal) {\n await waitForReady(signal);\n },\n async call(method, params, controller) {\n if (isDestroyed) {\n throw new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge was disconnected.\",\n });\n }\n\n await waitForReady(controller?.signal);\n\n const requestId = createRequestId();\n\n return await new Promise<TipsyBridgeResponseMap[typeof method]>(\n (resolve, reject) => {\n const pending: PendingRequest = {\n method,\n resolve: (value) =>\n resolve(value as TipsyBridgeResponseMap[typeof method]),\n reject,\n onEvent: controller?.onEvent as\n | ((event: TipsyBridgeStreamMap[typeof method]) => void)\n | undefined,\n };\n\n pendingRequests.set(requestId, pending);\n\n const abortSignal = controller?.signal;\n const handleAbort = () => {\n if (!pendingRequests.has(requestId)) {\n return;\n }\n\n pendingRequests.delete(requestId);\n pending.cleanupAbortListener?.();\n postMessageToTarget({\n protocol: TIPSY_BRIDGE_PROTOCOL,\n type: \"tipsy:abort\",\n requestId,\n });\n reject(new DOMException(\"The operation was aborted.\", \"AbortError\"));\n };\n\n pending.cleanupAbortListener = () => {\n abortSignal?.removeEventListener(\"abort\", handleAbort);\n };\n\n if (abortSignal?.aborted) {\n handleAbort();\n return;\n }\n\n abortSignal?.addEventListener(\"abort\", handleAbort, { once: true });\n\n postMessageToTarget({\n protocol: TIPSY_BRIDGE_PROTOCOL,\n type: \"tipsy:request\",\n requestId,\n method,\n params,\n });\n },\n );\n },\n respond,\n destroy() {\n if (isDestroyed) {\n return;\n }\n\n isDestroyed = true;\n resolveReadyWaiters();\n emitReadyChange(false);\n listeners.clear();\n\n if (isConnected && sourceWindow) {\n if (initIntervalId !== null) {\n sourceWindow.clearInterval(initIntervalId);\n }\n sourceWindow.removeEventListener(\"message\", handleMessage);\n }\n\n initIntervalId = null;\n isConnected = false;\n rejectPending({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge was disconnected.\",\n });\n },\n };\n\n return client;\n}\n","import {\n createElement,\n createContext,\n type PropsWithChildren,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport {\n TipsyBridgeClientError,\n type TipsyBridgeRequestMap,\n type TipsyBridgeResponseMap,\n type TipsyRequestController,\n type TipsyRespondController,\n type TipsyRespondEnvelope,\n type TipsyRespondNonStreamRequest,\n type TipsyRespondRequest,\n type TipsyRespondResult,\n type TipsyRespondStreamRequest,\n normalizeTargetOrigin,\n} from \"./bridge\";\nimport { createTipsyStudioClient, type TipsyStudioClient } from \"./client\";\n\nexport {\n RESPOND_METHOD,\n TIPSY_BRIDGE_PROTOCOL,\n TIPSY_INIT_RETRY_MS,\n TipsyBridgeClientError,\n createRequestId,\n getParentOriginFromReferrer,\n isBridgeMessage,\n normalizeTargetOrigin,\n type TipsyAbortMessage,\n type TipsyBridgeError,\n type TipsyBridgeErrorCode,\n type TipsyBridgeMessage,\n type TipsyBridgeRequestMap,\n type TipsyBridgeResponseMap,\n type TipsyBridgeStreamMap,\n type TipsyJsonSchemaResponseFormat,\n type TipsyMessage,\n type TipsyRequestController,\n type TipsyRequestMessage,\n type TipsyRespondController,\n type TipsyRespondEnvelope,\n type TipsyRespondMetaEvent,\n type TipsyRespondNonStreamRequest,\n type TipsyRespondRequest,\n type TipsyRespondResponseFormat,\n type TipsyRespondResult,\n type TipsyRespondStreamEvent,\n type TipsyRespondStreamRequest,\n type TipsyRole,\n type TipsyTextResponseFormat,\n type TipsyUsage,\n} from \"./bridge\";\nexport {\n createTipsyStudioClient,\n type TipsyStudioClient,\n type TipsyStudioClientOptions,\n} from \"./client\";\n\nexport type TipsyStudioProviderProps = PropsWithChildren<{\n targetOrigin?: string;\n}>;\n\ntype TipsyStudioContextValue = {\n isReady: boolean;\n targetOrigin: string;\n call: <M extends keyof TipsyBridgeRequestMap>(\n method: M,\n params: TipsyBridgeRequestMap[M],\n controller?: TipsyRequestController<M>,\n ) => Promise<TipsyBridgeResponseMap[M]>;\n respond<T = string>(\n request: TipsyRespondNonStreamRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondEnvelope<T>>;\n respond<T = string>(\n request: TipsyRespondStreamRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondResult<T>>;\n respond<T = string>(\n request: TipsyRespondRequest,\n controller?: TipsyRespondController<T>,\n ): Promise<TipsyRespondEnvelope<T> | TipsyRespondResult<T>>;\n};\n\nconst TipsyStudioContext = createContext<TipsyStudioContextValue | null>(null);\n\nexport function TipsyStudioProvider({\n children,\n targetOrigin,\n}: TipsyStudioProviderProps) {\n const resolvedTargetOrigin = useMemo(\n () => normalizeTargetOrigin(targetOrigin),\n [targetOrigin],\n );\n const [isReady, setIsReady] = useState(false);\n const [client, setClient] = useState<TipsyStudioClient | null>(null);\n\n useEffect(() => {\n const nextClient = createTipsyStudioClient({ targetOrigin });\n setClient(nextClient);\n setIsReady(nextClient.isReady());\n\n const unsubscribe = nextClient.subscribe((nextIsReady) => {\n setIsReady(nextIsReady);\n });\n\n return () => {\n unsubscribe();\n nextClient.destroy();\n setClient((currentClient) =>\n currentClient === nextClient ? null : currentClient,\n );\n setIsReady(false);\n };\n }, [targetOrigin]);\n\n const contextValue = useMemo<TipsyStudioContextValue>(() => {\n const notReadyError = new TipsyBridgeClientError({\n code: \"NETWORK_ERROR\",\n message: \"Tipsy bridge is not ready.\",\n });\n\n const respond = ((\n request: TipsyRespondRequest,\n controller?: TipsyRespondController,\n ) => {\n if (!client) {\n return Promise.reject(notReadyError);\n }\n\n return client.respond(request, controller);\n }) as TipsyStudioContextValue[\"respond\"];\n\n return {\n isReady,\n targetOrigin: resolvedTargetOrigin,\n call(method, params, controller) {\n if (!client) {\n return Promise.reject(notReadyError);\n }\n\n return client.call(method, params, controller);\n },\n respond,\n };\n }, [client, isReady, resolvedTargetOrigin]);\n\n return createElement(\n TipsyStudioContext.Provider,\n { value: contextValue },\n children,\n );\n}\n\nexport function useTipsyStudio() {\n const context = useContext(TipsyStudioContext);\n\n if (!context) {\n throw new Error(\"useTipsyStudio must be used within TipsyStudioProvider.\");\n }\n\n return context;\n}\n"]}
package/dist/react.d.cts CHANGED
@@ -1,100 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { PropsWithChildren } from 'react';
3
-
4
- declare const TIPSY_BRIDGE_PROTOCOL = "tipsy-bridge-v1";
5
- declare const CHAT_COMPLETIONS_METHOD = "chat.completions";
6
- type TipsyRole = "system" | "user" | "assistant";
7
- type TipsyChatMessage = {
8
- role: TipsyRole;
9
- content: string;
10
- };
11
- type TipsyChatCompletionInput = {
12
- messages: TipsyChatMessage[];
13
- stream: true;
14
- };
15
- type TipsyChatCompletionRawChunk = {
16
- type?: string;
17
- choices?: Array<{
18
- delta?: {
19
- content?: string;
20
- reasoning?: string;
21
- };
22
- }>;
23
- isFinished?: boolean;
24
- [key: string]: unknown;
25
- };
26
- type TipsyChatCompletionChunk = {
27
- type: "stream";
28
- chunk: string;
29
- raw: TipsyChatCompletionRawChunk;
30
- isFinished: false;
31
- };
32
- type TipsyChatCompletionResult = {
33
- type: "done";
34
- raw: TipsyChatCompletionRawChunk;
35
- isFinished: true;
36
- };
37
- type TipsyBridgeErrorCode = "UNAUTHORIZED" | "BAD_REQUEST" | "NETWORK_ERROR" | "STREAM_PARSE_ERROR" | "ORIGIN_MISMATCH" | "UNSUPPORTED_METHOD" | "INTERNAL_ERROR";
38
- type TipsyBridgeError = {
39
- code: TipsyBridgeErrorCode;
40
- message: string;
41
- };
42
- type TipsyBridgeRequestMap = {
43
- [CHAT_COMPLETIONS_METHOD]: TipsyChatCompletionInput;
44
- };
45
- type TipsyBridgeResponseMap = {
46
- [CHAT_COMPLETIONS_METHOD]: TipsyChatCompletionResult;
47
- };
48
- type TipsyInitMessage = {
49
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
50
- type: "tipsy:init";
51
- };
52
- type TipsyInitAckMessage = {
53
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
54
- type: "tipsy:init:ack";
55
- };
56
- type TipsyRequestMessage<M extends keyof TipsyBridgeRequestMap> = {
57
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
58
- type: "tipsy:request";
59
- requestId: string;
60
- method: M;
61
- payload: TipsyBridgeRequestMap[M];
62
- };
63
- type TipsyStreamMessage = {
64
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
65
- type: "tipsy:stream";
66
- requestId: string;
67
- payload: TipsyChatCompletionChunk;
68
- };
69
- type TipsyResponseMessage<M extends keyof TipsyBridgeResponseMap> = {
70
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
71
- type: "tipsy:response";
72
- requestId: string;
73
- payload: TipsyBridgeResponseMap[M];
74
- };
75
- type TipsyErrorMessage = {
76
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
77
- type: "tipsy:error";
78
- requestId?: string;
79
- error: TipsyBridgeError;
80
- };
81
- type TipsyAbortMessage = {
82
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
83
- type: "tipsy:abort";
84
- requestId: string;
85
- };
86
- type TipsyBridgeMessage = TipsyInitMessage | TipsyInitAckMessage | TipsyRequestMessage<keyof TipsyBridgeRequestMap> | TipsyStreamMessage | TipsyResponseMessage<keyof TipsyBridgeResponseMap> | TipsyErrorMessage | TipsyAbortMessage;
87
- type TipsyRequestController = {
88
- signal?: AbortSignal;
89
- };
90
- type TipsyChatCompletionController = TipsyRequestController & {
91
- onData?: (chunk: TipsyChatCompletionChunk) => void;
92
- onComplete?: (result: TipsyChatCompletionResult) => void;
93
- };
94
- declare class TipsyBridgeClientError extends Error {
95
- code: TipsyBridgeErrorCode;
96
- constructor(error: TipsyBridgeError);
97
- }
3
+ import { TipsyBridgeRequestMap, TipsyRequestController, TipsyBridgeResponseMap, TipsyRespondNonStreamRequest, TipsyRespondController, TipsyRespondEnvelope, TipsyRespondStreamRequest, TipsyRespondResult, TipsyRespondRequest } from './index.cjs';
4
+ export { RESPOND_METHOD, TIPSY_BRIDGE_PROTOCOL, TIPSY_INIT_RETRY_MS, TipsyAbortMessage, TipsyBridgeClientError, TipsyBridgeError, TipsyBridgeErrorCode, TipsyBridgeMessage, TipsyBridgeStreamMap, TipsyJsonSchemaResponseFormat, TipsyMessage, TipsyRequestMessage, TipsyRespondMetaEvent, TipsyRespondResponseFormat, TipsyRespondStreamEvent, TipsyRole, TipsyStudioClient, TipsyStudioClientOptions, TipsyTextResponseFormat, TipsyUsage, createRequestId, createTipsyStudioClient, getParentOriginFromReferrer, isBridgeMessage, normalizeTargetOrigin } from './index.cjs';
98
5
 
99
6
  type TipsyStudioProviderProps = PropsWithChildren<{
100
7
  targetOrigin?: string;
@@ -102,12 +9,12 @@ type TipsyStudioProviderProps = PropsWithChildren<{
102
9
  type TipsyStudioContextValue = {
103
10
  isReady: boolean;
104
11
  targetOrigin: string;
105
- call: <M extends keyof TipsyBridgeRequestMap>(method: M, payload: TipsyBridgeRequestMap[M], controller?: M extends "chat.completions" ? TipsyChatCompletionController : TipsyRequestController) => Promise<TipsyBridgeResponseMap[M]>;
12
+ call: <M extends keyof TipsyBridgeRequestMap>(method: M, params: TipsyBridgeRequestMap[M], controller?: TipsyRequestController<M>) => Promise<TipsyBridgeResponseMap[M]>;
13
+ respond<T = string>(request: TipsyRespondNonStreamRequest, controller?: TipsyRespondController<T>): Promise<TipsyRespondEnvelope<T>>;
14
+ respond<T = string>(request: TipsyRespondStreamRequest, controller?: TipsyRespondController<T>): Promise<TipsyRespondResult<T>>;
15
+ respond<T = string>(request: TipsyRespondRequest, controller?: TipsyRespondController<T>): Promise<TipsyRespondEnvelope<T> | TipsyRespondResult<T>>;
106
16
  };
107
17
  declare function TipsyStudioProvider({ children, targetOrigin, }: TipsyStudioProviderProps): react.FunctionComponentElement<react.ProviderProps<TipsyStudioContextValue | null>>;
108
18
  declare function useTipsyStudio(): TipsyStudioContextValue;
109
- declare function useTipsyChat(): {
110
- completions(input: TipsyChatCompletionInput, controller?: TipsyChatCompletionController): Promise<TipsyChatCompletionResult>;
111
- };
112
19
 
113
- export { CHAT_COMPLETIONS_METHOD, TIPSY_BRIDGE_PROTOCOL, type TipsyAbortMessage, TipsyBridgeClientError, type TipsyBridgeError, type TipsyBridgeMessage, type TipsyBridgeRequestMap, type TipsyBridgeResponseMap, type TipsyChatCompletionChunk, type TipsyChatCompletionController, type TipsyChatCompletionInput, type TipsyChatCompletionRawChunk, type TipsyChatCompletionResult, type TipsyChatMessage, TipsyStudioProvider, type TipsyStudioProviderProps, useTipsyChat, useTipsyStudio };
20
+ export { TipsyBridgeRequestMap, TipsyBridgeResponseMap, TipsyRequestController, TipsyRespondController, TipsyRespondEnvelope, TipsyRespondNonStreamRequest, TipsyRespondRequest, TipsyRespondResult, TipsyRespondStreamRequest, TipsyStudioProvider, type TipsyStudioProviderProps, useTipsyStudio };
package/dist/react.d.ts CHANGED
@@ -1,100 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { PropsWithChildren } from 'react';
3
-
4
- declare const TIPSY_BRIDGE_PROTOCOL = "tipsy-bridge-v1";
5
- declare const CHAT_COMPLETIONS_METHOD = "chat.completions";
6
- type TipsyRole = "system" | "user" | "assistant";
7
- type TipsyChatMessage = {
8
- role: TipsyRole;
9
- content: string;
10
- };
11
- type TipsyChatCompletionInput = {
12
- messages: TipsyChatMessage[];
13
- stream: true;
14
- };
15
- type TipsyChatCompletionRawChunk = {
16
- type?: string;
17
- choices?: Array<{
18
- delta?: {
19
- content?: string;
20
- reasoning?: string;
21
- };
22
- }>;
23
- isFinished?: boolean;
24
- [key: string]: unknown;
25
- };
26
- type TipsyChatCompletionChunk = {
27
- type: "stream";
28
- chunk: string;
29
- raw: TipsyChatCompletionRawChunk;
30
- isFinished: false;
31
- };
32
- type TipsyChatCompletionResult = {
33
- type: "done";
34
- raw: TipsyChatCompletionRawChunk;
35
- isFinished: true;
36
- };
37
- type TipsyBridgeErrorCode = "UNAUTHORIZED" | "BAD_REQUEST" | "NETWORK_ERROR" | "STREAM_PARSE_ERROR" | "ORIGIN_MISMATCH" | "UNSUPPORTED_METHOD" | "INTERNAL_ERROR";
38
- type TipsyBridgeError = {
39
- code: TipsyBridgeErrorCode;
40
- message: string;
41
- };
42
- type TipsyBridgeRequestMap = {
43
- [CHAT_COMPLETIONS_METHOD]: TipsyChatCompletionInput;
44
- };
45
- type TipsyBridgeResponseMap = {
46
- [CHAT_COMPLETIONS_METHOD]: TipsyChatCompletionResult;
47
- };
48
- type TipsyInitMessage = {
49
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
50
- type: "tipsy:init";
51
- };
52
- type TipsyInitAckMessage = {
53
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
54
- type: "tipsy:init:ack";
55
- };
56
- type TipsyRequestMessage<M extends keyof TipsyBridgeRequestMap> = {
57
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
58
- type: "tipsy:request";
59
- requestId: string;
60
- method: M;
61
- payload: TipsyBridgeRequestMap[M];
62
- };
63
- type TipsyStreamMessage = {
64
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
65
- type: "tipsy:stream";
66
- requestId: string;
67
- payload: TipsyChatCompletionChunk;
68
- };
69
- type TipsyResponseMessage<M extends keyof TipsyBridgeResponseMap> = {
70
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
71
- type: "tipsy:response";
72
- requestId: string;
73
- payload: TipsyBridgeResponseMap[M];
74
- };
75
- type TipsyErrorMessage = {
76
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
77
- type: "tipsy:error";
78
- requestId?: string;
79
- error: TipsyBridgeError;
80
- };
81
- type TipsyAbortMessage = {
82
- protocol: typeof TIPSY_BRIDGE_PROTOCOL;
83
- type: "tipsy:abort";
84
- requestId: string;
85
- };
86
- type TipsyBridgeMessage = TipsyInitMessage | TipsyInitAckMessage | TipsyRequestMessage<keyof TipsyBridgeRequestMap> | TipsyStreamMessage | TipsyResponseMessage<keyof TipsyBridgeResponseMap> | TipsyErrorMessage | TipsyAbortMessage;
87
- type TipsyRequestController = {
88
- signal?: AbortSignal;
89
- };
90
- type TipsyChatCompletionController = TipsyRequestController & {
91
- onData?: (chunk: TipsyChatCompletionChunk) => void;
92
- onComplete?: (result: TipsyChatCompletionResult) => void;
93
- };
94
- declare class TipsyBridgeClientError extends Error {
95
- code: TipsyBridgeErrorCode;
96
- constructor(error: TipsyBridgeError);
97
- }
3
+ import { TipsyBridgeRequestMap, TipsyRequestController, TipsyBridgeResponseMap, TipsyRespondNonStreamRequest, TipsyRespondController, TipsyRespondEnvelope, TipsyRespondStreamRequest, TipsyRespondResult, TipsyRespondRequest } from './index.js';
4
+ export { RESPOND_METHOD, TIPSY_BRIDGE_PROTOCOL, TIPSY_INIT_RETRY_MS, TipsyAbortMessage, TipsyBridgeClientError, TipsyBridgeError, TipsyBridgeErrorCode, TipsyBridgeMessage, TipsyBridgeStreamMap, TipsyJsonSchemaResponseFormat, TipsyMessage, TipsyRequestMessage, TipsyRespondMetaEvent, TipsyRespondResponseFormat, TipsyRespondStreamEvent, TipsyRole, TipsyStudioClient, TipsyStudioClientOptions, TipsyTextResponseFormat, TipsyUsage, createRequestId, createTipsyStudioClient, getParentOriginFromReferrer, isBridgeMessage, normalizeTargetOrigin } from './index.js';
98
5
 
99
6
  type TipsyStudioProviderProps = PropsWithChildren<{
100
7
  targetOrigin?: string;
@@ -102,12 +9,12 @@ type TipsyStudioProviderProps = PropsWithChildren<{
102
9
  type TipsyStudioContextValue = {
103
10
  isReady: boolean;
104
11
  targetOrigin: string;
105
- call: <M extends keyof TipsyBridgeRequestMap>(method: M, payload: TipsyBridgeRequestMap[M], controller?: M extends "chat.completions" ? TipsyChatCompletionController : TipsyRequestController) => Promise<TipsyBridgeResponseMap[M]>;
12
+ call: <M extends keyof TipsyBridgeRequestMap>(method: M, params: TipsyBridgeRequestMap[M], controller?: TipsyRequestController<M>) => Promise<TipsyBridgeResponseMap[M]>;
13
+ respond<T = string>(request: TipsyRespondNonStreamRequest, controller?: TipsyRespondController<T>): Promise<TipsyRespondEnvelope<T>>;
14
+ respond<T = string>(request: TipsyRespondStreamRequest, controller?: TipsyRespondController<T>): Promise<TipsyRespondResult<T>>;
15
+ respond<T = string>(request: TipsyRespondRequest, controller?: TipsyRespondController<T>): Promise<TipsyRespondEnvelope<T> | TipsyRespondResult<T>>;
106
16
  };
107
17
  declare function TipsyStudioProvider({ children, targetOrigin, }: TipsyStudioProviderProps): react.FunctionComponentElement<react.ProviderProps<TipsyStudioContextValue | null>>;
108
18
  declare function useTipsyStudio(): TipsyStudioContextValue;
109
- declare function useTipsyChat(): {
110
- completions(input: TipsyChatCompletionInput, controller?: TipsyChatCompletionController): Promise<TipsyChatCompletionResult>;
111
- };
112
19
 
113
- export { CHAT_COMPLETIONS_METHOD, TIPSY_BRIDGE_PROTOCOL, type TipsyAbortMessage, TipsyBridgeClientError, type TipsyBridgeError, type TipsyBridgeMessage, type TipsyBridgeRequestMap, type TipsyBridgeResponseMap, type TipsyChatCompletionChunk, type TipsyChatCompletionController, type TipsyChatCompletionInput, type TipsyChatCompletionRawChunk, type TipsyChatCompletionResult, type TipsyChatMessage, TipsyStudioProvider, type TipsyStudioProviderProps, useTipsyChat, useTipsyStudio };
20
+ export { TipsyBridgeRequestMap, TipsyBridgeResponseMap, TipsyRequestController, TipsyRespondController, TipsyRespondEnvelope, TipsyRespondNonStreamRequest, TipsyRespondRequest, TipsyRespondResult, TipsyRespondStreamRequest, TipsyStudioProvider, type TipsyStudioProviderProps, useTipsyStudio };
package/dist/react.js CHANGED
@@ -1,61 +1,7 @@
1
- import { createContext, useMemo, useState, useRef, useEffect, createElement, useContext } from 'react';
1
+ import { normalizeTargetOrigin, createTipsyStudioClient, TipsyBridgeClientError } from './chunk-NLCN4YRK.js';
2
+ export { RESPOND_METHOD, TIPSY_BRIDGE_PROTOCOL, TIPSY_INIT_RETRY_MS, TipsyBridgeClientError, createRequestId, createTipsyStudioClient, getParentOriginFromReferrer, isBridgeMessage, normalizeTargetOrigin } from './chunk-NLCN4YRK.js';
3
+ import { createContext, useMemo, useState, useEffect, createElement, useContext } from 'react';
2
4
 
3
- // src/react.ts
4
-
5
- // src/bridge.ts
6
- var TIPSY_BRIDGE_PROTOCOL = "tipsy-bridge-v1";
7
- var TIPSY_INIT_RETRY_MS = 500;
8
- var CHAT_COMPLETIONS_METHOD = "chat.completions";
9
- var TipsyBridgeClientError = class extends Error {
10
- constructor(error) {
11
- super(error.message);
12
- this.name = "TipsyBridgeClientError";
13
- this.code = error.code;
14
- }
15
- };
16
- function getParentOriginFromReferrer() {
17
- if (typeof document === "undefined" || !document.referrer) {
18
- return null;
19
- }
20
- try {
21
- return new URL(document.referrer).origin;
22
- } catch {
23
- return null;
24
- }
25
- }
26
- function normalizeTargetOrigin(value) {
27
- if (value && value.trim()) {
28
- return value;
29
- }
30
- return getParentOriginFromReferrer() ?? "*";
31
- }
32
- function isBridgeMessage(value) {
33
- if (!value || typeof value !== "object") {
34
- return false;
35
- }
36
- const candidate = value;
37
- if (candidate.protocol !== TIPSY_BRIDGE_PROTOCOL) {
38
- return false;
39
- }
40
- const validTypes = /* @__PURE__ */ new Set([
41
- "tipsy:init",
42
- "tipsy:init:ack",
43
- "tipsy:request",
44
- "tipsy:stream",
45
- "tipsy:response",
46
- "tipsy:error",
47
- "tipsy:abort"
48
- ]);
49
- return typeof candidate.type === "string" && validTypes.has(candidate.type);
50
- }
51
- function createRequestId() {
52
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
53
- return crypto.randomUUID();
54
- }
55
- return `tipsy_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
56
- }
57
-
58
- // src/react.ts
59
5
  var TipsyStudioContext = createContext(null);
60
6
  function TipsyStudioProvider({
61
7
  children,
@@ -66,160 +12,46 @@ function TipsyStudioProvider({
66
12
  [targetOrigin]
67
13
  );
68
14
  const [isReady, setIsReady] = useState(false);
69
- const pendingRef = useRef(/* @__PURE__ */ new Map());
70
- const readyRef = useRef(false);
71
- const targetOriginRef = useRef(resolvedTargetOrigin);
15
+ const [client, setClient] = useState(null);
72
16
  useEffect(() => {
73
- targetOriginRef.current = resolvedTargetOrigin;
74
- }, [resolvedTargetOrigin]);
75
- useEffect(() => {
76
- if (typeof window === "undefined") {
77
- return void 0;
78
- }
79
- let cancelled = false;
80
- const rejectPending = (error) => {
81
- const pendingRequests = Array.from(pendingRef.current.values());
82
- pendingRef.current.clear();
83
- for (const pending of pendingRequests) {
84
- pending.reject(new TipsyBridgeClientError(error));
85
- }
86
- };
87
- const postInit = () => {
88
- if (cancelled || readyRef.current || window.parent === window) {
89
- return;
90
- }
91
- const initMessage = {
92
- protocol: TIPSY_BRIDGE_PROTOCOL,
93
- type: "tipsy:init"
94
- };
95
- window.parent.postMessage(initMessage, targetOriginRef.current);
96
- };
97
- const intervalId = window.setInterval(postInit, TIPSY_INIT_RETRY_MS);
98
- postInit();
99
- const handleMessage = (event) => {
100
- if (window.parent === window || event.source !== window.parent) {
101
- return;
102
- }
103
- if (targetOriginRef.current !== "*" && event.origin !== targetOriginRef.current) {
104
- return;
105
- }
106
- if (!isBridgeMessage(event.data)) {
107
- return;
108
- }
109
- if (event.data.type === "tipsy:init:ack") {
110
- readyRef.current = true;
111
- setIsReady(true);
112
- return;
113
- }
114
- if (event.data.type === "tipsy:error") {
115
- if (!event.data.requestId) {
116
- return;
117
- }
118
- const pending = pendingRef.current.get(event.data.requestId);
119
- if (!pending) {
120
- return;
121
- }
122
- pendingRef.current.delete(event.data.requestId);
123
- pending.reject(new TipsyBridgeClientError(event.data.error));
124
- return;
125
- }
126
- if (event.data.type === "tipsy:stream") {
127
- const pending = pendingRef.current.get(event.data.requestId);
128
- if (!pending || pending.method !== CHAT_COMPLETIONS_METHOD) {
129
- return;
130
- }
131
- pending.onData?.(event.data.payload);
132
- return;
133
- }
134
- if (event.data.type === "tipsy:response") {
135
- const pending = pendingRef.current.get(event.data.requestId);
136
- if (!pending) {
137
- return;
138
- }
139
- pendingRef.current.delete(event.data.requestId);
140
- pending.onComplete?.(event.data.payload);
141
- pending.resolve(event.data.payload);
142
- }
143
- };
144
- window.addEventListener("message", handleMessage);
17
+ const nextClient = createTipsyStudioClient({ targetOrigin });
18
+ setClient(nextClient);
19
+ setIsReady(nextClient.isReady());
20
+ const unsubscribe = nextClient.subscribe((nextIsReady) => {
21
+ setIsReady(nextIsReady);
22
+ });
145
23
  return () => {
146
- cancelled = true;
147
- readyRef.current = false;
24
+ unsubscribe();
25
+ nextClient.destroy();
26
+ setClient(
27
+ (currentClient) => currentClient === nextClient ? null : currentClient
28
+ );
148
29
  setIsReady(false);
149
- window.clearInterval(intervalId);
150
- window.removeEventListener("message", handleMessage);
151
- rejectPending({
152
- code: "NETWORK_ERROR",
153
- message: "Tipsy bridge was disconnected."
154
- });
155
30
  };
156
- }, []);
31
+ }, [targetOrigin]);
157
32
  const contextValue = useMemo(() => {
33
+ const notReadyError = new TipsyBridgeClientError({
34
+ code: "NETWORK_ERROR",
35
+ message: "Tipsy bridge is not ready."
36
+ });
37
+ const respond = ((request, controller) => {
38
+ if (!client) {
39
+ return Promise.reject(notReadyError);
40
+ }
41
+ return client.respond(request, controller);
42
+ });
158
43
  return {
159
44
  isReady,
160
45
  targetOrigin: resolvedTargetOrigin,
161
- call(method, payload, controller) {
162
- if (typeof window === "undefined" || window.parent === window) {
163
- return Promise.reject(
164
- new TipsyBridgeClientError({
165
- code: "NETWORK_ERROR",
166
- message: "Tipsy bridge is only available inside an iframe."
167
- })
168
- );
46
+ call(method, params, controller) {
47
+ if (!client) {
48
+ return Promise.reject(notReadyError);
169
49
  }
170
- if (!readyRef.current) {
171
- return Promise.reject(
172
- new TipsyBridgeClientError({
173
- code: "NETWORK_ERROR",
174
- message: "Tipsy bridge is not ready."
175
- })
176
- );
177
- }
178
- const requestId = createRequestId();
179
- return new Promise(
180
- (resolve, reject) => {
181
- const pending = {
182
- method,
183
- resolve: (value) => resolve(value),
184
- reject,
185
- onData: method === CHAT_COMPLETIONS_METHOD ? controller?.onData : void 0,
186
- onComplete: method === CHAT_COMPLETIONS_METHOD ? controller?.onComplete : void 0
187
- };
188
- pendingRef.current.set(requestId, pending);
189
- const abortSignal = controller?.signal;
190
- const handleAbort = () => {
191
- if (!pendingRef.current.has(requestId)) {
192
- return;
193
- }
194
- pendingRef.current.delete(requestId);
195
- const abortMessage = {
196
- protocol: TIPSY_BRIDGE_PROTOCOL,
197
- type: "tipsy:abort",
198
- requestId
199
- };
200
- window.parent.postMessage(abortMessage, targetOriginRef.current);
201
- reject(
202
- new DOMException("The operation was aborted.", "AbortError")
203
- );
204
- };
205
- if (abortSignal?.aborted) {
206
- handleAbort();
207
- return;
208
- }
209
- abortSignal?.addEventListener("abort", handleAbort, { once: true });
210
- const requestMessage = {
211
- protocol: TIPSY_BRIDGE_PROTOCOL,
212
- type: "tipsy:request",
213
- requestId,
214
- method,
215
- payload
216
- };
217
- window.parent.postMessage(requestMessage, targetOriginRef.current);
218
- }
219
- );
220
- }
50
+ return client.call(method, params, controller);
51
+ },
52
+ respond
221
53
  };
222
- }, [isReady, resolvedTargetOrigin]);
54
+ }, [client, isReady, resolvedTargetOrigin]);
223
55
  return createElement(
224
56
  TipsyStudioContext.Provider,
225
57
  { value: contextValue },
@@ -233,17 +65,7 @@ function useTipsyStudio() {
233
65
  }
234
66
  return context;
235
67
  }
236
- function useTipsyChat() {
237
- const studio = useTipsyStudio();
238
- return useMemo(() => {
239
- return {
240
- completions(input, controller) {
241
- return studio.call(CHAT_COMPLETIONS_METHOD, input, controller);
242
- }
243
- };
244
- }, [studio]);
245
- }
246
68
 
247
- export { CHAT_COMPLETIONS_METHOD, TIPSY_BRIDGE_PROTOCOL, TipsyBridgeClientError, TipsyStudioProvider, useTipsyChat, useTipsyStudio };
69
+ export { TipsyStudioProvider, useTipsyStudio };
248
70
  //# sourceMappingURL=react.js.map
249
71
  //# sourceMappingURL=react.js.map