trackswap 0.0.1

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.
@@ -0,0 +1,510 @@
1
+ import dayjs from "dayjs";
2
+ import utc from "dayjs/plugin/utc.js";
3
+ import { GpxExtensionsv3Mapping, TrackPointExtensionv1Mapping, } from "./extensions/index.js";
4
+ // 配置 dayjs UTC 插件
5
+ dayjs.extend(utc);
6
+ /**
7
+ * GPX 编码器 - 将 GPX11Type 数据编码为 GPX XML 格式
8
+ */
9
+ export class GPXEncoder {
10
+ /**
11
+ * 构造函数
12
+ * @param options 编码器选项
13
+ */
14
+ constructor(options = {}) {
15
+ /**
16
+ * 格式化高程
17
+ */
18
+ this.formatElevation = (elevation) => {
19
+ const num = parseFloat(elevation);
20
+ return isNaN(num) ? elevation : this.roundTo(num, 2).toString();
21
+ };
22
+ this.compact = options.compact ?? true;
23
+ }
24
+ // ==================== 公共接口 ====================
25
+ /**
26
+ * 编码 GPX 数据为 Buffer
27
+ */
28
+ async encode(gpxData) {
29
+ const xmlContent = this.buildGPXXML(gpxData);
30
+ return Buffer.from(xmlContent, "utf-8");
31
+ }
32
+ /**
33
+ * 编码 GPX 数据为 XML 字符串
34
+ */
35
+ encodeToString(gpxData) {
36
+ return this.buildGPXXML(gpxData);
37
+ }
38
+ // ==================== 核心构建方法 ====================
39
+ /**
40
+ * 构建完整的 GPX XML
41
+ */
42
+ buildGPXXML(gpxData) {
43
+ const header = this.buildXMLHeader();
44
+ const content = this.buildGPXContent(gpxData);
45
+ const footer = "</gpx>";
46
+ const xml = `${header}${content}\n${footer}`;
47
+ // 如果启用压缩模式,则压缩XML
48
+ return this.compact ? this.compressXML(xml) : xml;
49
+ }
50
+ /**
51
+ * 压缩XML字符串,去掉多余的换行和空格
52
+ */
53
+ compressXML(xml) {
54
+ return (xml
55
+ // 去掉标签之间的换行和多余空格
56
+ .replace(/>\s+</g, "><")
57
+ // 去掉行首行尾的空白字符
58
+ .replace(/^\s+|\s+$/gm, "")
59
+ // 将多个连续空格替换为单个空格
60
+ .replace(/\s+/g, " ")
61
+ // 去掉整体的首尾空白
62
+ .trim());
63
+ }
64
+ /**
65
+ * 构建 XML 头部
66
+ */
67
+ buildXMLHeader() {
68
+ return [
69
+ '<?xml version="1.0" encoding="UTF-8"?>',
70
+ '<gpx creator="https://gpxonline.net" version="1.1"',
71
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',
72
+ ' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd',
73
+ " http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd",
74
+ " http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd",
75
+ " http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd",
76
+ ' http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd"',
77
+ ' xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"',
78
+ ' xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"',
79
+ ' xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1"',
80
+ ' xmlns:gpx_style="http://www.topografix.com/GPX/gpx_style/0/2"',
81
+ ' xmlns="http://www.topografix.com/GPX/1/1">',
82
+ ].join("\n");
83
+ }
84
+ /**
85
+ * 构建 GPX 内容
86
+ */
87
+ buildGPXContent(gpxData) {
88
+ const { metadata, wpt: waypoints = [], rte: routes = [], trk: tracks = [], } = gpxData;
89
+ const parts = [];
90
+ // 按标准 GPX 顺序构建内容
91
+ if (metadata) {
92
+ parts.push(this.buildMetadata(metadata));
93
+ }
94
+ waypoints.forEach((wpt) => {
95
+ parts.push(this.buildWaypoint(wpt, "wpt"));
96
+ });
97
+ routes.forEach((route) => {
98
+ parts.push(this.buildRoute(route));
99
+ });
100
+ tracks.forEach((track) => {
101
+ parts.push(this.buildTrack(track));
102
+ });
103
+ return parts.join("\n");
104
+ }
105
+ // ==================== 元数据构建 ====================
106
+ /**
107
+ * 构建 metadata 元素
108
+ */
109
+ buildMetadata(metadata) {
110
+ const parts = ["<metadata>"];
111
+ this.addOptionalElement(parts, "name", metadata.name);
112
+ this.addOptionalElement(parts, "desc", metadata.desc);
113
+ if (metadata.author) {
114
+ parts.push(this.buildAuthor(metadata.author));
115
+ }
116
+ if (metadata.copyright) {
117
+ parts.push(this.buildCopyright(metadata.copyright));
118
+ }
119
+ if (metadata.link) {
120
+ this.addLinks(parts, metadata.link);
121
+ }
122
+ if (metadata.time) {
123
+ parts.push(this.buildTimeElement(metadata.time));
124
+ }
125
+ this.addOptionalElement(parts, "keywords", metadata.keywords);
126
+ if (metadata.bounds) {
127
+ parts.push(this.buildBounds(metadata.bounds));
128
+ }
129
+ if (metadata.extensions) {
130
+ parts.push(this.buildExtensions(metadata.extensions));
131
+ }
132
+ parts.push("</metadata>");
133
+ return parts.join("\n ");
134
+ }
135
+ /**
136
+ * 构建 author 元素
137
+ */
138
+ buildAuthor(author) {
139
+ const parts = ["<author>"];
140
+ this.addOptionalElement(parts, "name", author.name);
141
+ if (author.email) {
142
+ parts.push(`<email id="${this.escapeXML(author.email.id || "")}" domain="${this.escapeXML(author.email.domain || "")}"/>`);
143
+ }
144
+ if (author.link) {
145
+ parts.push(this.buildLink(author.link));
146
+ }
147
+ parts.push("</author>");
148
+ return parts.join("\n ");
149
+ }
150
+ /**
151
+ * 构建 copyright 元素
152
+ */
153
+ buildCopyright(copyright) {
154
+ const parts = [
155
+ `<copyright author="${this.escapeXML(copyright.author || "")}">`,
156
+ ];
157
+ this.addOptionalElement(parts, "year", copyright.year);
158
+ this.addOptionalElement(parts, "license", copyright.license);
159
+ parts.push("</copyright>");
160
+ return parts.join("\n ");
161
+ }
162
+ /**
163
+ * 构建 bounds 元素
164
+ */
165
+ buildBounds(bounds) {
166
+ // 确保数值安全转换为字符串并转义
167
+ const minlat = this.escapeXMLAttribute((bounds.minlat || 0).toString());
168
+ const minlon = this.escapeXMLAttribute((bounds.minlon || 0).toString());
169
+ const maxlat = this.escapeXMLAttribute((bounds.maxlat || 0).toString());
170
+ const maxlon = this.escapeXMLAttribute((bounds.maxlon || 0).toString());
171
+ return `<bounds minlat="${minlat}" minlon="${minlon}" maxlat="${maxlat}" maxlon="${maxlon}"/>`;
172
+ }
173
+ // ==================== 航路点构建 ====================
174
+ /**
175
+ * 构建航路点元素
176
+ */
177
+ buildWaypoint(point, tagName) {
178
+ if (!this.isValidCoordinate(point.lat, point.lon)) {
179
+ return "";
180
+ }
181
+ const parts = [
182
+ `<${tagName} lat="${this.escapeXMLAttribute(this.formatCoordinate(point.lat))}" lon="${this.escapeXMLAttribute(this.formatCoordinate(point.lon))}">`,
183
+ ];
184
+ // 基础属性
185
+ this.addOptionalElement(parts, "ele", point.ele?.toString(), this.formatElevation);
186
+ if (point.time) {
187
+ parts.push(this.buildTimeElement(point.time));
188
+ }
189
+ // 添加速度和航向信息
190
+ this.addOptionalElement(parts, "speed", point.speed?.toString());
191
+ this.addOptionalElement(parts, "course", point.course?.toString());
192
+ // GPX 标准属性
193
+ this.addStandardWaypointElements(parts, point);
194
+ // 扩展属性
195
+ if (point.extensions) {
196
+ const processedExtensions = this.processPointExtensions(point, point.extensions);
197
+ if (Object.keys(processedExtensions).length > 0) {
198
+ parts.push(this.buildExtensions(processedExtensions));
199
+ }
200
+ }
201
+ parts.push(`</${tagName}>`);
202
+ return parts.join("\n ");
203
+ }
204
+ /**
205
+ * 添加标准航路点元素
206
+ */
207
+ addStandardWaypointElements(parts, point) {
208
+ // 按 GPX 标准顺序添加元素
209
+ this.addOptionalElement(parts, "magvar", point.magvar?.toString());
210
+ this.addOptionalElement(parts, "geoidheight", point.geoidheight?.toString());
211
+ this.addOptionalElement(parts, "name", point.name);
212
+ this.addOptionalElement(parts, "cmt", point.cmt);
213
+ this.addOptionalElement(parts, "desc", point.desc);
214
+ this.addOptionalElement(parts, "src", point.src);
215
+ if (point.link) {
216
+ this.addLinks(parts, point.link);
217
+ }
218
+ this.addOptionalElement(parts, "sym", point.sym);
219
+ this.addOptionalElement(parts, "type", point.type);
220
+ this.addOptionalElement(parts, "fix", point.fix);
221
+ this.addOptionalElement(parts, "sat", point.sat);
222
+ this.addOptionalElement(parts, "hdop", point.hdop?.toString());
223
+ this.addOptionalElement(parts, "vdop", point.vdop?.toString());
224
+ this.addOptionalElement(parts, "pdop", point.pdop?.toString());
225
+ this.addOptionalElement(parts, "ageofdgpsdata", point.ageofdgpsdata?.toString());
226
+ this.addOptionalElement(parts, "dgpsid", point.dgpsid?.toString());
227
+ }
228
+ // ==================== 路线构建 ====================
229
+ /**
230
+ * 构建 rte 元素
231
+ */
232
+ buildRoute(route) {
233
+ const parts = ["<rte>"];
234
+ this.addRouteTrackCommonElements(parts, route);
235
+ // 路线点
236
+ if (route.rtept) {
237
+ route.rtept?.forEach((point) => {
238
+ parts.push(this.buildWaypoint(point, "rtept"));
239
+ });
240
+ }
241
+ if (route.extensions) {
242
+ parts.push(this.buildExtensions(route.extensions));
243
+ }
244
+ parts.push("</rte>");
245
+ return parts.join("\n ");
246
+ }
247
+ // ==================== 轨迹构建 ====================
248
+ /**
249
+ * 构建轨迹元素
250
+ */
251
+ buildTrack(track) {
252
+ const parts = ["<trk>"];
253
+ this.addRouteTrackCommonElements(parts, track);
254
+ // 轨迹段
255
+ if (track.trkseg) {
256
+ track.trkseg.forEach((segment) => {
257
+ parts.push(this.buildTrackSegment(segment));
258
+ });
259
+ }
260
+ if (track.extensions) {
261
+ parts.push(this.buildExtensions(track.extensions));
262
+ }
263
+ parts.push("</trk>");
264
+ return parts.join("\n ");
265
+ }
266
+ /**
267
+ * 构建轨迹段元素
268
+ */
269
+ buildTrackSegment(segment) {
270
+ const parts = ["<trkseg>"];
271
+ if (segment.trkpt) {
272
+ segment.trkpt.forEach((point) => {
273
+ parts.push(this.buildWaypoint(point, "trkpt"));
274
+ });
275
+ }
276
+ if (segment.extensions) {
277
+ parts.push(this.buildExtensions(segment.extensions));
278
+ }
279
+ parts.push("</trkseg>");
280
+ return parts.join("\n ");
281
+ }
282
+ /**
283
+ * 添加路线和轨迹的公共元素
284
+ */
285
+ addRouteTrackCommonElements(parts, item) {
286
+ this.addOptionalElement(parts, "name", item.name);
287
+ this.addOptionalElement(parts, "cmt", item.cmt);
288
+ this.addOptionalElement(parts, "desc", item.desc);
289
+ this.addOptionalElement(parts, "src", item.src);
290
+ if (item.link) {
291
+ this.addLinks(parts, item.link);
292
+ }
293
+ this.addOptionalElement(parts, "number", item.number?.toString());
294
+ this.addOptionalElement(parts, "type", item.type);
295
+ }
296
+ // ==================== 扩展处理 ====================
297
+ /**
298
+ * 处理点的扩展属性
299
+ */
300
+ processPointExtensions(point, extensions) {
301
+ const result = this.deepClone(extensions);
302
+ // 处理各种扩展
303
+ const trackPointExt = this.buildTrackPointExtension(point, extensions);
304
+ if (Object.keys(trackPointExt).length > 0) {
305
+ result["gpxtpx:TrackPointExtension"] = trackPointExt;
306
+ }
307
+ const powerExt = this.buildPowerExtension(point, extensions);
308
+ if (Object.keys(powerExt).length > 0) {
309
+ result["gpxpx:PowerExtension"] = powerExt;
310
+ }
311
+ const gpxExt = this.buildGpxExtensions(point, extensions);
312
+ if (Object.keys(gpxExt).length > 0) {
313
+ result["gpxx:GpxExtensions"] = gpxExt;
314
+ }
315
+ return result;
316
+ }
317
+ /**
318
+ * 构建 TrackPoint 扩展
319
+ */
320
+ buildTrackPointExtension(point, extensions) {
321
+ const result = this.deepClone(extensions["gpxtpx:TrackPointExtension"] || {});
322
+ const mappingKeys = Object.keys(TrackPointExtensionv1Mapping);
323
+ Object.keys(point)
324
+ .filter((key) => mappingKeys.includes(key))
325
+ .forEach((key) => {
326
+ const mappedKey = TrackPointExtensionv1Mapping[key];
327
+ if (mappedKey && point[key] !== undefined) {
328
+ result[`gpxtpx:${mappedKey}`] = point[key];
329
+ }
330
+ });
331
+ return result;
332
+ }
333
+ /**
334
+ * 构建 Power 扩展
335
+ */
336
+ buildPowerExtension(point, extensions) {
337
+ return this.deepClone(extensions["gpxpx:PowerExtension"] || {});
338
+ }
339
+ /**
340
+ * 构建 GPX 扩展
341
+ */
342
+ buildGpxExtensions(point, extensions) {
343
+ const result = this.deepClone(extensions["gpxx:GpxExtensions"] || {});
344
+ const mappingKeys = Object.keys(GpxExtensionsv3Mapping);
345
+ Object.keys(point)
346
+ .filter((key) => mappingKeys.includes(key))
347
+ .forEach((key) => {
348
+ const mappedKey = GpxExtensionsv3Mapping[key];
349
+ if (mappedKey && point[key] !== undefined) {
350
+ result[`gpxx:${mappedKey}`] = point[key];
351
+ }
352
+ });
353
+ return result;
354
+ }
355
+ /**
356
+ * 构建扩展元素
357
+ */
358
+ buildExtensions(extensions) {
359
+ const content = this.buildExtensionContent(extensions);
360
+ return content ? `<extensions>${content}</extensions>` : "";
361
+ }
362
+ /**
363
+ * 递归构建扩展内容
364
+ */
365
+ buildExtensionContent(extension) {
366
+ return Object.entries(extension)
367
+ .filter(([key]) => !key.startsWith("xmlns"))
368
+ .map(([key, value]) => {
369
+ if (value && typeof value === "object") {
370
+ const content = this.buildExtensionContent(value);
371
+ return `<${key}>${content}</${key}>`;
372
+ }
373
+ else if (value !== undefined && value !== null) {
374
+ return `<${key}>${this.escapeXML(String(value))}</${key}>`;
375
+ }
376
+ return "";
377
+ })
378
+ .filter((content) => content)
379
+ .join("");
380
+ }
381
+ // ==================== 辅助方法 ====================
382
+ /**
383
+ * 构建 link 元素
384
+ */
385
+ buildLink(link) {
386
+ const parts = [
387
+ `<link href="${this.escapeXMLAttribute(link.href || "")}">`,
388
+ ];
389
+ this.addOptionalElement(parts, "text", link.text);
390
+ this.addOptionalElement(parts, "type", link.type);
391
+ parts.push("</link>");
392
+ return parts.join("");
393
+ }
394
+ /**
395
+ * 添加多个 link 元素
396
+ */
397
+ addLinks(parts, links) {
398
+ const linkArray = Array.isArray(links) ? links : [links];
399
+ linkArray.forEach((link) => {
400
+ parts.push(this.buildLink(link));
401
+ });
402
+ }
403
+ /**
404
+ * 构建时间元素
405
+ */
406
+ buildTimeElement(time) {
407
+ // 如果是字符串且已经是正确的ISO格式,直接使用
408
+ if (typeof time === "string") {
409
+ // 检查是否已经是标准的ISO 8601格式
410
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?$/.test(time)) {
411
+ return `<time>${time}</time>`;
412
+ }
413
+ }
414
+ // 对于Date对象或其他格式的字符串,使用dayjs处理
415
+ // 生成不带毫秒的UTC时间格式,与原始GPX文件格式保持一致
416
+ const timeStr = dayjs(time).utc().format("YYYY-MM-DDTHH:mm:ss[Z]");
417
+ return `<time>${timeStr}</time>`;
418
+ }
419
+ /**
420
+ * 添加可选元素
421
+ */
422
+ addOptionalElement(parts, tagName, value, formatter) {
423
+ if (value !== undefined && value !== null && value !== "") {
424
+ const formattedValue = formatter
425
+ ? formatter(value)
426
+ : this.escapeXML(value);
427
+ parts.push(`<${tagName}>${formattedValue}</${tagName}>`);
428
+ }
429
+ }
430
+ /**
431
+ * 验证坐标有效性
432
+ */
433
+ isValidCoordinate(lat, lon) {
434
+ return (lat !== undefined &&
435
+ lat !== null &&
436
+ lon !== undefined &&
437
+ lon !== null &&
438
+ !isNaN(lat) &&
439
+ !isNaN(lon));
440
+ }
441
+ /**
442
+ * 格式化坐标
443
+ */
444
+ formatCoordinate(coord) {
445
+ return this.roundTo(coord, 6).toString();
446
+ }
447
+ /**
448
+ * 数字四舍五入
449
+ */
450
+ roundTo(num, precision) {
451
+ const factor = Math.pow(10, precision);
452
+ return Math.round(num * factor) / factor;
453
+ }
454
+ /**
455
+ * XML 转义
456
+ */
457
+ escapeXML(text) {
458
+ return text
459
+ .replace(/&/g, "&amp;")
460
+ .replace(/</g, "&lt;")
461
+ .replace(/>/g, "&gt;")
462
+ .replace(/"/g, "&quot;")
463
+ .replace(/'/g, "&apos;");
464
+ }
465
+ /**
466
+ * XML 属性值转义(专门用于属性值的安全转义)
467
+ */
468
+ escapeXMLAttribute(text) {
469
+ if (typeof text !== "string") {
470
+ return String(text || "");
471
+ }
472
+ return text
473
+ .replace(/&/g, "&amp;")
474
+ .replace(/"/g, "&quot;")
475
+ .replace(/'/g, "&apos;")
476
+ .replace(/</g, "&lt;")
477
+ .replace(/>/g, "&gt;")
478
+ .replace(/\r/g, "&#13;")
479
+ .replace(/\n/g, "&#10;")
480
+ .replace(/\t/g, "&#9;");
481
+ }
482
+ /**
483
+ * 深度拷贝
484
+ */
485
+ deepClone(obj) {
486
+ if (obj === null || typeof obj !== "object") {
487
+ return obj;
488
+ }
489
+ if (obj instanceof Date) {
490
+ return new Date(obj.getTime());
491
+ }
492
+ if (Array.isArray(obj)) {
493
+ return obj.map((item) => this.deepClone(item));
494
+ }
495
+ const cloned = {};
496
+ for (const key in obj) {
497
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
498
+ cloned[key] = this.deepClone(obj[key]);
499
+ }
500
+ }
501
+ return cloned;
502
+ }
503
+ // ==================== 向后兼容 ====================
504
+ /**
505
+ * @deprecated 使用 encode() 替代
506
+ */
507
+ encoder(node) {
508
+ return this.encode(node);
509
+ }
510
+ }
@@ -0,0 +1,14 @@
1
+ export declare const TrackPointExtensionv1Key: string[];
2
+ export declare const TrackPointExtensionv1Mapping: {
3
+ temperature: string;
4
+ wtemp: string;
5
+ heartRate: string;
6
+ cadence: string;
7
+ };
8
+ export declare const GpxExtensionsv3Key: string[];
9
+ export declare const GpxExtensionsv3Mapping: {
10
+ temperature: string;
11
+ Depth: string;
12
+ };
13
+ export declare const PowerExtensionKey: never[];
14
+ export declare const PowerExtensionMapping: {};
@@ -0,0 +1,14 @@
1
+ export const TrackPointExtensionv1Key = ['temperature', 'heartRate', 'cadence'];
2
+ export const TrackPointExtensionv1Mapping = {
3
+ temperature: 'atemp',
4
+ wtemp: 'wtemp',
5
+ heartRate: 'hr',
6
+ cadence: 'cad',
7
+ };
8
+ export const GpxExtensionsv3Key = ['temperature', 'Depth'];
9
+ export const GpxExtensionsv3Mapping = {
10
+ temperature: 'Temperature',
11
+ Depth: 'Depth',
12
+ };
13
+ export const PowerExtensionKey = [];
14
+ export const PowerExtensionMapping = {};
@@ -0,0 +1,12 @@
1
+ import { GPXDecoder } from "./decoder.js";
2
+ import { GPXEncoder } from "./encoder.js";
3
+ import { registerDefaultMiddlewares } from "./converters.js";
4
+ import { PipelineStage } from "./processor.js";
5
+ export { GPXDecoder, GPXEncoder, registerDefaultMiddlewares, PipelineStage };
6
+ declare const _default: {
7
+ GPXDecoder: typeof GPXDecoder;
8
+ GPXEncoder: typeof GPXEncoder;
9
+ registerDefaultMiddlewares: typeof registerDefaultMiddlewares;
10
+ PipelineStage: typeof PipelineStage;
11
+ };
12
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { GPXDecoder } from "./decoder.js";
2
+ import { GPXEncoder } from "./encoder.js";
3
+ import { registerDefaultMiddlewares } from "./converters.js";
4
+ import { PipelineStage } from "./processor.js";
5
+ export { GPXDecoder, GPXEncoder, registerDefaultMiddlewares, PipelineStage };
6
+ export default {
7
+ GPXDecoder,
8
+ GPXEncoder,
9
+ registerDefaultMiddlewares,
10
+ PipelineStage,
11
+ };
@@ -0,0 +1,48 @@
1
+ import { DecoderContext } from "./types.js";
2
+ /**
3
+ * 流水线阶段
4
+ */
5
+ export declare enum PipelineStage {
6
+ TOKENIZE = "tokenize",
7
+ AST_GENERATE = "ast_generate",
8
+ CONVERT = "convert",
9
+ COMPLETE = "complete"
10
+ }
11
+ /**
12
+ * 流水线处理器
13
+ */
14
+ export interface IPipelineProcessor {
15
+ stage: PipelineStage;
16
+ process(context: DecoderContext): Promise<DecoderContext>;
17
+ }
18
+ /**
19
+ * Tokenize处理器
20
+ */
21
+ export declare class TokenizeProcessor implements IPipelineProcessor {
22
+ stage: PipelineStage;
23
+ process(context: DecoderContext): Promise<DecoderContext>;
24
+ }
25
+ /**
26
+ * AST生成处理器
27
+ */
28
+ export declare class AstGenerateProcessor implements IPipelineProcessor {
29
+ stage: PipelineStage;
30
+ process(context: DecoderContext): Promise<DecoderContext>;
31
+ }
32
+ /**
33
+ * 转换处理器
34
+ */
35
+ export declare class ConvertProcessor implements IPipelineProcessor {
36
+ private getConverter;
37
+ stage: PipelineStage;
38
+ constructor(getConverter: (tag: string) => any);
39
+ process(context: DecoderContext): Promise<DecoderContext>;
40
+ private assignResult;
41
+ }
42
+ /**
43
+ * 完成处理器
44
+ */
45
+ export declare class CompleteProcessor implements IPipelineProcessor {
46
+ stage: PipelineStage;
47
+ process(context: DecoderContext): Promise<DecoderContext>;
48
+ }