withRequestScope<T> static method

Future<T> withRequestScope<T>(
  1. FutureOr<T> body(
    1. BloomQueryScope scope
    ), {
  2. BloomQueryScope? scope,
  3. String? debugLabel,
})

Runs body in a fresh request scope, disposing it afterwards.

If scope is supplied, it is used and NOT disposed (caller owns it). Otherwise a new scope is created and disposed after body completes, including async completion and sync/async errors.

For streaming (Stream results), prefer withRequestScopeStream so the scope stays alive until the stream closes, errors, or is cancelled.

final html = await BloomData.withRequestScope((scope) async {
  BloomData.setQueryData(['user', 'current'], (_) => alice);
  final html = renderToHtml(page());
  return html;
});

Implementation

static Future<T> withRequestScope<T>(
  FutureOr<T> Function(BloomQueryScope scope) body, {
  BloomQueryScope? scope,
  String? debugLabel,
}) async {
  final effective =
      scope ?? BloomQueryScope(debugLabel: debugLabel ?? 'ssr-request');
  final owned = scope == null;
  try {
    final result = runZoned(() => body(effective),
        zoneValues: {scopeZoneKey: effective});
    if (result is Future<T>) {
      try {
        return await result;
      } finally {
        if (owned) effective.dispose();
      }
    } else {
      // Sync result (T is not a Future). Dispose owned scope now.
      if (owned) effective.dispose();
      return result;
    }
  } catch (_) {
    if (owned) effective.dispose();
    rethrow;
  }
}