pulse_dev 0.1.0 copy "pulse_dev: ^0.1.0" to clipboard
pulse_dev: ^0.1.0 copied to clipboard

Pure Dart core for the Pulse Developer Intelligence SDK. Provides event models, the event pipeline, transport and storage interfaces, privacy sanitization, breadcrumb buffering, performance instrument [...]

pulse_dev #

pub.flutter-io.cn CI License: MIT

Pure Dart core for the Pulse Developer Intelligence SDK.

pulse_dev is Flutter-free and works in any Dart project β€” Flutter apps, CLI tools, or server-side Dart. It provides the event model, processing pipeline, privacy engine, network observer, performance instrumentation, and offline storage β€” all behind clean, replaceable interfaces.

For Flutter applications, use pulse_dev_flutter which builds on this package and provides the Pulse static API.


Features #

  • πŸ“¦ Typed event model β€” ErrorEvent, ExceptionEvent, BreadcrumbEvent, CustomEvent, NetworkEvent, TransactionEvent
  • πŸ”€ Composable pipeline β€” pluggable EventProcessor chain β†’ sanitizer β†’ transport
  • πŸ”’ Privacy-first sanitization β€” recursive PII redaction for 20+ sensitive key patterns out of the box
  • 🌐 Network monitoring β€” framework-agnostic PulseNetworkObserver; adapters for dio and package:http sold separately
  • ⚑ Performance tracking β€” transactions, spans, and slow operation detection
  • πŸ’Ύ Offline queue β€” FIFO event queue with exponential backoff, configurable retry, and expiration
  • πŸ”Œ Pluggable transport β€” implement PulseTransport to send events anywhere
  • πŸ§ͺ Fully testable β€” injectable Clock, IdGenerator, PulseTransport, and PulseStorage

Installation #

dependencies:
  pulse_dev: ^0.1.0

For Flutter projects, use pulse_dev_flutter instead β€” it re-exports everything from this package.


Quick Start (pure Dart) #

import 'package:pulse_dev/pulse_dev.dart';

final config = PulseConfig(
  dsn: 'https://key@ingest.example.com/1',
  environment: 'production',
  release: '1.0.0',
  transport: MyHttpTransport(),
);

final pipeline = EventPipeline.fromConfig(config);

try {
  await riskyOperation();
} catch (e, st) {
  await pipeline.process(ExceptionEvent(
    id: const UuidGenerator().newId(),
    timestamp: const SystemClock().now(),
    sdkVersion: kPulseSdkVersion,
    appVersion: config.release,
    environment: config.environment,
    platform: PulsePlatform.dart,
    context: PulseContext.empty,
    exceptionType: e.runtimeType.toString(),
    message: e.toString(),
    stackTrace: st.toString(),
    breadcrumbs: const [],
    handled: true,
  ));
}

Custom Transport #

Implement PulseTransport to deliver events to your backend:

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:pulse_dev/pulse_dev.dart';

final class MyHttpTransport implements PulseTransport {
  final Uri _endpoint;
  final String _apiKey;

  MyHttpTransport({required Uri endpoint, required String apiKey})
      : _endpoint = endpoint,
        _apiKey = apiKey;

  @override
  Future<PulseTransportResult> send(PulseEvent event) async {
    try {
      final response = await http.post(
        _endpoint,
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_apiKey',
        },
        body: jsonEncode(event.toJson()),
      );
      if (response.statusCode == 429 || response.statusCode >= 500) {
        return PulseTransportResult.retryableFailure;
      }
      if (response.statusCode >= 400) {
        return PulseTransportResult.permanentFailure;
      }
      return PulseTransportResult.success;
    } catch (_) {
      return PulseTransportResult.retryableFailure;
    }
  }

  @override
  Future<void> close() async {}
}

Custom Sanitizer #

Override sensitive data redaction for your organisation's needs:

import 'package:pulse_dev/pulse_dev.dart';

final class MyOrgSanitizer extends DefaultSanitizer {
  MyOrgSanitizer()
      : super(
          config: const PulseSanitizationConfig(
            additionalRedactedKeys: {
              'employee_id',
              'internal_project_code',
              'client_secret',
            },
          ),
        );
}

Custom Event Processor #

Enrich or filter events before transport:

import 'package:pulse_dev/pulse_dev.dart';

final class EnvironmentTagProcessor implements EventProcessor {
  final String region;

  const EnvironmentTagProcessor({required this.region});

  @override
  PulseEvent? process(PulseEvent event) {
    if (event is CustomEvent) {
      return CustomEvent(
        // copy fields and add region tag
        properties: {...event.properties, 'region': region},
        // ... other fields
      );
    }
    return event; // pass-through for other event types
  }
}

Network Monitoring #

import 'package:pulse_dev/pulse_dev.dart';

final observer = PulseNetworkObserver(
  pipeline: pipeline,
  config: PulseNetworkConfig(
    enabled: true,
    captureHeaders: false,          // never capture headers by default
    captureBody: false,             // never capture body by default
    redactQueryParameters: const {'token', 'api_key'},
  ),
);

// Use with an HTTP adapter:
// - package:pulse_http β†’ PulseHttpClient
// - package:pulse_dio  β†’ PulseDioInterceptor

Performance Tracking #

import 'package:pulse_dev/pulse_dev.dart';

final transaction = pipeline.startTransaction('checkout_flow');

try {
  final span = transaction.startSpan('validate_cart');
  await validateCart();
  span.finish();

  final paySpan = transaction.startSpan('process_payment');
  await processPayment();
  paySpan.finish();

  transaction.finish(status: 'ok');
} catch (e, st) {
  transaction.finish(status: 'error', error: e);
  rethrow;
}

Configuration Reference #

PulseConfig(
  dsn: 'https://key@ingest.example.com/1',   // required
  environment: 'staging',                     // default: 'production'
  release: '2.0.0+42',                        // app version string
  debug: true,                                // verbose SDK logging
  enabled: true,                              // global kill-switch
  sampleRate: 0.25,                           // drop 75% of events (0.0–1.0)
  maxBreadcrumbs: 50,                         // breadcrumb ring buffer size
  transport: MyHttpTransport(),               // your delivery implementation
  sanitizer: MyOrgSanitizer(),               // custom privacy sanitization
  logger: MyDebugLogger(),                    // custom SDK-internal logging
  processors: [EnvironmentTagProcessor()],   // event enrichment chain
  network: PulseNetworkConfig(...),           // network monitoring options
  performance: PulsePerformanceConfig(...),   // performance monitoring options
  sanitization: PulseSanitizationConfig(...), // sanitization options
)

Package Description
pulse_dev_flutter Flutter integration β€” Pulse static API, error hooks, debug inspector
pulse_http package:http network adapter
pulse_dio package:dio network interceptor

Contributing #

See CONTRIBUTING.md.

License #

MIT β€” see LICENSE.

0
likes
140
points
31
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Pure Dart core for the Pulse Developer Intelligence SDK. Provides event models, the event pipeline, transport and storage interfaces, privacy sanitization, breadcrumb buffering, performance instrumentation, offline queueing, and configuration. Flutter-free β€” suitable for any Dart project.

Repository (GitHub)
View/report issues
Contributing

Topics

#monitoring #error-reporting #observability #analytics #sdk

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

meta, uuid

More

Packages that depend on pulse_dev