trackswap 0.0.1 → 0.0.3
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.
- package/README.md +322 -281
- package/dist/FIT/base.d.ts +61 -0
- package/dist/FIT/crc.d.ts +1 -0
- package/dist/FIT/decoder.d.ts +35 -0
- package/dist/FIT/encoder.d.ts +45 -0
- package/dist/FIT/index.d.ts +12 -0
- package/dist/FIT/mesg.d.ts +37 -0
- package/dist/FIT/middleware.d.ts +33 -0
- package/dist/FIT/plugins.d.ts +17 -0
- package/dist/FIT/processor.d.ts +34 -0
- package/dist/FIT/types/course_point.d.ts +56 -0
- package/dist/FIT/types/event.d.ts +49 -0
- package/dist/FIT/types/event_type.d.ts +18 -0
- package/dist/FIT/types/file.d.ts +23 -0
- package/dist/FIT/types/index.d.ts +119 -0
- package/dist/FIT/types/mesg_num.d.ts +105 -0
- package/dist/FIT/types/sport.d.ts +47 -0
- package/dist/FIT/types.d.ts +196 -0
- package/dist/FIT/util.d.ts +1 -0
- package/dist/GPX/base.d.ts +14 -77
- package/dist/GPX/converters.d.ts +12 -66
- package/dist/GPX/decoder.d.ts +5 -71
- package/dist/GPX/encoder.d.ts +4 -109
- package/dist/GPX/index.d.ts +1 -1
- package/dist/GPX/middleware.d.ts +18 -0
- package/dist/GPX/processor.d.ts +0 -18
- package/dist/GPX/types.d.ts +2 -111
- package/dist/TCX/base.d.ts +19 -0
- package/dist/TCX/converters.d.ts +51 -0
- package/dist/TCX/decoder.d.ts +33 -0
- package/dist/TCX/encoder.d.ts +41 -0
- package/dist/TCX/index.d.ts +13 -0
- package/dist/TCX/middleware.d.ts +18 -0
- package/dist/TCX/processor.d.ts +30 -0
- package/dist/TCX/types.d.ts +190 -0
- package/dist/TrackSwap.d.ts +37 -33
- package/dist/core/base.d.ts +73 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/xml-utils.d.ts +17 -0
- package/dist/index.js +24 -5
- package/dist/sport/base.d.ts +63 -0
- package/dist/sport/converters.d.ts +33 -0
- package/dist/sport/encoders.d.ts +34 -0
- package/dist/sport/index.d.ts +17 -0
- package/dist/sport/processor.d.ts +19 -0
- package/dist/types.d.ts +91 -13
- package/package.json +25 -7
- package/dist/GPX/base.js +0 -83
- package/dist/GPX/converters.js +0 -444
- package/dist/GPX/decoder.js +0 -403
- package/dist/GPX/encoder.js +0 -510
- package/dist/GPX/extensions/index.js +0 -14
- package/dist/GPX/index.js +0 -11
- package/dist/GPX/processor.js +0 -187
- package/dist/GPX/types.js +0 -1
- package/dist/GPX/util.js +0 -18
- package/dist/TrackSwap.js +0 -84
- package/dist/types.js +0 -1
package/dist/GPX/processor.js
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import { Parser } from "htmlparser2";
|
|
2
|
-
/**
|
|
3
|
-
* 流水线阶段
|
|
4
|
-
*/
|
|
5
|
-
export var PipelineStage;
|
|
6
|
-
(function (PipelineStage) {
|
|
7
|
-
PipelineStage["TOKENIZE"] = "tokenize";
|
|
8
|
-
PipelineStage["AST_GENERATE"] = "ast_generate";
|
|
9
|
-
PipelineStage["CONVERT"] = "convert";
|
|
10
|
-
PipelineStage["COMPLETE"] = "complete";
|
|
11
|
-
})(PipelineStage || (PipelineStage = {}));
|
|
12
|
-
/**
|
|
13
|
-
* Tokenize处理器
|
|
14
|
-
*/
|
|
15
|
-
export class TokenizeProcessor {
|
|
16
|
-
constructor() {
|
|
17
|
-
this.stage = PipelineStage.TOKENIZE;
|
|
18
|
-
}
|
|
19
|
-
async process(context) {
|
|
20
|
-
const startTime = Date.now();
|
|
21
|
-
if (!context.xmlContent) {
|
|
22
|
-
throw new Error("XML内容不能为空");
|
|
23
|
-
}
|
|
24
|
-
const tokens = [];
|
|
25
|
-
const parser = new Parser({
|
|
26
|
-
onopentag(name, attribs) {
|
|
27
|
-
tokens.push({
|
|
28
|
-
type: "open",
|
|
29
|
-
tag: name,
|
|
30
|
-
attributes: attribs,
|
|
31
|
-
});
|
|
32
|
-
},
|
|
33
|
-
ontext(text) {
|
|
34
|
-
const filteredText = text.replace(/\n/g, "").trim();
|
|
35
|
-
if (filteredText) {
|
|
36
|
-
tokens.push({ type: "text", tag: "text", value: filteredText });
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
onclosetag(name) {
|
|
40
|
-
tokens.push({ type: "close", tag: name });
|
|
41
|
-
},
|
|
42
|
-
}, { xmlMode: true });
|
|
43
|
-
parser.write(context.xmlContent);
|
|
44
|
-
parser.end();
|
|
45
|
-
context.tokens = tokens;
|
|
46
|
-
context.performance.tokenizeTime = Date.now() - startTime;
|
|
47
|
-
return context;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* AST生成处理器
|
|
52
|
-
*/
|
|
53
|
-
export class AstGenerateProcessor {
|
|
54
|
-
constructor() {
|
|
55
|
-
this.stage = PipelineStage.AST_GENERATE;
|
|
56
|
-
}
|
|
57
|
-
async process(context) {
|
|
58
|
-
const startTime = Date.now();
|
|
59
|
-
if (!context.tokens) {
|
|
60
|
-
throw new Error("Tokens不能为空");
|
|
61
|
-
}
|
|
62
|
-
const stack = [];
|
|
63
|
-
let root = undefined;
|
|
64
|
-
let current = null;
|
|
65
|
-
for (const token of context.tokens) {
|
|
66
|
-
if (token.type === "open") {
|
|
67
|
-
const newElement = {
|
|
68
|
-
tag: token.tag,
|
|
69
|
-
attributes: token.attributes || {},
|
|
70
|
-
children: [],
|
|
71
|
-
};
|
|
72
|
-
if (!root) {
|
|
73
|
-
root = newElement;
|
|
74
|
-
}
|
|
75
|
-
else if (current) {
|
|
76
|
-
current.children?.push(newElement);
|
|
77
|
-
}
|
|
78
|
-
stack.push(newElement);
|
|
79
|
-
current = newElement;
|
|
80
|
-
}
|
|
81
|
-
else if (token.type === "text" && current) {
|
|
82
|
-
current.value = token.value;
|
|
83
|
-
}
|
|
84
|
-
else if (token.type === "close") {
|
|
85
|
-
stack.pop();
|
|
86
|
-
current = stack[stack.length - 1] || null;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
context.ast = root;
|
|
90
|
-
context.performance.astTime = Date.now() - startTime;
|
|
91
|
-
return context;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* 转换处理器
|
|
96
|
-
*/
|
|
97
|
-
export class ConvertProcessor {
|
|
98
|
-
constructor(getConverter) {
|
|
99
|
-
this.getConverter = getConverter;
|
|
100
|
-
this.stage = PipelineStage.CONVERT;
|
|
101
|
-
}
|
|
102
|
-
async process(context) {
|
|
103
|
-
const startTime = Date.now();
|
|
104
|
-
if (!context.ast) {
|
|
105
|
-
throw new Error("AST不能为空");
|
|
106
|
-
}
|
|
107
|
-
const gpx = {};
|
|
108
|
-
// 处理根节点属性
|
|
109
|
-
if (context.ast.attributes) {
|
|
110
|
-
Object.entries(context.ast.attributes).forEach(([key, value]) => {
|
|
111
|
-
if (key.startsWith("xmlns:")) {
|
|
112
|
-
gpx[key] = value.replace(/'/g, "'");
|
|
113
|
-
}
|
|
114
|
-
else if (key === "xsi:schemaLocation") {
|
|
115
|
-
gpx[key] = value.replace(/'/g, "'");
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
gpx[key] = value;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
// 处理子节点
|
|
123
|
-
context.ast.children?.forEach((child) => {
|
|
124
|
-
const converter = this.getConverter(child.tag);
|
|
125
|
-
if (converter) {
|
|
126
|
-
try {
|
|
127
|
-
const result = converter.convert(child, context);
|
|
128
|
-
if (result) {
|
|
129
|
-
this.assignResult(gpx, child.tag, result);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
context.errors.push(error);
|
|
134
|
-
console.error(`转换器 ${converter.name} 处理标签 ${child.tag} 时出错:`, error);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
context.result = gpx;
|
|
139
|
-
context.performance.convertTime = Date.now() - startTime;
|
|
140
|
-
return context;
|
|
141
|
-
}
|
|
142
|
-
assignResult(gpx, tag, result) {
|
|
143
|
-
switch (tag) {
|
|
144
|
-
case "metadata":
|
|
145
|
-
gpx.metadata = result;
|
|
146
|
-
break;
|
|
147
|
-
case "wpt":
|
|
148
|
-
if (!gpx.wpt)
|
|
149
|
-
gpx.wpt = [];
|
|
150
|
-
gpx.wpt.push(result);
|
|
151
|
-
break;
|
|
152
|
-
case "rte":
|
|
153
|
-
if (!gpx.rte)
|
|
154
|
-
gpx.rte = [];
|
|
155
|
-
gpx.rte.push(result);
|
|
156
|
-
break;
|
|
157
|
-
case "trk":
|
|
158
|
-
if (!gpx.trk)
|
|
159
|
-
gpx.trk = [];
|
|
160
|
-
gpx.trk.push(result);
|
|
161
|
-
break;
|
|
162
|
-
case "extensions":
|
|
163
|
-
gpx.extensions = result;
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* 完成处理器
|
|
170
|
-
*/
|
|
171
|
-
export class CompleteProcessor {
|
|
172
|
-
constructor() {
|
|
173
|
-
this.stage = PipelineStage.COMPLETE;
|
|
174
|
-
}
|
|
175
|
-
async process(context) {
|
|
176
|
-
context.performance.endTime = Date.now();
|
|
177
|
-
// 记录性能指标
|
|
178
|
-
const totalTime = context.performance.endTime - context.performance.startTime;
|
|
179
|
-
context.metadata.set("performance", {
|
|
180
|
-
totalTime,
|
|
181
|
-
tokenizeTime: context.performance.tokenizeTime,
|
|
182
|
-
astTime: context.performance.astTime,
|
|
183
|
-
convertTime: context.performance.convertTime,
|
|
184
|
-
});
|
|
185
|
-
return context;
|
|
186
|
-
}
|
|
187
|
-
}
|
package/dist/GPX/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/GPX/util.js
DELETED
package/dist/TrackSwap.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { GPXDecoder, GPXEncoder } from "./GPX/index.js";
|
|
2
|
-
/**
|
|
3
|
-
* GPX轨迹交换处理类
|
|
4
|
-
* 提供GPX文件的解析和编码功能
|
|
5
|
-
*/
|
|
6
|
-
export class TrackSwap {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.decoder = new GPXDecoder();
|
|
9
|
-
this.encoder = new GPXEncoder();
|
|
10
|
-
}
|
|
11
|
-
// ==================== 解析功能 ====================
|
|
12
|
-
/**
|
|
13
|
-
* 解析GPX文件Buffer为GPX对象
|
|
14
|
-
*/
|
|
15
|
-
async parseGPX(buffer) {
|
|
16
|
-
try {
|
|
17
|
-
return await this.decoder.parserByBuffer(buffer);
|
|
18
|
-
}
|
|
19
|
-
catch (error) {
|
|
20
|
-
console.error("GPX解析失败:", error);
|
|
21
|
-
throw new Error(`GPX解析失败: ${error.message}`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* 解析GPX文件字符串为GPX对象
|
|
26
|
-
*/
|
|
27
|
-
async parseGPXString(xmlString) {
|
|
28
|
-
const buffer = Buffer.from(xmlString, "utf-8");
|
|
29
|
-
return this.parseGPX(buffer);
|
|
30
|
-
}
|
|
31
|
-
// ==================== 编码功能 ====================
|
|
32
|
-
/**
|
|
33
|
-
* 编码GPX对象为Buffer
|
|
34
|
-
*/
|
|
35
|
-
async encodeGPX(gpxData) {
|
|
36
|
-
try {
|
|
37
|
-
return await this.encoder.encode(gpxData);
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
console.error("GPX编码失败:", error);
|
|
41
|
-
throw new Error(`GPX编码失败: ${error.message}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* 编码GPX对象为XML字符串
|
|
46
|
-
*/
|
|
47
|
-
encodeGPXString(gpxData) {
|
|
48
|
-
try {
|
|
49
|
-
return this.encoder.encodeToString(gpxData);
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
console.error("GPX编码失败:", error);
|
|
53
|
-
throw new Error(`GPX编码失败: ${error.message}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// ==================== 实例管理 ====================
|
|
57
|
-
/**
|
|
58
|
-
* 获取解码器实例
|
|
59
|
-
*/
|
|
60
|
-
getDecoder() {
|
|
61
|
-
return this.decoder;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* 获取编码器实例
|
|
65
|
-
*/
|
|
66
|
-
getEncoder() {
|
|
67
|
-
return this.encoder;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* 销毁实例,清理资源
|
|
71
|
-
*/
|
|
72
|
-
async destroy() {
|
|
73
|
-
await this.decoder.destroy();
|
|
74
|
-
}
|
|
75
|
-
// ==================== 向后兼容 ====================
|
|
76
|
-
/**
|
|
77
|
-
* @deprecated 使用 encodeGPX() 替代
|
|
78
|
-
*/
|
|
79
|
-
async encoderGPX(gpx) {
|
|
80
|
-
return this.encodeGPX(gpx);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// 默认导出
|
|
84
|
-
export default { TrackSwap };
|
package/dist/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|