Ability to stream function responses
tmcgann-neotax opened this issue · comments
Feature request
Is your feature request related to a problem? Please describe.
Want to stream function responses. Use case: stream chat completions from AI provider.
Describe the solution you'd like
Would love to augment the FunctionsClient
to be able to stream data from a function response. Rough example of solution:
/// Implement the StreamResponseHandler protocol to handle the streamed data.
/// You could append received data chunks to a buffer, process data as it arrives,
/// or update the UI (updates would be dispatched on the main thread).
protocol StreamResponseHandler {
func didReceive(data: Data)
func didCompleteWithError(_ error: Error?)
}
class StreamDataTaskHandler: NSObject, URLSessionDataDelegate {
let streamHandler: StreamResponseHandler
init(streamHandler: StreamResponseHandler) {
self.streamHandler = streamHandler
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
// Forward the received data to the stream handler
streamHandler.didReceive(data: data)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
// Notify the stream handler about completion or error
streamHandler.didCompleteWithError(error)
}
}
extension FunctionsClient {
public func invokeWithStream(
_ functionName: String,
options: FunctionInvokeOptions = .init(),
streamHandler: StreamResponseHandler
) async throws {
// Setup URLSession with StreamDataTaskHandler as delegate
let delegate = StreamDataTaskHandler(streamHandler: streamHandler)
let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)
// Rest of the setup similar to `rawInvoke`, but use the session with delegate
let url = self.url.appendingPathComponent(functionName)
var urlRequest = URLRequest(url: url)
urlRequest.allHTTPHeaderFields = options.headers.merging(headers) { invoke, _ in invoke }
urlRequest.httpMethod = (options.method ?? .post).rawValue
urlRequest.httpBody = options.body
// Start the data task
let task = session.dataTask(with: urlRequest)
task.resume()
// Ensure to keep the session and delegate alive as long as needed
// This may require storing references in the FunctionsClient or managing lifecycle appropriately
}
}
Describe alternatives you've considered
Make the request to the function outside of supabase-swift.
Additional context
Open to alternatives, especially if this is somehow already supported and I missed it.
Going to recreate with my non-work github account. :)