trackswap 0.0.2 → 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.
Files changed (82) hide show
  1. package/README.md +322 -281
  2. package/dist/FIT/base.d.ts +0 -30
  3. package/dist/FIT/decoder.d.ts +0 -48
  4. package/dist/FIT/encoder.d.ts +0 -97
  5. package/dist/FIT/mesg.d.ts +0 -3
  6. package/dist/FIT/middleware.d.ts +0 -15
  7. package/dist/FIT/plugins.d.ts +0 -9
  8. package/dist/FIT/processor.d.ts +0 -24
  9. package/dist/FIT/types/mesg_num.d.ts +102 -102
  10. package/dist/FIT/types/sport.d.ts +44 -44
  11. package/dist/FIT/types.d.ts +0 -35
  12. package/dist/GPX/base.d.ts +0 -39
  13. package/dist/GPX/converters.d.ts +0 -30
  14. package/dist/GPX/decoder.d.ts +0 -66
  15. package/dist/GPX/encoder.d.ts +0 -109
  16. package/dist/GPX/middleware.d.ts +0 -9
  17. package/dist/GPX/processor.d.ts +0 -18
  18. package/dist/GPX/types.d.ts +0 -108
  19. package/dist/TCX/base.d.ts +0 -33
  20. package/dist/TCX/converters.d.ts +0 -24
  21. package/dist/TCX/decoder.d.ts +0 -54
  22. package/dist/TCX/encoder.d.ts +0 -109
  23. package/dist/TCX/index.d.ts +4 -1
  24. package/dist/TCX/middleware.d.ts +0 -9
  25. package/dist/TCX/processor.d.ts +0 -18
  26. package/dist/TCX/types.d.ts +0 -13
  27. package/dist/TrackSwap.d.ts +37 -33
  28. package/dist/core/base.d.ts +0 -46
  29. package/dist/core/xml-utils.d.ts +0 -24
  30. package/dist/index.js +24 -5
  31. package/dist/sport/base.d.ts +63 -0
  32. package/dist/sport/converters.d.ts +33 -0
  33. package/dist/sport/encoders.d.ts +34 -0
  34. package/dist/sport/index.d.ts +17 -0
  35. package/dist/sport/processor.d.ts +19 -0
  36. package/dist/types.d.ts +91 -13
  37. package/package.json +18 -3
  38. package/dist/FIT/base.js +0 -101
  39. package/dist/FIT/crc.js +0 -16
  40. package/dist/FIT/decoder.js +0 -323
  41. package/dist/FIT/encoder.js +0 -445
  42. package/dist/FIT/index.js +0 -13
  43. package/dist/FIT/mesg.js +0 -208
  44. package/dist/FIT/middleware.js +0 -206
  45. package/dist/FIT/plugins.js +0 -104
  46. package/dist/FIT/processor.js +0 -170
  47. package/dist/FIT/types/course_point.js +0 -58
  48. package/dist/FIT/types/event.js +0 -50
  49. package/dist/FIT/types/event_type.js +0 -19
  50. package/dist/FIT/types/file.js +0 -24
  51. package/dist/FIT/types/index.js +0 -297
  52. package/dist/FIT/types/mesg_num.js +0 -106
  53. package/dist/FIT/types/sport.js +0 -48
  54. package/dist/FIT/types.js +0 -1
  55. package/dist/FIT/util.js +0 -7
  56. package/dist/GPX/base.js +0 -56
  57. package/dist/GPX/converters.js +0 -352
  58. package/dist/GPX/decoder.js +0 -409
  59. package/dist/GPX/encoder.js +0 -513
  60. package/dist/GPX/extensions/index.js +0 -14
  61. package/dist/GPX/index.js +0 -11
  62. package/dist/GPX/middleware.js +0 -93
  63. package/dist/GPX/processor.js +0 -188
  64. package/dist/GPX/types.js +0 -1
  65. package/dist/GPX/util.js +0 -18
  66. package/dist/TCX/base.js +0 -62
  67. package/dist/TCX/converters.js +0 -333
  68. package/dist/TCX/decoder.js +0 -350
  69. package/dist/TCX/encoder.js +0 -513
  70. package/dist/TCX/index.js +0 -9
  71. package/dist/TCX/middleware.js +0 -93
  72. package/dist/TCX/processor.js +0 -197
  73. package/dist/TCX/types.js +0 -1
  74. package/dist/TrackSwap.js +0 -84
  75. package/dist/core/base.js +0 -138
  76. package/dist/core/decoder.d.ts +0 -66
  77. package/dist/core/decoder.js +0 -90
  78. package/dist/core/index.js +0 -4
  79. package/dist/core/processor.d.ts +0 -69
  80. package/dist/core/processor.js +0 -265
  81. package/dist/core/xml-utils.js +0 -140
  82. package/dist/types.js +0 -1
@@ -1,265 +0,0 @@
1
- /**
2
- * 通用处理器 - 负责管理插件和处理流程
3
- */
4
- export class Processor {
5
- constructor() {
6
- this.converters = new Map();
7
- this.middlewares = [];
8
- this.plugins = new Map();
9
- }
10
- /**
11
- * 注册插件
12
- */
13
- registerPlugin(plugin) {
14
- if (this.plugins.has(plugin.name)) {
15
- throw new Error(`插件 ${plugin.name} 已存在`);
16
- }
17
- this.plugins.set(plugin.name, plugin);
18
- // 根据插件类型注册到相应的集合
19
- if (this.isConverterPlugin(plugin)) {
20
- plugin.supportedTags?.forEach((tag) => {
21
- this.converters.set(tag, plugin);
22
- });
23
- }
24
- if (this.isMiddlewarePlugin(plugin)) {
25
- this.middlewares.push(plugin);
26
- // 按优先级排序
27
- this.middlewares.sort((a, b) => (a.priority || 100) - (b.priority || 100));
28
- }
29
- }
30
- /**
31
- * 批量注册插件
32
- */
33
- registerPlugins(plugins) {
34
- plugins.forEach((plugin) => this.registerPlugin(plugin));
35
- }
36
- /**
37
- * 获取转换器
38
- */
39
- getConverter(tag) {
40
- return this.converters.get(tag);
41
- }
42
- /**
43
- * 移除插件
44
- */
45
- unregisterPlugin(name) {
46
- const plugin = this.plugins.get(name);
47
- if (!plugin)
48
- return false;
49
- // 从转换器中移除
50
- if (this.isConverterPlugin(plugin)) {
51
- plugin.supportedTags?.forEach((tag) => {
52
- if (this.converters.get(tag) === plugin) {
53
- this.converters.delete(tag);
54
- }
55
- });
56
- }
57
- // 从中间件中移除
58
- if (this.isMiddlewarePlugin(plugin)) {
59
- const index = this.middlewares.indexOf(plugin);
60
- if (index !== -1) {
61
- this.middlewares.splice(index, 1);
62
- }
63
- }
64
- this.plugins.delete(name);
65
- return true;
66
- }
67
- /**
68
- * 获取已注册的插件列表
69
- */
70
- getRegisteredPlugins() {
71
- return Array.from(this.plugins.values());
72
- }
73
- /**
74
- * 清空所有插件
75
- */
76
- clear() {
77
- this.plugins.clear();
78
- this.converters.clear();
79
- this.middlewares.length = 0;
80
- }
81
- /**
82
- * 处理数据 - 四阶段处理流程
83
- */
84
- async process(tokens, context, options = {}) {
85
- try {
86
- // 初始化插件
87
- await this.initializePlugins(context);
88
- // 1. Tokenize 阶段
89
- let processedTokens = tokens;
90
- for (const middleware of this.middlewares) {
91
- if (middleware.onTokenize) {
92
- processedTokens = await middleware.onTokenize(processedTokens, context);
93
- }
94
- }
95
- // 2. AST 生成阶段
96
- let ast = this.generateAST(processedTokens);
97
- for (const middleware of this.middlewares) {
98
- if (middleware.onAstGenerate) {
99
- ast = await middleware.onAstGenerate(ast, context);
100
- }
101
- }
102
- // 3. 转换阶段
103
- let result = this.convertAST(ast, context);
104
- for (const middleware of this.middlewares) {
105
- if (middleware.onConvert) {
106
- result = await middleware.onConvert(result, context);
107
- }
108
- }
109
- // 4. 完成阶段
110
- let finalResult = result;
111
- for (const middleware of this.middlewares) {
112
- if (middleware.onComplete) {
113
- finalResult = await middleware.onComplete(finalResult, context);
114
- }
115
- }
116
- // 更新统计信息
117
- if (options.enableStats) {
118
- context.stats.endTime = Date.now();
119
- context.stats.processedTokens = processedTokens.length;
120
- }
121
- return finalResult;
122
- }
123
- catch (error) {
124
- // 错误处理
125
- const err = error;
126
- context.errors.push(err);
127
- for (const middleware of this.middlewares) {
128
- if (middleware.onError) {
129
- await middleware.onError(err, context);
130
- }
131
- }
132
- throw err;
133
- }
134
- finally {
135
- // 销毁插件
136
- await this.destroyPlugins(context);
137
- }
138
- }
139
- /**
140
- * 生成 AST
141
- */
142
- generateAST(tokens) {
143
- const stack = [];
144
- let root = undefined;
145
- let current = null;
146
- for (const token of tokens) {
147
- if (token.type === "open") {
148
- const newElement = {
149
- tag: token.tag,
150
- attributes: token.attributes || {},
151
- children: [],
152
- };
153
- if (!root) {
154
- root = newElement;
155
- }
156
- else {
157
- current?.children?.push(newElement);
158
- }
159
- stack.push(newElement);
160
- current = newElement;
161
- }
162
- else if (token.type === "text") {
163
- if (current) {
164
- current.value = token.value;
165
- }
166
- }
167
- else if (token.type === "close") {
168
- stack.pop();
169
- current = stack[stack.length - 1] || null;
170
- }
171
- }
172
- if (!root) {
173
- throw new Error("无法生成有效的 AST");
174
- }
175
- return root;
176
- }
177
- /**
178
- * 转换 AST
179
- */
180
- convertAST(ast, context) {
181
- const converter = this.getConverter(ast.tag);
182
- if (converter) {
183
- return converter.convert(ast, context);
184
- }
185
- // 如果没有专门的转换器,使用通用转换逻辑
186
- return this.convertGeneric(ast, context);
187
- }
188
- /**
189
- * 通用转换逻辑
190
- */
191
- convertGeneric(ast, context) {
192
- const result = {};
193
- // 复制属性
194
- if (ast.attributes) {
195
- Object.entries(ast.attributes).forEach(([key, value]) => {
196
- result[key] = value;
197
- });
198
- }
199
- // 如果有值,直接返回值
200
- if (ast.value !== undefined &&
201
- (!ast.children || ast.children.length === 0)) {
202
- return ast.value;
203
- }
204
- // 处理子元素
205
- if (ast.children) {
206
- ast.children.forEach((child) => {
207
- if (child.tag) {
208
- const converted = this.convertAST(child, context);
209
- if (result[child.tag]) {
210
- // 如果已存在,转换为数组
211
- if (!Array.isArray(result[child.tag])) {
212
- result[child.tag] = [result[child.tag]];
213
- }
214
- result[child.tag].push(converted);
215
- }
216
- else {
217
- result[child.tag] = converted;
218
- }
219
- }
220
- });
221
- }
222
- return result;
223
- }
224
- /**
225
- * 初始化插件
226
- */
227
- async initializePlugins(context) {
228
- for (const plugin of this.plugins.values()) {
229
- if (plugin.initialize) {
230
- await plugin.initialize(context);
231
- }
232
- }
233
- }
234
- /**
235
- * 销毁插件
236
- */
237
- async destroyPlugins(context) {
238
- for (const plugin of this.plugins.values()) {
239
- if (plugin.destroy) {
240
- try {
241
- await plugin.destroy(context);
242
- }
243
- catch (error) {
244
- console.warn(`销毁插件 ${plugin.name} 时出错:`, error);
245
- }
246
- }
247
- }
248
- }
249
- /**
250
- * 检查是否为转换器插件
251
- */
252
- isConverterPlugin(plugin) {
253
- return "convert" in plugin && typeof plugin.convert === "function";
254
- }
255
- /**
256
- * 检查是否为中间件插件
257
- */
258
- isMiddlewarePlugin(plugin) {
259
- return ("onTokenize" in plugin ||
260
- "onAstGenerate" in plugin ||
261
- "onConvert" in plugin ||
262
- "onComplete" in plugin ||
263
- "onError" in plugin);
264
- }
265
- }
@@ -1,140 +0,0 @@
1
- import { Parser } from "htmlparser2";
2
- /**
3
- * XML 解析工具类
4
- */
5
- export class XMLUtils {
6
- /**
7
- * 将 XML 内容转换为 Token 数组
8
- */
9
- static tokenizeXML(xmlContent) {
10
- const tokens = [];
11
- const parser = new Parser({
12
- onopentag(name, attribs) {
13
- tokens.push({
14
- type: "open",
15
- tag: name,
16
- attributes: attribs,
17
- });
18
- },
19
- ontext(text) {
20
- const filteredText = text.replace(/\n/g, "").trim();
21
- if (filteredText) {
22
- tokens.push({ type: "text", tag: "text", value: filteredText });
23
- }
24
- },
25
- onclosetag(name) {
26
- tokens.push({ type: "close", tag: name });
27
- },
28
- }, { xmlMode: true });
29
- parser.write(xmlContent);
30
- parser.end();
31
- return tokens;
32
- }
33
- /**
34
- * 压缩 XML 字符串(移除多余空白)
35
- */
36
- static compressXML(xmlContent) {
37
- return xmlContent
38
- .replace(/>\s+</g, "><") // 移除标签间的空白
39
- .replace(/\s+/g, " ") // 将多个空白字符替换为单个空格
40
- .trim();
41
- }
42
- /**
43
- * 格式化 XML 字符串(添加缩进)
44
- */
45
- static formatXML(xmlContent, indentSize = 2) {
46
- const indent = " ".repeat(indentSize);
47
- let formatted = "";
48
- let depth = 0;
49
- let inTag = false;
50
- for (let i = 0; i < xmlContent.length; i++) {
51
- const char = xmlContent[i];
52
- const nextChar = xmlContent[i + 1];
53
- if (char === "<") {
54
- if (nextChar === "/") {
55
- // 闭合标签
56
- depth--;
57
- if (!inTag) {
58
- formatted += "\n" + indent.repeat(depth);
59
- }
60
- }
61
- else if (nextChar !== "?" && nextChar !== "!") {
62
- // 开始标签
63
- if (!inTag) {
64
- formatted += "\n" + indent.repeat(depth);
65
- }
66
- depth++;
67
- }
68
- inTag = true;
69
- }
70
- else if (char === ">") {
71
- inTag = false;
72
- if (nextChar === "<" && xmlContent[i + 2] === "/") {
73
- // 自闭合标签或紧跟闭合标签
74
- depth--;
75
- }
76
- }
77
- formatted += char;
78
- }
79
- return formatted.trim();
80
- }
81
- /**
82
- * 验证 XML 格式
83
- */
84
- static validateXML(xmlContent) {
85
- try {
86
- const parser = new Parser({}, { xmlMode: true });
87
- parser.write(xmlContent);
88
- parser.end();
89
- return { isValid: true };
90
- }
91
- catch (error) {
92
- return {
93
- isValid: false,
94
- error: error.message,
95
- };
96
- }
97
- }
98
- /**
99
- * 提取 XML 声明信息
100
- */
101
- static extractXMLDeclaration(xmlContent) {
102
- const declarationMatch = xmlContent.match(/<\?xml\s+([^>]+)\?>/);
103
- if (!declarationMatch)
104
- return {};
105
- const declaration = declarationMatch[1];
106
- const result = {};
107
- const versionMatch = declaration.match(/version=["']([^"']+)["']/);
108
- if (versionMatch)
109
- result.version = versionMatch[1];
110
- const encodingMatch = declaration.match(/encoding=["']([^"']+)["']/);
111
- if (encodingMatch)
112
- result.encoding = encodingMatch[1];
113
- const standaloneMatch = declaration.match(/standalone=["']([^"']+)["']/);
114
- if (standaloneMatch)
115
- result.standalone = standaloneMatch[1];
116
- return result;
117
- }
118
- /**
119
- * 转义 XML 特殊字符
120
- */
121
- static escapeXML(text) {
122
- return text
123
- .replace(/&/g, "&amp;")
124
- .replace(/</g, "&lt;")
125
- .replace(/>/g, "&gt;")
126
- .replace(/"/g, "&quot;")
127
- .replace(/'/g, "&#39;");
128
- }
129
- /**
130
- * 反转义 XML 特殊字符
131
- */
132
- static unescapeXML(text) {
133
- return text
134
- .replace(/&lt;/g, "<")
135
- .replace(/&gt;/g, ">")
136
- .replace(/&quot;/g, '"')
137
- .replace(/&#39;/g, "'")
138
- .replace(/&amp;/g, "&");
139
- }
140
- }
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};