@agile-team/mach-report 2.5.0 → 2.6.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.
- package/README.md +91 -14
- package/dist/ReportPreview-Dk-28QAi.js +2946 -0
- package/dist/ReportPreview-FSvcBLjH.cjs +6 -0
- package/dist/_plugin-vue_export-helper-BHFhmbuH.cjs +1 -0
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
- package/dist/analytics.cjs +1 -0
- package/dist/analytics.d.cts +276 -0
- package/dist/analytics.d.ts +276 -0
- package/dist/analytics.js +223 -0
- package/dist/assets-66UBlhES.cjs +1 -0
- package/dist/assets-NVA_sftu.js +163 -0
- package/dist/capabilities-CNjIirfo.js +36 -0
- package/dist/capabilities-D4xeVYSR.cjs +1 -0
- package/dist/designer.cjs +1 -0
- package/dist/designer.d.cts +753 -0
- package/dist/designer.d.ts +753 -0
- package/dist/designer.js +372 -0
- package/dist/grid-geometry-BNptEcMm.js +65 -0
- package/dist/grid-geometry-CZ_cYB6O.cjs +1 -0
- package/dist/index.cjs +8 -5
- package/dist/index.d.cts +413 -8
- package/dist/index.d.ts +413 -8
- package/dist/index.js +1016 -1501
- package/dist/param-validation-BWNjLcN0.js +116 -0
- package/dist/param-validation-CiTxFeZ8.cjs +1 -0
- package/dist/pdf.cjs +48 -48
- package/dist/pdf.d.cts +111 -1
- package/dist/pdf.d.ts +111 -1
- package/dist/pdf.js +3931 -3868
- package/dist/{plugin-DMPLDpBY.cjs → plugin-BqBkn_kI.cjs} +1 -1
- package/dist/{plugin-DDLcFWlk.js → plugin-Ds10VnQO.js} +2 -2
- package/dist/render-plan-CckPEQyf.cjs +1 -0
- package/dist/{render-plan-CXBWRog4.js → render-plan-uzZYYSy1.js} +11 -10
- package/dist/report-params-B_VCihAh.js +12 -0
- package/dist/report-params-CjWrjPl6.cjs +1 -0
- package/dist/report-source-B9bENO0F.js +750 -0
- package/dist/report-source-BbNkkBDy.cjs +1 -0
- package/dist/server/node.d.cts +297 -0
- package/dist/server/node.d.ts +297 -0
- package/dist/server-node.cjs +1 -0
- package/dist/server-node.js +270 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.cts +643 -0
- package/dist/server.d.ts +643 -0
- package/dist/server.js +237 -0
- package/dist/style-CpwiOPyB.cjs +1 -0
- package/dist/style-Dv5o_x6b.js +67 -0
- package/dist/style.css +1 -1
- package/dist/template-registry-DWExx0gU.cjs +1 -0
- package/dist/template-registry-NpOakidD.js +354 -0
- package/dist/textwrap-CnGsEum6.cjs +4 -0
- package/dist/textwrap-DOl04hCQ.js +110 -0
- package/dist/validate-DfHPD8wX.cjs +1 -0
- package/dist/validate-S6CgIm5d.js +148 -0
- package/dist/vue/async.d.cts +602 -57
- package/dist/vue/async.d.ts +602 -57
- package/dist/vue/index.d.cts +1074 -111
- package/dist/vue/index.d.ts +1074 -111
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +167 -82
- package/dist/worker.cjs +1 -0
- package/dist/worker.d.cts +302 -0
- package/dist/worker.d.ts +302 -0
- package/dist/worker.js +133 -0
- package/dist/xlsx/node.d.cts +47 -0
- package/dist/xlsx/node.d.ts +47 -0
- package/dist/xlsx-node.cjs +221 -0
- package/dist/xlsx-node.js +36409 -0
- package/dist/xlsx.cjs +20 -20
- package/dist/xlsx.d.cts +78 -1
- package/dist/xlsx.d.ts +78 -1
- package/dist/xlsx.js +5974 -5831
- package/package.json +62 -2
- package/dist/ReportPreview-CBKLI--k.js +0 -2188
- package/dist/ReportPreview-ClM8h0pM.cjs +0 -6
- package/dist/grid-geometry-BNIvw52m.cjs +0 -1
- package/dist/grid-geometry-C8hGoe9o.js +0 -130
- package/dist/render-plan-CCTL4F9v.cjs +0 -1
- package/dist/report-params-B3Fia6JO.js +0 -10
- package/dist/report-params-D1gZ1DME.cjs +0 -1
- package/dist/textwrap-nH0UYU6D.js +0 -108
- package/dist/textwrap-oD-t4b4B.cjs +0 -4
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
export declare interface BrowserReportWorker {
|
|
2
|
+
postMessage(value: unknown, transfer?: Transferable[]): void;
|
|
3
|
+
terminate(): void;
|
|
4
|
+
addEventListener(type: "message", listener: (event: MessageEvent) => void): void;
|
|
5
|
+
addEventListener(type: "error" | "messageerror", listener: (event: Event) => void): void;
|
|
6
|
+
removeEventListener(type: "message", listener: (event: MessageEvent) => void): void;
|
|
7
|
+
removeEventListener(type: "error" | "messageerror", listener: (event: Event) => void): void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare type ComponentKind = "text" | "image" | "barcode" | "qrcode" | "chart" | "line" | "rect" | "ellipse";
|
|
11
|
+
|
|
12
|
+
declare interface ComponentStyle {
|
|
13
|
+
fontSizePx?: number;
|
|
14
|
+
fontSize?: number;
|
|
15
|
+
fontFamily?: string;
|
|
16
|
+
bold?: boolean;
|
|
17
|
+
italic?: boolean;
|
|
18
|
+
underline?: boolean;
|
|
19
|
+
color?: string;
|
|
20
|
+
backgroundColor?: string;
|
|
21
|
+
align?: "left" | "center" | "right" | "justify";
|
|
22
|
+
verticalAlign?: "top" | "middle" | "bottom";
|
|
23
|
+
lineColor?: string;
|
|
24
|
+
borderColor?: string;
|
|
25
|
+
lineWidthPt?: number;
|
|
26
|
+
borderTop?: boolean;
|
|
27
|
+
borderRight?: boolean;
|
|
28
|
+
borderBottom?: boolean;
|
|
29
|
+
borderLeft?: boolean;
|
|
30
|
+
lineHeight?: number;
|
|
31
|
+
letterSpacing?: number;
|
|
32
|
+
opacity?: number;
|
|
33
|
+
rotateDeg?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** factory 每次返回全新 Worker,例如 () => new Worker(new URL('./worker.ts', import.meta.url), {type:'module'})。 */
|
|
37
|
+
export declare function createBrowserReportExecutor(factory: () => BrowserReportWorker, options?: ReportWorkerOptions): ReportRuntimeExecutor;
|
|
38
|
+
|
|
39
|
+
declare interface GridCell {
|
|
40
|
+
text?: string;
|
|
41
|
+
rawText?: string;
|
|
42
|
+
/** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
|
|
43
|
+
value?: string | number | boolean | null;
|
|
44
|
+
/** Excel 数字格式(例如 #,##0.00 / 0.00%),不改变 text。 */
|
|
45
|
+
numberFormat?: string;
|
|
46
|
+
/** 编辑输入类型;省略时只按原始值推断,数字字符串不会被转换为数值。 */
|
|
47
|
+
valueType?: "text" | "number" | "boolean";
|
|
48
|
+
/** 单元格级编辑控制;预览仍需显式开启 editing。 */
|
|
49
|
+
editable?: boolean;
|
|
50
|
+
source?: ReportCellSource;
|
|
51
|
+
/** Excel 公式保留元数据;当前引擎不计算公式,公式格始终只读。 */
|
|
52
|
+
formula?: string;
|
|
53
|
+
children?: PlanComponent[];
|
|
54
|
+
colSpan?: number;
|
|
55
|
+
rowSpan?: number;
|
|
56
|
+
style?: ComponentStyle;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare interface PlanComponent {
|
|
60
|
+
kind: ComponentKind;
|
|
61
|
+
leftMm: number;
|
|
62
|
+
topMm: number;
|
|
63
|
+
widthMm: number;
|
|
64
|
+
heightMm: number;
|
|
65
|
+
nid?: string;
|
|
66
|
+
rkey?: string;
|
|
67
|
+
text?: string;
|
|
68
|
+
rawText?: string;
|
|
69
|
+
lines?: string[];
|
|
70
|
+
richParagraphs?: RichParagraph[];
|
|
71
|
+
imageData?: string;
|
|
72
|
+
/** 明确指定线段方向;省略保持历史水平线行为。 */
|
|
73
|
+
lineDirection?: "down" | "up";
|
|
74
|
+
grid?: PlanGrid;
|
|
75
|
+
table?: PlanTableFragment;
|
|
76
|
+
style?: ComponentStyle;
|
|
77
|
+
meta?: Record<string, unknown>;
|
|
78
|
+
/** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
|
|
79
|
+
fallbackText?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare interface PlanGrid {
|
|
83
|
+
/** 行内允许 null 空位;渲染器按空单元格处理 */
|
|
84
|
+
cells: (GridCell | null)[][];
|
|
85
|
+
colWidthsMm?: number[];
|
|
86
|
+
rowHeightsMm?: number[];
|
|
87
|
+
gapMm?: number;
|
|
88
|
+
/** 单元格四边内距;旧静态网格默认 0.5mm,分页列表使用其真实测量内距。 */
|
|
89
|
+
paddingMm?: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
declare interface PlanPage {
|
|
93
|
+
/** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
|
|
94
|
+
layout?: "page" | "wide";
|
|
95
|
+
pageWidthMm: number;
|
|
96
|
+
pageHeightMm: number;
|
|
97
|
+
marginTopMm?: number;
|
|
98
|
+
marginBottomMm?: number;
|
|
99
|
+
marginLeftMm?: number;
|
|
100
|
+
marginRightMm?: number;
|
|
101
|
+
components: PlanComponent[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
|
|
105
|
+
declare interface PlanTableFragment {
|
|
106
|
+
/** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
|
|
107
|
+
id: string;
|
|
108
|
+
/** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
|
|
109
|
+
rowIndex: number;
|
|
110
|
+
role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
|
|
111
|
+
/** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
|
|
112
|
+
columnKeys: string[];
|
|
113
|
+
layout?: "page" | "wide";
|
|
114
|
+
title?: string;
|
|
115
|
+
/** 只有宿主声明稳定 rowKey 时生成,不能用显示顺序替代业务主键。 */
|
|
116
|
+
source?: Omit<ReportCellSource, "field" | "rowKey"> & {
|
|
117
|
+
rowKey?: string | number;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
declare interface PreparedReport {
|
|
122
|
+
plan: RenderPlan;
|
|
123
|
+
diagnostics: ReportDiagnostic[];
|
|
124
|
+
stats: ReportRuntimeStats;
|
|
125
|
+
revisions: Record<string, {
|
|
126
|
+
revision?: string;
|
|
127
|
+
sourceToken?: string;
|
|
128
|
+
}>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
declare interface RenderPlan {
|
|
132
|
+
schemaVersion: string;
|
|
133
|
+
pages: PlanPage[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** 可持久化的业务身份与计划坐标独立;权限及并发校验仍由业务服务器执行。 */
|
|
137
|
+
declare interface ReportCellSource {
|
|
138
|
+
datasetId: string;
|
|
139
|
+
rowKey: string | number;
|
|
140
|
+
field: string;
|
|
141
|
+
revision?: string | number;
|
|
142
|
+
sourceToken?: string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
declare interface ReportDescription {
|
|
146
|
+
id: string;
|
|
147
|
+
params: ReportParamDef[];
|
|
148
|
+
paramsSchema: Record<string, unknown>;
|
|
149
|
+
datasetsSchema: Record<string, Record<string, unknown>>;
|
|
150
|
+
/** Provider 的可选远程能力;runtime 自身始终提供 PDF/XLSX 导出。 */
|
|
151
|
+
capabilities: {
|
|
152
|
+
save: boolean;
|
|
153
|
+
export: boolean;
|
|
154
|
+
templates: boolean;
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
declare interface ReportDiagnostic {
|
|
159
|
+
code: string;
|
|
160
|
+
message: string;
|
|
161
|
+
path?: string;
|
|
162
|
+
severity: "warning" | "error" | "info";
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** 报表参数定义(声明式,模板自描述参数面:渲染组件据此生成查询面板) */
|
|
166
|
+
declare interface ReportParamDef {
|
|
167
|
+
/** 参数名(传入 params,与数据集 SQL #{field} 绑定对应) */
|
|
168
|
+
field: string;
|
|
169
|
+
/** 显示名(缺省用 field) */
|
|
170
|
+
label?: string;
|
|
171
|
+
type?: "text" | "number" | "date" | "select";
|
|
172
|
+
/** select 选项 */
|
|
173
|
+
options?: Array<{
|
|
174
|
+
label: string;
|
|
175
|
+
value: string;
|
|
176
|
+
}>;
|
|
177
|
+
defaultValue?: string;
|
|
178
|
+
required?: boolean;
|
|
179
|
+
placeholder?: string;
|
|
180
|
+
/** 数字上下界;date 参数使用 YYYY-MM-DD 字符串(含边界)。 */
|
|
181
|
+
min?: number | string;
|
|
182
|
+
max?: number | string;
|
|
183
|
+
minLength?: number;
|
|
184
|
+
maxLength?: number;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
declare interface ReportParamIssue {
|
|
188
|
+
code: ReportParamIssueCode;
|
|
189
|
+
path: string;
|
|
190
|
+
field: string;
|
|
191
|
+
message: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
declare type ReportParamIssueCode = "definition" | "required" | "type" | "option" | "minimum" | "maximum" | "minLength" | "maxLength";
|
|
195
|
+
|
|
196
|
+
declare interface ReportParamValidation {
|
|
197
|
+
ok: boolean;
|
|
198
|
+
/** 保留历史取数契约的字符串形式;未知参数保留,不能代替接口权限白名单。 */
|
|
199
|
+
values: Record<string, string>;
|
|
200
|
+
/** JSON Schema 对应的规范值:number 参数转换为有限数字。 */
|
|
201
|
+
typedValues: Record<string, string | number>;
|
|
202
|
+
issues: ReportParamIssue[];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
declare interface ReportRuntime {
|
|
206
|
+
describe(reportIds?: string[]): ReportDescription[];
|
|
207
|
+
validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
|
|
208
|
+
prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
|
|
209
|
+
export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
|
|
213
|
+
declare interface ReportRuntimeExecutor {
|
|
214
|
+
prepare(input: Omit<ReportRuntimeInput, "signal">, signal?: AbortSignal): Promise<PreparedReport>;
|
|
215
|
+
export(input: Omit<ReportRuntimeExportInput, "signal">, signal?: AbortSignal): Promise<ReportRuntimeExportResult>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
|
|
219
|
+
format: "pdf" | "xlsx";
|
|
220
|
+
/** PDF 中文需宿主显式提供有授权的字体;不隐式下载字体或资源。 */
|
|
221
|
+
pdf?: {
|
|
222
|
+
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
223
|
+
customFontName?: string;
|
|
224
|
+
customFontFaces?: {
|
|
225
|
+
regular: Uint8Array | ArrayBuffer;
|
|
226
|
+
bold?: Uint8Array | ArrayBuffer;
|
|
227
|
+
italic?: Uint8Array | ArrayBuffer;
|
|
228
|
+
boldItalic?: Uint8Array | ArrayBuffer;
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
xlsx?: {
|
|
232
|
+
sheetMode?: "auto" | "pages" | "continuous";
|
|
233
|
+
valueMode?: "text" | "raw";
|
|
234
|
+
paperSize?: "auto" | "a3" | "a4" | "a5";
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
declare interface ReportRuntimeExportResult extends Omit<PreparedReport, "plan"> {
|
|
239
|
+
bytes: Uint8Array;
|
|
240
|
+
format: "pdf" | "xlsx";
|
|
241
|
+
contentType: string;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
declare interface ReportRuntimeInput {
|
|
245
|
+
reportIds: string[];
|
|
246
|
+
params?: Record<string, string>;
|
|
247
|
+
signal?: AbortSignal;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
declare interface ReportRuntimeStats {
|
|
251
|
+
rows: number;
|
|
252
|
+
pages: number;
|
|
253
|
+
cells: number;
|
|
254
|
+
durationMs: number;
|
|
255
|
+
outputBytes?: number;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export declare class ReportWorkerError extends Error {
|
|
259
|
+
readonly code?: string;
|
|
260
|
+
readonly path?: string;
|
|
261
|
+
readonly issues?: unknown;
|
|
262
|
+
constructor(error: SerializedReportError);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export declare interface ReportWorkerOptions {
|
|
266
|
+
timeoutMs?: number;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export declare interface ReportWorkerScope {
|
|
270
|
+
postMessage(value: unknown, transfer?: Transferable[]): void;
|
|
271
|
+
addEventListener(type: "message", listener: (event: MessageEvent) => void): void;
|
|
272
|
+
removeEventListener(type: "message", listener: (event: MessageEvent) => void): void;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
declare interface RichParagraph {
|
|
276
|
+
segments: RichSegment[];
|
|
277
|
+
align?: ComponentStyle["align"];
|
|
278
|
+
lineHeight?: number;
|
|
279
|
+
spaceBeforeMm?: number;
|
|
280
|
+
spaceAfterMm?: number;
|
|
281
|
+
indentMm?: number;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
declare interface RichSegment {
|
|
285
|
+
kind?: "text" | "field";
|
|
286
|
+
text?: string;
|
|
287
|
+
field?: string;
|
|
288
|
+
style?: ComponentStyle;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
declare interface SerializedReportError {
|
|
292
|
+
name: string;
|
|
293
|
+
message: string;
|
|
294
|
+
code?: string;
|
|
295
|
+
path?: string;
|
|
296
|
+
issues?: unknown;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/** 在 Worker 入口注册一次 runtime;返回函数可清理监听器,浏览器主线程无需引入 Node。 */
|
|
300
|
+
export declare function serveReportWorker(runtime: ReportRuntime, scope?: ReportWorkerScope): () => void;
|
|
301
|
+
|
|
302
|
+
export { }
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { c as v } from "./validate-S6CgIm5d.js";
|
|
2
|
+
const u = "mach-report-worker/1";
|
|
3
|
+
class R extends Error {
|
|
4
|
+
constructor(e) {
|
|
5
|
+
super(e.message), this.name = e.name, this.code = e.code, this.path = e.path, this.issues = e.issues;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function m(r) {
|
|
9
|
+
return !!r && typeof r == "object" && !Array.isArray(r);
|
|
10
|
+
}
|
|
11
|
+
function x(r) {
|
|
12
|
+
return m(r) ? ["rows", "pages", "cells"].every((e) => typeof r[e] == "number" && Number.isSafeInteger(r[e]) && r[e] >= 0) && typeof r.durationMs == "number" && Number.isFinite(r.durationMs) && r.durationMs >= 0 : !1;
|
|
13
|
+
}
|
|
14
|
+
function M(r) {
|
|
15
|
+
return Array.isArray(r) && r.every((e) => m(e) && typeof e.code == "string" && typeof e.message == "string" && ["info", "warning", "error"].includes(e.severity));
|
|
16
|
+
}
|
|
17
|
+
function L(r) {
|
|
18
|
+
return m(r) && Object.values(r).every((e) => m(e) && (e.revision === void 0 || typeof e.revision == "string") && (e.sourceToken === void 0 || typeof e.sourceToken == "string"));
|
|
19
|
+
}
|
|
20
|
+
function A(r, e) {
|
|
21
|
+
if (!m(r) || !x(r.stats) || !M(r.diagnostics) || !L(r.revisions)) return !1;
|
|
22
|
+
if (e === "prepare") return v(r.plan).ok;
|
|
23
|
+
const t = r.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
24
|
+
return r.bytes instanceof Uint8Array && (r.format === "pdf" || r.format === "xlsx") && r.contentType === t;
|
|
25
|
+
}
|
|
26
|
+
function T(r) {
|
|
27
|
+
if (!r || typeof r != "object") return { message: String(r) };
|
|
28
|
+
const e = {};
|
|
29
|
+
for (const t of ["code", "path", "field", "message"]) {
|
|
30
|
+
const o = r[t];
|
|
31
|
+
typeof o == "string" && (e[t] = o);
|
|
32
|
+
}
|
|
33
|
+
return e;
|
|
34
|
+
}
|
|
35
|
+
function j(r) {
|
|
36
|
+
if (!(r instanceof Error)) return { name: "Error", message: String(r) };
|
|
37
|
+
const e = r;
|
|
38
|
+
return {
|
|
39
|
+
name: r.name,
|
|
40
|
+
message: r.message,
|
|
41
|
+
...typeof e.code == "string" ? { code: e.code } : {},
|
|
42
|
+
...typeof e.path == "string" ? { path: e.path } : {},
|
|
43
|
+
...Array.isArray(e.issues) ? { issues: e.issues.map(T) } : {}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function O(r) {
|
|
47
|
+
if (!r || typeof r != "object") return !1;
|
|
48
|
+
const e = r;
|
|
49
|
+
return e.protocol === u && typeof e.id == "string" && (e.operation === "prepare" || e.operation === "export") && !!e.input && typeof e.input == "object";
|
|
50
|
+
}
|
|
51
|
+
async function P(r, e) {
|
|
52
|
+
try {
|
|
53
|
+
const t = e.operation === "prepare" ? await r.prepare(e.input) : await r.export(e.input);
|
|
54
|
+
return { protocol: u, id: e.id, result: t };
|
|
55
|
+
} catch (t) {
|
|
56
|
+
return { protocol: u, id: e.id, error: j(t) };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function N(r) {
|
|
60
|
+
const e = r.result;
|
|
61
|
+
return !e || !("bytes" in e) || !(e.bytes.buffer instanceof ArrayBuffer) ? [] : [e.bytes.buffer];
|
|
62
|
+
}
|
|
63
|
+
let S = 0;
|
|
64
|
+
function w(r) {
|
|
65
|
+
const e = new Error("报表 Worker 任务已取消");
|
|
66
|
+
return e.name = "AbortError", Object.defineProperty(e, "cause", { value: r }), e;
|
|
67
|
+
}
|
|
68
|
+
function $(r, e) {
|
|
69
|
+
if (!r || typeof r != "object") return;
|
|
70
|
+
const t = r;
|
|
71
|
+
return t.protocol === u && t.id === e ? t : void 0;
|
|
72
|
+
}
|
|
73
|
+
function z(r, e = {}) {
|
|
74
|
+
const t = e.timeoutMs ?? 12e4;
|
|
75
|
+
if (!Number.isFinite(t) || t <= 0 || t > 2147483647) throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");
|
|
76
|
+
const o = (s, c, n) => n?.aborted ? Promise.reject(w(n.reason)) : new Promise((p, g) => {
|
|
77
|
+
let d;
|
|
78
|
+
try {
|
|
79
|
+
d = r();
|
|
80
|
+
} catch (i) {
|
|
81
|
+
g(i);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const l = `mach-report-${Date.now()}-${++S}`;
|
|
85
|
+
let b = !1, y = () => {
|
|
86
|
+
}, E;
|
|
87
|
+
const f = (i, a) => {
|
|
88
|
+
b || (b = !0, E && clearTimeout(E), y(), n?.removeEventListener("abort", h), Promise.resolve().then(() => d.terminate()).then(
|
|
89
|
+
() => i === void 0 ? p(a) : g(i),
|
|
90
|
+
(W) => g(i ?? W)
|
|
91
|
+
));
|
|
92
|
+
}, h = () => f(w(n?.reason)), k = (i) => {
|
|
93
|
+
const a = $(i, l);
|
|
94
|
+
a && (a.error && typeof a.error.name == "string" && typeof a.error.message == "string" ? f(new R(a.error)) : A(a.result, s) && (s !== "export" || "format" in a.result && "format" in c && a.result.format === c.format) ? f(void 0, a.result) : f(new Error("报表 Worker 返回无效响应")));
|
|
95
|
+
};
|
|
96
|
+
try {
|
|
97
|
+
if (y = d.subscribe(k, (i) => f(i ?? new Error("报表 Worker 执行失败"))), b) {
|
|
98
|
+
y();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
n?.addEventListener("abort", h, { once: !0 }), E = setTimeout(() => f(new R({ name: "ReportRuntimeError", code: "timeout", message: `报表 Worker 执行超过 ${t}ms` })), t), n?.aborted ? h() : d.postMessage({ protocol: u, id: l, operation: s, input: c });
|
|
102
|
+
} catch (i) {
|
|
103
|
+
f(i);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return { prepare: (s, c) => o("prepare", s, c), export: (s, c) => o("export", s, c) };
|
|
107
|
+
}
|
|
108
|
+
function F(r, e = {}) {
|
|
109
|
+
return z(() => {
|
|
110
|
+
const t = r();
|
|
111
|
+
return {
|
|
112
|
+
postMessage: (o) => t.postMessage(o),
|
|
113
|
+
terminate: () => t.terminate(),
|
|
114
|
+
subscribe: (o, s) => {
|
|
115
|
+
const c = (p) => o(p.data), n = (p) => s(p instanceof ErrorEvent ? new Error(p.message) : new Error("报表 Worker 消息无法解码"));
|
|
116
|
+
return t.addEventListener("message", c), t.addEventListener("error", n), t.addEventListener("messageerror", n), () => {
|
|
117
|
+
t.removeEventListener("message", c), t.removeEventListener("error", n), t.removeEventListener("messageerror", n);
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}, e);
|
|
122
|
+
}
|
|
123
|
+
function I(r, e = globalThis) {
|
|
124
|
+
const t = (o) => {
|
|
125
|
+
O(o.data) && P(r, o.data).then((s) => e.postMessage(s, N(s)));
|
|
126
|
+
};
|
|
127
|
+
return e.addEventListener("message", t), () => e.removeEventListener("message", t);
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
R as ReportWorkerError,
|
|
131
|
+
F as createBrowserReportExecutor,
|
|
132
|
+
I as serveReportWorker
|
|
133
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
import { Writable } from 'node:stream';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Commits each source row directly to ExcelJS WorkbookWriter. No RenderPlan, full row array,
|
|
7
|
+
* Workbook or Buffer is retained. Styles are column-scoped; shared strings are disabled.
|
|
8
|
+
* Destination is ended by the writer. An abort/error leaves a partial, unusable XLSX file.
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeRowsToXlsx<Row extends object>(rows: AsyncIterable<Row> | Iterable<Row>, options: XlsxStreamOptions<Row>): Promise<XlsxStreamProgress>;
|
|
11
|
+
|
|
12
|
+
export declare type XlsxRowValue = string | number | boolean | Date | null | undefined;
|
|
13
|
+
|
|
14
|
+
export declare interface XlsxStreamColumn<Row> {
|
|
15
|
+
key: keyof Row & string;
|
|
16
|
+
header?: string;
|
|
17
|
+
width?: number;
|
|
18
|
+
numberFormat?: string;
|
|
19
|
+
value?: (row: Row, rowIndex: number) => XlsxRowValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare interface XlsxStreamCommonOptions<Row> {
|
|
23
|
+
columns: readonly XlsxStreamColumn<Row>[];
|
|
24
|
+
sheetName?: string;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
/** Data rows, excluding the header. Excel's hard limit is always enforced. */
|
|
27
|
+
maxRows?: number;
|
|
28
|
+
maxDurationMs?: number;
|
|
29
|
+
/** Yield/check downstream backpressure after each batch (default 256). */
|
|
30
|
+
batchSize?: number;
|
|
31
|
+
onProgress?: (progress: XlsxStreamProgress) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export declare type XlsxStreamOptions<Row> = XlsxStreamCommonOptions<Row> & ({
|
|
35
|
+
stream: Writable;
|
|
36
|
+
filename?: never;
|
|
37
|
+
} | {
|
|
38
|
+
filename: string;
|
|
39
|
+
stream?: never;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export declare interface XlsxStreamProgress {
|
|
43
|
+
rowsWritten: number;
|
|
44
|
+
elapsedMs: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { }
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
import { Writable } from 'node:stream';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Commits each source row directly to ExcelJS WorkbookWriter. No RenderPlan, full row array,
|
|
7
|
+
* Workbook or Buffer is retained. Styles are column-scoped; shared strings are disabled.
|
|
8
|
+
* Destination is ended by the writer. An abort/error leaves a partial, unusable XLSX file.
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeRowsToXlsx<Row extends object>(rows: AsyncIterable<Row> | Iterable<Row>, options: XlsxStreamOptions<Row>): Promise<XlsxStreamProgress>;
|
|
11
|
+
|
|
12
|
+
export declare type XlsxRowValue = string | number | boolean | Date | null | undefined;
|
|
13
|
+
|
|
14
|
+
export declare interface XlsxStreamColumn<Row> {
|
|
15
|
+
key: keyof Row & string;
|
|
16
|
+
header?: string;
|
|
17
|
+
width?: number;
|
|
18
|
+
numberFormat?: string;
|
|
19
|
+
value?: (row: Row, rowIndex: number) => XlsxRowValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare interface XlsxStreamCommonOptions<Row> {
|
|
23
|
+
columns: readonly XlsxStreamColumn<Row>[];
|
|
24
|
+
sheetName?: string;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
/** Data rows, excluding the header. Excel's hard limit is always enforced. */
|
|
27
|
+
maxRows?: number;
|
|
28
|
+
maxDurationMs?: number;
|
|
29
|
+
/** Yield/check downstream backpressure after each batch (default 256). */
|
|
30
|
+
batchSize?: number;
|
|
31
|
+
onProgress?: (progress: XlsxStreamProgress) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export declare type XlsxStreamOptions<Row> = XlsxStreamCommonOptions<Row> & ({
|
|
35
|
+
stream: Writable;
|
|
36
|
+
filename?: never;
|
|
37
|
+
} | {
|
|
38
|
+
filename: string;
|
|
39
|
+
stream?: never;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export declare interface XlsxStreamProgress {
|
|
43
|
+
rowsWritten: number;
|
|
44
|
+
elapsedMs: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { }
|