pulse_ops 1.4.0
pulse_ops: ^1.4.0 copied to clipboard
Flutter-native developer toolkit for in-app network inspection, cURL export, log sharing, shake-to-open, and crash diagnostics with breadcrumbs.
Changelog #
All notable changes to PulseOps will be documented in this file. The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
1.4.0 โ 2026-06-25 #
๐งช Test Observability #
Testing Tools
- Widget test logging โ
PulseTestObserver.log()captures freeform messages into the active test session with severity levels (debug / info / warning / error). - Integration test tracking โ
PulseTestObserver.beginTest()/PulseTestObserver.endTest()create boundedTestSessionrecords with name, group, status, timing, and a full event timeline. - API logs during tests โ
PulseTestObserver.captureNetworkRequest()attaches anyNetworkRecordfromPulseDioInterceptorto the active session, so you can see exactly which API calls were made (and whether they succeeded) per test. - Test timelines โ each session stores an ordered
List<TestEvent>with typed events:log,networkRequest,assertion,widgetPump,performance,failureโ visible as a visual connector timeline in the inspector. - Failure diagnostics โ
PulseTestObserver.endTest(passed: false, failureMessage: ..., stackTrace: ...)records the failure with up to 12 lines of stack trace displayed in the inspector. - Assertion tracking โ
PulseTestObserver.assertion(description)records named assertion results, coloured green (pass) or red (fail) in the timeline. - Widget pump events โ
PulseTestObserver.pump(frameCount:, duration:)logs pump calls so you can correlate widget rebuilds with API activity. - Performance snapshots โ
PulseTestObserver.capturePerformance(fps:, droppedFrames:)stores FPS/jank data captured during a test.
Reporting
- Exportable test reports โ the Test screen shares reports in JSON (structured, machine-readable) or plain text (human-readable per-session block) via the platform share sheet, falling back to clipboard.
- Pass-rate summary bar โ total / passed / failed counts and percentage pass rate shown at the top of the Test screen.
- Debug logs attachment โ exported JSON includes per-session events and network request summaries, making the report self-contained for CI artefact upload.
New Public API
TestStoreโ in-memory ring-buffer (default 100 sessions, configurable viaPulseOpsConfig.maxTestSessions) withbeginSession/endSession/logEvent/recordNetworkRequest/recordPerformanceand a reactivestream.PulseTestObserverโ static helper; attach a store once per test run withPulseTestObserver.attach(PulseOps.instance.testStore), then usebeginTest/endTest/log/assertion/pump/captureNetworkRequest/capturePerformance.TestReportExporterโ serialises sessions to JSON or plain text.TestSession/TestEvent/TestSessionStatus/TestEventTypeโ immutable value types exported from the public API.PulseOpsConfig.enableTestObservabilityโ opt-in flag (defaultfalse).PulseOpsConfig.maxTestSessionsโ ring-buffer capacity (default100).
๐ฌ Inspector: Tests Screen #
- New ๐งช toolbar button in the inspector opens the Test Observability screen showing a session list with status dots, group labels, failure previews, network/event badges, and a pass-rate summary bar.
- Session detail screen shows a connector-style event timeline with typed badges (LOG / NET / ASSERT / PUMP / PERF / FAIL), per-event timing, and a dedicated API log section with method chip, endpoint, status, and duration.
๐ Enhancements & Bug Fixes #
InMemoryNetworkStoreโ replaced the O(n) linear scan infindByIdandupdatewith anid โ recordhash map index. Both are now O(1), eliminating a latency spike on large request histories (previously O(nยฒ) onupdate).FileBackedNetworkStore._persist()โ added atry/catcharoundwriteAsStringSync; disk-full and permission errors are now silently suppressed instead of crashing the app mid-request.
1.3.0 โ 2026-06-04 #
๐ง Memory Monitoring #
- RSS memory tracking โ polls
ProcessInfo.currentRssevery 2 s (configurable) and stores up to 120 snapshots in a ring buffer. - Memory spike warnings โ samples >20% above the rolling average are flagged and highlighted in the RSS sparkline chart.
- Leak detection โ subscribes to
FlutterMemoryAllocationsto trackChangeNotifier,AnimationController,TextEditingController, and other disposable Flutter objects. Objects not disposed within 30 s are listed as potential leaks with their age. - Widget lifecycle log โ live created/disposed/active counts and a type-breakdown of the top active objects.
- Rebuild tracker โ call
store.recordRebuild(widgetType)(or use the providedPulseRebuildTrackermixin) to track how often each widget rebuilds. Counts appear colour-coded in the Memory screen (red >50, yellow >20). - Memory screen accessible from the inspector toolbar (
๐งbutton), showing the RSS chart, spike warnings, leak list, lifecycle summary, and rebuild counts.
๐พ Persistent Network Store #
FileBackedNetworkStoreโ a drop-inNetworkStorereplacement that persists captured records to a JSON file in the app's documents directory. Records survive app restarts. Pass it toPulseOps.initialize(networkStore:).
๐ก Unified Event Exporter #
PulseEventExporterโ new interface with two callbacks:onFailedRequest(NetworkRecord)andonCrash(error, stack, ...). Implement it and pass it toPulseOps.initialize(eventExporter:)to forward every failed API call and every crash to your own backend in one place.
1.2.0 โ 2026-05-22 #
โก Performance Monitoring #
- Real-time FPS monitor โ subscribes to
WidgetsBindingframe timings and streams FPS data into a rolling 300-frame ring buffer. - Frame drop & jank detection โ frames exceeding 16 ms are flagged as dropped; frames exceeding 33 ms are marked severe jank.
- Startup time tracking โ measures wall-clock time from
PulseOps.initializeto the first rendered frame. - API latency chart โ
CustomPainterbar chart showing the last 40 request durations, coloured green / yellow / red against the slow-request threshold. - FPS sparkline chart โ gradient-filled line chart with 60 fps / 30 fps reference grid lines, coloured by current FPS health.
- Performance screen accessible from the inspector toolbar (
โกbutton), showing startup banner, FPS stats, frame drop list, and latency charts.
๐ Inspector Improvements #
- Slow filter chip โ one-tap filter to show only requests that exceeded the
configured
slowRequestThresholdMs. - Status-family filter chips โ filter by
2xx,3xx,4xx, or5xxresponse families. - Wider search โ search now matches against host name and error message in addition to URL, method, and status code.
1.1.1 โ 2026-05-21 #
๐ Bug Fixes #
- Fixed
No Directionality widget foundcrash on Android and iOS when thePulseOverlayStackwas mounted above the host app'sMaterialApp. The overlay now wraps theStackin an explicitDirectionality(ltr). - Fixed
RenderFlex overflowedyellow-stripe inRequestTilewhen the host name is long (e.g.jsonplaceholder.typicode.com). The hostTextis now wrapped inFlexibleso it ellipsises instead of overflowing.
๐ Documentation #
- Added a Sentry adapter code snippet to the README โ drop-in equivalent
of the existing Firebase Crashlytics adapter. Covers non-fatal, fatal,
breadcrumbs, network history, and custom tags via
Sentry.configureScope. - Updated CI workflow (
publish.yml) to useflutter pub get,flutter analyze, andflutter testinstead of their baredartequivalents, fixing the "Flutter users should use flutter pub" error in GitHub Actions.
1.1.0 โ 2026-05-16 #
๐ Debug Overlay #
- Shake-to-open: shaking the device launches the inspector. Tunable via
PulseOpsConfig.enableShakeToOpenandshakeThreshold. Powered bysensors_plusand silently no-ops when an accelerometer is unavailable. - Expandable bottom sheet: the inspector now slides up as a draggable
bottom sheet with 40 / 70 / 95 % snap points instead of a full-screen
route. Switch back via
PulseOpsConfig(inspectorPresentation: InspectorPresentation.fullScreen).
โจ Developer Experience #
- Log export: new export menu in the inspector (JSON / plain text / cURL)
that opens the platform share sheet via
share_plusand falls back to clipboard. Programmatic exports available viaNetworkLogExporter.
Migration #
PulseOps.openInspectornow respectsinspectorPresentation. Existing callers continue to work unchanged.
1.0.0 โ 2026-05-16 #
Initial public release.
๐ Network Inspector #
- Dio interceptor (
PulseDioInterceptor) capturing request, response, headers, query params, timing, sizes, and errors. - In-memory ring-buffer store (
InMemoryNetworkStore) with configurable capacity and reactive stream API. - Beautiful dark Material 3 inspector UI:
- Newest-first timeline with method, status, host, duration, timestamp.
- Live search and filter chips (
GET/POST/PUT/PATCH/DELETE, plus "failed only"). - Per-request detail screen with Overview, Headers, Request, Response, and cURL tabs.
- Syntax-highlighted JSON viewer with copy-to-clipboard.
- One-tap cURL export via
CurlBuilderwith proper shell escaping. - One-tap retry using a host-provided Dio instance.
- Multipart (
FormData) request description, including filenames + sizes. - Header / body sanitization for sensitive keys.
๐ฅ Crash Diagnostics #
- Backend-agnostic
PulseCrashReporterinterface with shippedNoopCrashReporterand a documented Firebase Crashlytics adapter. BreadcrumbTrailring buffer withdebug/info/warning/errorlevels.- Automatic non-fatal reporting for failed Dio requests, with recent request summary attached as context.
- Manual breadcrumb + error APIs:
PulseOps.instance.log(...),PulseOps.instance.recordError(...). - Optional global
FlutterError.onErrorandPlatformDispatcher.onErrorinstallation.
Developer Experience #
- Single-call
PulseOps.initialize(...)with shorthandcrashlytics,enableInRelease, andsanitizeKeysnamed args. PulseOps.instance.wrap(child:)to mount the draggable floating overlay launcher around any widget tree.PulseOps.instance.openInspector(context)to push the inspector from a debug menu without the overlay.- Production-safe: inspector and overlay are disabled in release builds
unless
enableInReleaseis explicitly set. - Comprehensive test suite covering sanitizer, cURL builder, store, breadcrumb trail, interceptor, and facade.