export function dbCleanupPlugin() {
    return {
        onContextBuilding({ context }) {
            // Initialize the cleanup list
            // Cast to AccounterContext to avoid potential readonly issues or type mismatches
            // during initial context building phase.
            context.dbClientsToDispose = [];
        },
        onExecute({ args }) {
            return {
                async onExecuteDone({ result }) {
                    // If the result is an async iterable (stream/defer), wrap it.
                    // This allows us to defer cleanup until the entire stream is consumed or the connection is closed.
                    // Standard onExecuteDone fires before the stream is completely consumed.
                    if (Symbol.asyncIterator in result) {
                        const originalIterator = result[Symbol.asyncIterator]();
                        result[Symbol.asyncIterator] = () => ({
                            next: async () => {
                                const next = await originalIterator.next();
                                if (next.done) {
                                    await disposeClients(args.contextValue);
                                }
                                return next;
                            },
                            return: async () => {
                                // If the stream is cancelled/closed early
                                await disposeClients(args.contextValue);
                                return originalIterator.return
                                    ? originalIterator.return()
                                    : { done: true, value: undefined };
                            },
                            throw: async (e) => {
                                await disposeClients(args.contextValue);
                                return originalIterator.throw
                                    ? originalIterator.throw(e)
                                    : { done: true, value: undefined };
                            },
                            [Symbol.asyncIterator]() {
                                return this;
                            },
                        });
                    }
                    else {
                        // Regular execution (single response), clean up immediately.
                        // CRITICAL: Must await to ensure connections are released before response is sent.
                        // Without await, connections accumulate under load faster than they're freed.
                        await disposeClients(args.contextValue);
                    }
                },
            };
        },
    };
}
async function disposeClients(context) {
    // Ensure context still exists and hasn't been corrupted
    if (context?.dbClientsToDispose) {
        await Promise.allSettled(context.dbClientsToDispose.map(client => client.dispose()));
        context.dbClientsToDispose = []; // prevent double disposal
    }
}
//# sourceMappingURL=db-cleanup-plugin.js.map