activity_files 0.5.1
activity_files: ^0.5.1 copied to clipboard
Workout file toolkit for Dart with GPX, TCX, FIT, GeoJSON and CSV parsing, editing, validation, and conversion.
Changelog #
0.5.0 #
Migration #
- Upgrading? This version mitigates the 0.4.0 breaking changes: the 64MB payload limit is now configurable per-call via
maxPayloadBytesand file paths work withallowFilePaths: trueor by passingFileobjects.
Added #
- CSV & GeoJSON Support: Full import/export for CSV and GeoJSON formats with roundtrip testing.
- Public API Methods: Facade methods for CSV/GeoJSON:
exportToCsv(),importFromCsv(),exportToGeojson(),exportToGeojsonPoints(),importFromGeojson(). - Better Error Messages: All exceptions now include actionable recovery hints and troubleshooting steps.
- Parser Performance: XML element caching and batch lookups reduce parsing time by 2-5x for large files (5000+ points).
- Full Garmin TrackPointExtension v2 schema support: GPX parser and encoder now handle all v2 fields (
wtemp,depth,speed,course,bearing) plus existing v1 fields (hr,cad,power,atemp) with corresponding channel types andChannelSnapshotaccessors. - Expanded FIT manufacturer database from 28 to 179 entries for comprehensive device identification.
- Multi-sport activity support: TCX and FIT parsers handle triathlon files with multiple sport segments. New
Lap.sportfield enables per-lap sport tracking, andActivityFiles.merge()/splitBySport()combine or divide multi-sport activities. - FIT session + lap stats are now parsed into
ActivitySummaryand additionalLapfields; extra record fields are surfaced as custom channels. - Added an artificial fixture generator (
scripts/generate_artificial_fixtures.dart) that refreshes sample fixtures for tests and examples. - Lap boundary validation via
RawEditor.validateLapBoundaries()for detecting timing mismatches. - Performance improvements in normalization and hot paths.
- Parser optimization: through eliminating redundant XML traversals, removing case-insensitive string comparisons and caching child element lookups during trackpoint parsing. Large files (>5000 points) see the most benefit.
Changed #
- CSV parser normalizes line endings (
\r\n→\n). - Optimized sport string conversion with caching.
- GPX/TCX parsing now uses batch element lookups instead of repeated traversals.
Lapclass includes optionalsportfield; null values inherit from activity-level sport.- TCX parser sport mapping extended to include swimming.
- Test suite reorganized into focused categories with shared fixtures. See
doc/testing.mdfor details. - Payload limit now configurable per-call via optional
maxPayloadBytesparameter (default: 64MB).
Fixed #
- FIT parser now fails gracefully (with diagnostics) instead of crashing when a data message references an unknown local definition (e.g. issue #2 user fixture). New diagnostics:
fit.data.unknown_definition,fit.no_usable_data.
0.4.4 #
Added #
- New Unit tests
- New Integration tests
- Synthetic test data generator with clean fixtures
0.4.3 #
Fixed #
- Fix FIT parser to remove corrupted data points with invalid timestamps or coordinates, ensuring FIT→GPX and FIT→TCX output matches reference files
0.4.2 #
Fixed #
- Fix FIT parser for non-standard message ordering. Thanks @hallr-boulder for reporting (fixes #2)
- Improved support for swimming activity files with non-standard message ordering
- Parser now gracefully handles unknown message types instead of crashing
0.4.0 #
Breaking #
- Plain string sources are always treated as inline payloads; pass a
Fileor setallowFilePaths: trueonload/convert/convertAndExport/ActivityExportRequest.fromSourceto read from disk. - A 64MB cap (
ActivityFiles.defaultMaxPayloadBytes) applies to load/convert/detect and streamed pipelines; oversized inputs throw or emit error diagnostics. Stream from disk/network or split files to go larger; onlyActivityParser.parseStream(maxBytes: ...)lets you override the limit.
Added #
- Stream-backed loads are replayable;
ActivityLoadResult.bytesPayloadexposes buffered bytes even when the source was aStream<List<int>>. - FIT integrity: header/trailer CRCs and truncation are reported as error
diagnostics (or throw when
strictFitIntegrity: true); the encoder now emits invalid coordinate sentinels for sensor-only activities. - Structural validation enforces lap ordering/overlap and warns when sensor channels extend past the point timeline during load/convert/export flows.
- GPX/TCX version selection:
EncoderOptionsand CLI flags can emit GPX 1.0/1.1 and TCX v1/v2; defaults remain GPX 1.1/TCX v2. FIT remains core-workout only. - GPX 1.0 round-trips root metadata, track extensions, and labels when
gpxVersionisGpxVersion.v1_0.
Changed #
RawTransformsandRawEditorlive in dedicated modules (transforms/raw_transforms.dart,transforms/raw_editor.dart);transforms.dartstill exports both for existing imports.ChannelMapper.cursorexposes reusable per-channel cursors;mapAtnow wraps it so overlays reuse cached lookups.- GPX/TCX/FIT encoders reuse the cursor (TCX/FIT also use distance readings) to avoid repeated binary searches.
- Resampling pre-sizes timetables and reuses sliding cursors to keep
RawTransforms.resample/_resampleNearestfast on long recordings. RawEditorskips work on sorted/valid inputs and reuses its timestamp cursor duringdownsampleTime.- FIT exports defer base64 decoding until
asBytes()when FIT sources arrive as base64 strings. RawEditor.smoothHRnow uses a sliding window to stay O(n).
Fixed #
RawEditor.downsampleDistancekeeps the final point even on short hops or duplicate timestamps, preserving distance/duration and channel alignment.RawEditor.markLapsByDistancerecovers from non-monotonic distance channels (e.g. pause resets) to keep splits accurate.RawEditor.smoothHRrespects even-numbered windows instead of averaging an extra sample.- Format detection inspects only a small prefix and honors payload caps.
- Exports with
normalize: falseauto-sort/dedup when needed;recomputeDistanceAndSpeedalso self-sorts to avoid invalid speed/distance. RawEditor.sortAndDedupclones lists before sorting to keep priorRawActivityinstances immutable.- Malformed GPX/TCX and invalid FIT binaries now return structured
ParseDiagnosticerrors instead of raw exceptions. - Stream parsing (
parseStream,convertAndExportStream,runPipelinewith streams) returns diagnostics for malformed/oversized payloads instead of throwing. - CLI
converthonors explicit--encoding, reads GPX/TCX as bytes to avoid Latin-1 corruption, and exits non-zero on parser errors. ActivityFiles.runPipelineno longer runs validation twice whenrunValidationis enabled.RawActivity.copyWithkeeps collections immutable, recognizes canonical inputs to avoid clones, and reuses cached distances.RawTransforms.resamplesorts points before resampling to avoid RangeErrors and keep start/end ordering.ActivityFiles.convertenforces the export ordering guard whennormalizeisfalse;detectFormatno longer probes filesystem paths unless allowed.
0.3.1 #
Fixed #
ActivityFiles.load/convertnow honor theencodingparameter for GPX/TCX byte payloads (without BOMs), so Latin-1 and other single-byte exports no longer throwFormatException.ActivityParser.parseBytesexposes anencodingargument for callers that read non-UTF-8 text files directly into byte buffers.
0.3.0 #
Added #
ActivityFiles.exportproduces encoded payloads with optional validation, normalization, and aggregated diagnostics in a single helper.ActivityFiles.convertAndExportexposes the same workflow directly from raw sources, including optional validation.ActivityFiles.exportAsyncandconvertAndExportStreammirror the export workflow off the UI thread and for streamed payloads.ActivityExportRequestandActivityFiles.runPipelinelet callers describe parse → normalize → export pipelines with consistent isolate controls.- Diagnostic summary getters (
warningCount,hasErrors,diagnosticsSummary, etc.) are now available on load, conversion, and export results to simplify UI surfacing. ActivityProcessingStatsandNormalizationStatscapture normalization and validation metrics alongside export diagnostics.- Facade convenience wrappers expose common transforms (
sortAndDedup,trimInvalid,smoothHeartRate,crop), structural validation, and channel snapshots. RawActivityandRawActivityBuildergained device metadata and namespace aware GPX extension support, enabling richer encoder output without custom glue.DiagnosticsFormatterprovides reusable helpers for summarisingParseDiagnosticcollections across logs and UI surfaces.- Stream-aware builder/export helpers (
builderFromStreams,convertAndExportwithlocation/channels) accept timestamp/value tuples so backends can export without manual model translation. ActivityFiles.registerSportMappersupplies pluggable sport inference and ships string/ID heuristics for common wearable categories.- GPX encoders honour builder-supplied metadata/track names and expose helper
factories (
gpxActivityLabelNode,gpxDeviceSummaryNode) for custom extensions with automatic namespace registration.
Changed #
- GPX encoder now emits device metadata and custom extensions, automatically declaring any additional namespaces used.
- TCX encoder/parser preserve device metadata and custom extensions, and FIT files now round-trip device metadata, including explicit manufacturer/product identifiers supplied via
ActivityDeviceMetadata. ActivityFiles.convertandconvertAndExportnow acceptexportInIsolate, bringing isolate offloading parity while ensuring FIT byte caches refresh when the encoded payload changes.
Fixed #
RawEditor.markLapsByDistancenow reports per-split distances correctly and always emits a trailing partial lap when applicable, ensuring summary totals stay accurate.RawEditor.downsampleTimekeeps the final point in the activity and performs sample matching without quadratic scans, avoiding data loss on closely spaced tracks.- Channel deduplication retains the most recent sample when multiple readings share the same timestamp instead of discarding later values.
ActivityFiles.channelSnapshotnow uses binary search when resolving channel samples, reducing lookup cost from O(n) to O(log n) for large time-series streams.
0.2.0 #
Added #
- Asynchronous parsing surface:
ActivityParser.parseAsync,parseBytesAsync, andparseStreamoptionally offload work to isolates for smoother UIs and streaming IO. ActivityFilesfacade providing ergonomicload,convert, andedithelpers tailored for app integrations.RawActivityBuilderfor incremental creation of activities.- Asset-backed integration tests cover
ActivityFiles.load,detectFormat, and conversion flows with real GPX/TCX/FIT fixtures.
Changed #
- GPX, TCX, and FIT parsers emit structured diagnostics instead of raw strings.
- Converter, CLI, documentation, examples, and tests now surface diagnostics in output flows.
- README/example now highlight the high-level facade and builder workflows.
- Added facade-focused regression tests covering format detection and builder seeding.
Deprecated #
ActivityParseResult.warningsremains available but now forwards to the new structured diagnostics; it is marked deprecated to encourage migration.ActivityConverter.convertstill accepts thewarningsparameter, which is deprecated in favor of the richerdiagnosticssink.
0.1.0 #
Added #
- Handle FIT compressed timestamp headers and ensure unknown message types advance the reader instead of hanging.
- Add
ActivityParser.parseBytes, broadenActivityConverter.convertinput support, and let the CLI operate on raw FIT binaries without manual base64. - Document the new FIT workflow and add regression coverage for compressed headers.