trackswap 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +16 -0
  2. package/dist/FIT/base.d.ts +30 -0
  3. package/dist/FIT/decoder.d.ts +48 -0
  4. package/dist/FIT/encoder.d.ts +96 -1
  5. package/dist/FIT/encoderCourse.d.ts +45 -0
  6. package/dist/FIT/encoderWorkout.d.ts +45 -0
  7. package/dist/FIT/health.d.ts +191 -4
  8. package/dist/FIT/index.d.ts +1 -1
  9. package/dist/FIT/mesg.d.ts +3 -0
  10. package/dist/FIT/middleware.d.ts +15 -0
  11. package/dist/FIT/plugins.d.ts +9 -0
  12. package/dist/FIT/processor.d.ts +24 -0
  13. package/dist/FIT/types/checksum_type.d.ts +6 -0
  14. package/dist/FIT/types/date_time_type.d.ts +3 -0
  15. package/dist/FIT/types/file.d.ts +63 -0
  16. package/dist/FIT/types/file_flags_type.d.ts +9 -0
  17. package/dist/FIT/types/local_date_time_type.d.ts +3 -0
  18. package/dist/FIT/types/mesg_count_type.d.ts +6 -0
  19. package/dist/FIT/types/mesg_num.d.ts +369 -0
  20. package/dist/FIT/types/message_index_type.d.ts +6591 -0
  21. package/dist/FIT/types/sport.d.ts +44 -44
  22. package/dist/FIT/types.d.ts +509 -0
  23. package/dist/GPX/base.d.ts +24 -0
  24. package/dist/GPX/converters.d.ts +44 -0
  25. package/dist/GPX/decoder.d.ts +66 -0
  26. package/dist/GPX/encoder.d.ts +109 -0
  27. package/dist/GPX/middleware.d.ts +9 -0
  28. package/dist/GPX/processor.d.ts +18 -0
  29. package/dist/GPX/types.d.ts +138 -0
  30. package/dist/TCX/base.d.ts +33 -0
  31. package/dist/TCX/converters.d.ts +33 -0
  32. package/dist/TCX/decoder.d.ts +54 -0
  33. package/dist/TCX/encoder.d.ts +116 -0
  34. package/dist/TCX/middleware.d.ts +12 -0
  35. package/dist/TCX/processor.d.ts +30 -0
  36. package/dist/TCX/types.d.ts +13 -0
  37. package/dist/TrackSwap.d.ts +4 -0
  38. package/dist/activity/base.d.ts +54 -0
  39. package/dist/activity/converters.d.ts +57 -0
  40. package/dist/activity/encoders.d.ts +34 -0
  41. package/dist/activity/metrics/MetricsCalculator.d.ts +30 -0
  42. package/dist/activity/processor.d.ts +31 -0
  43. package/dist/core/base.d.ts +46 -0
  44. package/dist/core/builtin-adapters.d.ts +1 -0
  45. package/dist/core/xml-utils.d.ts +24 -0
  46. package/dist/errors.d.ts +1 -1
  47. package/dist/fit-debug.d.ts +3 -0
  48. package/dist/index.cjs +5 -5
  49. package/dist/index.d.ts +2 -2
  50. package/dist/index.js +5 -5
  51. package/dist/types.d.ts +102 -1
  52. package/dist/util.d.ts +9 -0
  53. package/package.json +3 -2
@@ -4,37 +4,94 @@ import { ActivityRecordType } from "../types.js";
4
4
  import { WptType } from "../GPX/types.js";
5
5
  import { RecordMesgType } from "../FIT/types.js";
6
6
  import { TrackpointType } from "../TCX/types.js";
7
+ /**
8
+ * GPX to Activity converter
9
+ */
7
10
  export declare class GPXToActivityConverter extends BaseActivityConverter {
8
11
  name: string;
9
12
  supportedTags: string[];
10
13
  convert(ast: TokenAST, context: ActivityContext): FileType | undefined;
11
14
  private convertGPX;
15
+ /**
16
+ * 将 Wpt 转为 ActivityRecordType
17
+ * @param point
18
+ * @param idx
19
+ * @returns
20
+ */
12
21
  protected convertPoint(point: WptType, idx?: number, lapIdx?: number): ActivityRecordType;
22
+ /**
23
+ * 将 trk 转为 Activity
24
+ * @param trk
25
+ * @param idx
26
+ * @returns
27
+ */
13
28
  private convertTrk2Activity;
29
+ /**
30
+ * 将 trkseg 转为 lap
31
+ * @param seg
32
+ * @param idx
33
+ * @returns
34
+ */
14
35
  private convertTrackSeg2Lap;
15
36
  private convertRoute2Lap;
16
37
  private convertPoints2Lap;
38
+ /**
39
+ * 将 GPX 的 wpt[] 转为 ActivityRecordType 数组
40
+ * @param wpts
41
+ * @returns
42
+ */
17
43
  private convertWpts2Points;
18
44
  private convertGPXExtensions;
19
45
  private autoNumber;
20
46
  }
47
+ /**
48
+ * FIT to ActivityType converter
49
+ */
21
50
  export declare class FITToActivityConverter extends BaseActivityConverter {
22
51
  name: string;
23
52
  supportedTags: string[];
24
53
  convert(ast: TokenAST, context: ActivityContext): FileType | undefined;
25
54
  private convertFIT;
55
+ private convertFITStrengthSets;
56
+ /**
57
+ * 将 FIT 的 recordMesg 转为 ActivityRecordType
58
+ * @param point
59
+ * @param idx
60
+ * @returns
61
+ */
26
62
  protected convertPoint(point: RecordMesgType, idx?: number, lapIdx?: number): ActivityRecordType | undefined;
63
+ /**
64
+ *
65
+ * @param laps
66
+ * @returns
67
+ */
27
68
  private convertFITLap2Trackseg;
28
69
  private convertLap2Points;
29
70
  }
71
+ /**
72
+ * TCX to ActivityType converter
73
+ */
30
74
  export declare class TCXToActivityConverter extends BaseActivityConverter {
31
75
  name: string;
32
76
  supportedTags: string[];
33
77
  convert(ast: TokenAST, context: ActivityContext): FileType | undefined;
34
78
  private convertTCX;
79
+ /**
80
+ * TCX Course → FileType.routes(每条 Course 对应一条 route lap)
81
+ */
35
82
  private convertTCXCourseToRoute;
36
83
  private convertTCXCoursePointToRecord;
84
+ /**
85
+ * 将 tcx 的 activity 转为 ActivityType
86
+ * @param activity
87
+ */
37
88
  private convertTCXActivityToActivity;
89
+ /**
90
+ * 将 TCX Lap 转为 ActivityLapType
91
+ * @param lap
92
+ * @param idx
93
+ * @returns
94
+ */
38
95
  private convertTCXLap2Lap;
39
96
  protected convertPoint(point: TrackpointType, idx?: number, lapIdx?: number): ActivityRecordType;
40
97
  }
@@ -3,32 +3,66 @@ import { FileType } from "../types.js";
3
3
  import { GPX11Type } from "../GPX/types.js";
4
4
  import { FITFileType } from "../FIT/types.js";
5
5
  import { TCXFileType } from "../TCX/types.js";
6
+ /**
7
+ * ActivityType to GPX encoder
8
+ */
6
9
  export declare class ActivityToGPXEncoder extends BaseActivityEncoder {
7
10
  name: string;
8
11
  supportedTags: string[];
9
12
  encode(file: FileType, context: ActivityEncodingContext): GPX11Type | undefined;
13
+ /** GPX trkpt/wpt/rtept require finite coordinates in range. */
10
14
  private hasValidGpxCoordinates;
15
+ /** Count sample rows that have no usable lat/lon for GPX geometry. */
11
16
  private countRecordsMissingGpxCoordinates;
17
+ /**
18
+ * 将 ActivityPoint 转为 GPX 的 WPT Type 与 GPX1.1 映射
19
+ * @param points
20
+ * @return gpx
21
+ */
12
22
  private convertRecords2Wpts;
13
23
  private convertRoute2GPXRoute;
24
+ /**
25
+ * 转换 ActivityType 到 GPX TrkType
26
+ * @param track
27
+ * @returns
28
+ */
14
29
  private convertActivity2GPXTrack;
30
+ /**
31
+ *
32
+ * @param point
33
+ * @returns
34
+ */
15
35
  private extractGPXExtensions;
16
36
  }
37
+ /**
38
+ * ActivityType to FIT encoder
39
+ */
17
40
  export declare class ActivityToFITEncoder extends BaseActivityEncoder {
18
41
  name: string;
19
42
  supportedTags: string[];
20
43
  encode(file: FileType, context: ActivityEncodingContext): FITFileType | undefined;
44
+ /**
45
+ * 仅含路线(无 session 活动)时,合成单 session + 多 lap,供活动型 FIT 编码器写入。
46
+ */
21
47
  private convertRoutesToSyntheticSession;
22
48
  private convertActivity2FITSession;
23
49
  private convertLap2FITLap;
24
50
  private convertPoint2FITRecord;
25
51
  }
52
+ /**
53
+ * ActivityType to TCX encoder
54
+ */
26
55
  export declare class ActivityToTCXEncoder extends BaseActivityEncoder {
27
56
  name: string;
28
57
  supportedTags: string[];
29
58
  encode(file: FileType, context: ActivityEncodingContext): TCXFileType | undefined;
30
59
  private convertActivity2TCXActivity;
31
60
  private convertLap2TCXLap;
61
+ /**
62
+ * 将 ActivityPoint 转为 TCX TrackpointType
63
+ * @param records
64
+ * @returns
65
+ */
32
66
  private convertRecords2TCXTrack;
33
67
  private convertPoint2TCXTrackpoint;
34
68
  private validTimestamp;
@@ -1,4 +1,7 @@
1
1
  import { ActivityType, ActivityLapType, ActivityRecordType } from "../../types.js";
2
+ /**
3
+ * 指标计算结果接口
4
+ */
2
5
  interface MetricsRecordsResult extends Partial<ActivityLapType> {
3
6
  records: ActivityRecordType[];
4
7
  }
@@ -7,12 +10,39 @@ interface MetricsLapsResult extends Partial<ActivityType> {
7
10
  laps: ActivityLapType[];
8
11
  }
9
12
  export declare class MetricsAggregator {
13
+ /**
14
+ * record 数据聚合计算器 将 record 通过计算后输出
15
+ */
10
16
  calculateRecordsAggMetrics(records: ActivityRecordType[]): MetricsRecordsResult | undefined;
17
+ /**
18
+ * 将 laps 数据聚合起来,返回给 Activity
19
+ * @param laps
20
+ * @returns
21
+ */
11
22
  calculateLapAggMetrics(laps: ActivityLapType[]): MetricsLapsResult | undefined;
23
+ /**
24
+ * 对 record 数据进行预处理
25
+ * 由于 record 数据来自 FIT、TCX、GPX 可能存在缺失、异常等问题,所以需要提前对数据进行清洗和补全
26
+ */
12
27
  private preprocessRecords;
28
+ /**
29
+ * 计算两点间距离(使用 geolib 的高精度算法)
30
+ * @param prevPoint 前一个点
31
+ * @param currPoint 当前点
32
+ * @returns 距离(米),如果无法计算则返回 undefined
33
+ */
13
34
  private calculatePointDistanceByPosition;
35
+ /**
36
+ * 计算瞬时速度
37
+ */
14
38
  private calculateInstantSpeed;
39
+ /**
40
+ * 计算累计功率(功)
41
+ */
15
42
  private calculateAccumulatedPower;
43
+ /**
44
+ * 计算两点爬升和下降
45
+ */
16
46
  private calculateElevationChanges;
17
47
  }
18
48
  export {};
@@ -3,17 +3,48 @@ import { FileType } from "../types.js";
3
3
  import { GPX11Type } from "../GPX/types.js";
4
4
  import { FITFileType } from "../FIT/types.js";
5
5
  import { TCXFileType } from "../TCX/types.js";
6
+ /**
7
+ * Activity processor
8
+ * Responsible for managing conversion and encoding processes
9
+ */
6
10
  export declare class ActivityProcessor {
7
11
  private converters;
8
12
  private encoders;
9
13
  constructor();
14
+ /**
15
+ * Register default converters
16
+ */
10
17
  private registerDefaultConverters;
18
+ /**
19
+ * Register default encoders
20
+ */
11
21
  private registerDefaultEncoders;
22
+ /**
23
+ * Register converter
24
+ */
12
25
  registerConverter(converter: IActivityConverterPlugin): void;
26
+ /**
27
+ * Register encoder
28
+ */
13
29
  registerEncoder(encoder: IActivityEncoderPlugin): void;
30
+ /**
31
+ * Convert native format to FileType
32
+ */
14
33
  convertToActivity(sourceData: GPX11Type | FITFileType | TCXFileType, sourceFormat: "gpx" | "fit" | "tcx"): Promise<FileType>;
34
+ /**
35
+ * Encode ActivityType to native format
36
+ */
15
37
  encodeActivity(file: FileType, targetFormat: "gpx" | "fit" | "tcx"): Promise<GPX11Type | FITFileType | TCXFileType>;
38
+ /**
39
+ * Find converter
40
+ */
16
41
  private findConverter;
42
+ /**
43
+ * Find encoder
44
+ */
17
45
  private findEncoder;
46
+ /**
47
+ * Destroy processor, clean up resources
48
+ */
18
49
  destroy(): Promise<void>;
19
50
  }
@@ -1,39 +1,76 @@
1
1
  import { ExtensionsType, Token, TokenAST } from "../types.js";
2
+ /**
3
+ * Generic plugin interface
4
+ */
2
5
  export interface IPlugin<TContext = any> {
6
+ /** Plugin name */
3
7
  name: string;
8
+ /** Plugin version */
4
9
  version?: string;
10
+ /** Plugin description */
5
11
  description?: string;
12
+ /** Dependencies on other plugins */
6
13
  dependencies?: string[];
14
+ /** Supported tags */
7
15
  supportedTags?: string[];
16
+ /** Plugin initialization */
8
17
  initialize?(context: TContext): Promise<void> | void;
18
+ /** Plugin destruction */
9
19
  destroy?(context: TContext): Promise<void> | void;
20
+ /** Plugin validation */
10
21
  validate?(context: TContext): Promise<boolean> | boolean;
11
22
  }
23
+ /**
24
+ * Generic converter plugin interface
25
+ */
12
26
  export interface IConverterPlugin<TContext = any> extends IPlugin<TContext> {
27
+ /** Conversion method */
13
28
  convert(ast: TokenAST, context: TContext): any | undefined;
29
+ /** Whether it supports the tag */
14
30
  supports(tag: string): boolean;
31
+ /** Priority (lower number = higher priority) */
15
32
  priority?: number;
16
33
  }
34
+ /**
35
+ * Generic middleware plugin interface
36
+ */
17
37
  export interface IMiddlewarePlugin<TContext = any, TResult = any> extends IPlugin<TContext> {
38
+ /** Priority (lower number = higher priority) */
18
39
  priority?: number;
40
+ /** Execute during tokenize stage */
19
41
  onTokenize?(tokens: Token[], context: TContext): Promise<Token[]> | Token[];
42
+ /** Execute during AST generation stage */
20
43
  onAstGenerate?(ast: TokenAST, context: TContext): Promise<TokenAST> | TokenAST;
44
+ /** Execute during conversion stage */
21
45
  onConvert?(result: any, context: TContext): Promise<any> | any;
46
+ /** Execute during completion stage */
22
47
  onComplete?(result: TResult, context: TContext): Promise<TResult> | TResult;
48
+ /** Error handling */
23
49
  onError?(error: Error, context: TContext): Promise<void> | void;
24
50
  }
51
+ /**
52
+ * Generic processing context
53
+ */
25
54
  export interface IProcessingContext {
55
+ /** Metadata storage */
26
56
  metadata: Map<string, any>;
57
+ /** Error list */
27
58
  errors: Error[];
59
+ /** Warning list */
28
60
  warnings: string[];
61
+ /** Processing statistics */
29
62
  stats: {
30
63
  startTime: number;
31
64
  endTime?: number;
32
65
  processedTokens: number;
33
66
  convertedElements: number;
34
67
  };
68
+ /** User-defined data */
35
69
  userData?: Record<string, any>;
36
70
  }
71
+ /**
72
+ * Generic base converter abstract class
73
+ */
37
74
  export declare abstract class BaseConverter<TContext extends IProcessingContext = IProcessingContext> implements IConverterPlugin<TContext> {
38
75
  abstract name: string;
39
76
  abstract supportedTags: string[];
@@ -55,9 +92,18 @@ export declare abstract class BaseConverter<TContext extends IProcessingContext
55
92
  protected getChildValue(ast: TokenAST, tag: string): string | undefined;
56
93
  protected getChildByTag(ast: TokenAST, tag: string): TokenAST | undefined;
57
94
  protected getChildrenByTag(ast: TokenAST, tag: string): TokenAST[];
95
+ /**
96
+ * Generic Extensions processing method
97
+ */
58
98
  protected convertExtensions(extensionsAST: TokenAST): ExtensionsType;
99
+ /**
100
+ * Recursively convert Extensions content
101
+ */
59
102
  protected convertExtensionContent(extension: TokenAST): any;
60
103
  }
104
+ /**
105
+ * Generic base middleware abstract class
106
+ */
61
107
  export declare abstract class BaseMiddleware<TContext extends IProcessingContext = IProcessingContext, TResult = any> implements IMiddlewarePlugin<TContext, TResult> {
62
108
  abstract name: string;
63
109
  version: string;
@@ -5,6 +5,7 @@ import { ActivityProcessor } from "../activity/processor.js";
5
5
  import type { AdapterDecodeResult, FITCourseAdapter, TrackFormatAdapter } from "./format-adapter.js";
6
6
  import type { DecodeOptions, TrackFormat } from "../document.js";
7
7
  import type { FileType } from "../types.js";
8
+ export declare function assertFITActivityRecordParity(native: FITFileType, activity: FileType | undefined): void;
8
9
  export declare function detectBuiltInFormat(input: Buffer): TrackFormat | undefined;
9
10
  declare abstract class BuiltInAdapter<TNative> implements TrackFormatAdapter<TNative> {
10
11
  abstract readonly format: TrackFormat;
@@ -1,17 +1,41 @@
1
1
  import { Token } from "../types.js";
2
+ /**
3
+ * XML parsing utility class
4
+ */
2
5
  export declare class XMLUtils {
6
+ /**
7
+ * Convert XML content to Token array
8
+ */
3
9
  static tokenizeXML(xmlContent: string): Token[];
10
+ /**
11
+ * Compress XML string (remove extra whitespace)
12
+ */
4
13
  static compressXML(xmlContent: string): string;
14
+ /**
15
+ * Format XML string (add indentation)
16
+ */
5
17
  static formatXML(xmlContent: string, indentSize?: number): string;
18
+ /**
19
+ * Validate XML format
20
+ */
6
21
  static validateXML(xmlContent: string): {
7
22
  isValid: boolean;
8
23
  error?: string;
9
24
  };
25
+ /**
26
+ * Extract XML declaration information
27
+ */
10
28
  static extractXMLDeclaration(xmlContent: string): {
11
29
  version?: string;
12
30
  encoding?: string;
13
31
  standalone?: string;
14
32
  };
33
+ /**
34
+ * Escape XML special characters
35
+ */
15
36
  static escapeXML(text: string): string;
37
+ /**
38
+ * Unescape XML special characters
39
+ */
16
40
  static unescapeXML(text: string): string;
17
41
  }
package/dist/errors.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { TrackFormat } from "./document.js";
2
- export type TrackSwapErrorCode = "FORMAT_UNKNOWN" | "FORMAT_UNSUPPORTED" | "DECODE_FAILED" | "ACTIVITY_NOT_FOUND" | "ENCODE_FAILED" | "ADAPTER_CONFLICT" | "DISPOSED";
2
+ export type TrackSwapErrorCode = "FORMAT_UNKNOWN" | "FORMAT_UNSUPPORTED" | "DECODE_FAILED" | "FIT_ACTIVITY_DATA_LOSS" | "ACTIVITY_NOT_FOUND" | "ENCODE_FAILED" | "ADAPTER_CONFLICT" | "DISPOSED";
3
3
  export declare class TrackSwapError extends Error {
4
4
  readonly code: TrackSwapErrorCode;
5
5
  readonly format?: TrackFormat;
@@ -1,3 +1,6 @@
1
+ /**
2
+ * FIT pipeline verbose logging (disabled unless TRACKSWAP_FIT_DEBUG=1 or TRACKSWAP_DEBUG=1).
3
+ */
1
4
  export declare function fitDebugEnabled(): boolean;
2
5
  export declare function fitDebugLog(...args: unknown[]): void;
3
6
  export declare function fitDebugWarn(...args: unknown[]): void;