Skip to content

Ability to stream function responses #252

Closed
@tmcgann

Description

@tmcgann

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions