@agile-team/mach-report 2.12.0 → 2.14.0
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 +27 -3
- package/dist/ExcelBindingWizard-CLT2p7P3.cjs +1 -0
- package/dist/ExcelBindingWizard-CvsWR8Ga.js +1485 -0
- package/dist/{ParamEditor-BLaE5q5W.js → ParamEditor-CflQV3eQ.js} +191 -187
- package/dist/ParamEditor-vIDzvpPV.cjs +1 -0
- package/dist/ReportBatchPanel-DkxTzBkD.cjs +1 -0
- package/dist/{ReportBatchPanel-B5ClP9tm.js → ReportBatchPanel-LqVgiqp7.js} +3 -3
- package/dist/ReportPreview-CvbqLUzM.cjs +6 -0
- package/dist/ReportPreview-D_ywJ_-H.js +4533 -0
- package/dist/{ReportTemplateLibrary-BZB-XWjj.js → ReportTemplateLibrary-MjWEtc7X.js} +1 -1
- package/dist/ReportTemplateLibrary-cQ1sqNYo.cjs +1 -0
- package/dist/RuleEditor-BaR6xUiI.cjs +1 -0
- package/dist/RuleEditor-ChuXMlei.js +2037 -0
- package/dist/TemplateOutlinePanel-BHKP89Xz.cjs +1 -0
- package/dist/TemplateOutlinePanel-Dci6aRn1.js +96 -0
- package/dist/TemplateReusePanel-B7Gmyc1z.js +388 -0
- package/dist/TemplateReusePanel-CY5eO2Sh.cjs +1 -0
- package/dist/TemplateReviewPanel-DjlX3xpt.js +592 -0
- package/dist/TemplateReviewPanel-JvZe9_4G.cjs +1 -0
- package/dist/{batch-mRqhhhjt.js → batch-DzaTNLWI.js} +23 -16
- package/dist/batch-xMkqYiTr.cjs +1 -0
- package/dist/config-0UIohTS7.cjs +1 -0
- package/dist/{config-B612mw0x.js → config-Dt9NtCPl.js} +227 -186
- package/dist/data-explanation-BktvER5B.cjs +1 -0
- package/dist/data-explanation-C_J6jYNi.js +16 -0
- package/dist/designer-Ci1LizA9.js +5020 -0
- package/dist/designer-rtmVIIdN.cjs +2 -0
- package/dist/designer.cjs +1 -2
- package/dist/designer.d.cts +306 -3
- package/dist/designer.d.ts +306 -3
- package/dist/designer.js +21 -4266
- package/dist/font-loader-DHto6Lra.js +297 -0
- package/dist/font-loader-vhCT8znW.cjs +1 -0
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +182 -1
- package/dist/index.d.ts +182 -1
- package/dist/index.js +728 -628
- package/dist/{template-review-BzpcI-tR.js → json-snapshot-BeFT3Tso.js} +867 -637
- package/dist/json-snapshot-D1NTP2oI.cjs +2 -0
- package/dist/pdf-8UPQebOE.js +36288 -0
- package/dist/pdf-AyJGb22z.cjs +101 -0
- package/dist/pdf.cjs +1 -101
- package/dist/pdf.js +9 -36579
- package/dist/plugin-BGKf-Tqg.js +22 -0
- package/dist/{plugin-BDTU4D94.cjs → plugin-CktLH_Iy.cjs} +1 -1
- package/dist/{region-binding-workflow-CcUq8W2Q.js → region-binding-workflow-DEJbhpCv.js} +1 -1
- package/dist/server/node.d.cts +46 -11
- package/dist/server/node.d.ts +46 -11
- package/dist/server-node.cjs +1 -1
- package/dist/server-node.js +294 -280
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +107 -12
- package/dist/server.d.ts +107 -12
- package/dist/server.js +713 -453
- package/dist/style.css +1 -1
- package/dist/template-bindings-BJR4k7qZ.cjs +1 -0
- package/dist/template-bindings-Daui7hLF.js +252 -0
- package/dist/template-fragments-CLkGo6To.js +187 -0
- package/dist/template-fragments-DFUpq5QM.cjs +1 -0
- package/dist/template-outline-B3xVkzSv.cjs +1 -0
- package/dist/template-outline-CFenM1PV.js +88 -0
- package/dist/{template-registry-BjE1VS6g.js → template-registry-COXDEJEM.js} +1 -1
- package/dist/{useLocalDraft-C07SYRnC.js → useLocalDraft-BnhcxXk_.js} +1 -1
- package/dist/{useLocalDraft-Yiw1wFgI.cjs → useLocalDraft-CioIfDb6.cjs} +1 -1
- package/dist/{validate-DbgEM1Hh.js → validate-CkQBWCeg.js} +3 -3
- package/dist/vue/async.d.cts +72 -2
- package/dist/vue/async.d.ts +72 -2
- package/dist/vue/index.d.cts +124 -5
- package/dist/vue/index.d.ts +124 -5
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +5 -5
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +78 -71
- package/dist/{workbook-session-BPb3TMnT.js → workbook-session-BfK1yHOO.js} +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.cts +46 -11
- package/dist/worker.d.ts +46 -11
- package/dist/worker.js +59 -55
- package/dist/xlsx.js +3 -3
- package/package.json +1 -1
- package/dist/ExcelBindingWizard-CeAf4QSE.js +0 -1465
- package/dist/ExcelBindingWizard-y0mT-AHR.cjs +0 -1
- package/dist/ParamEditor-MBBC7lUE.cjs +0 -1
- package/dist/ReportBatchPanel-Dc-SDkYA.cjs +0 -1
- package/dist/ReportPreview-DWXROHBP.cjs +0 -6
- package/dist/ReportPreview-DiNXhQI0.js +0 -4138
- package/dist/ReportTemplateLibrary-5fk5CQBO.cjs +0 -1
- package/dist/RuleEditor-ChRzNQuF.cjs +0 -1
- package/dist/RuleEditor-DzAmW5YH.js +0 -2024
- package/dist/TemplateReviewPanel-BKofGrV9.js +0 -222
- package/dist/TemplateReviewPanel-DwtOcLue.cjs +0 -1
- package/dist/batch-Bt3Fd27Z.cjs +0 -1
- package/dist/config-BRoLo2oj.cjs +0 -1
- package/dist/plugin-Cd5G2QQn.js +0 -22
- package/dist/record-bindings-By_UKZ2g.cjs +0 -1
- package/dist/record-bindings-D-5jQlTj.js +0 -196
- package/dist/template-review-BfCC8Ng9.cjs +0 -2
package/dist/server-node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { parentPort as
|
|
1
|
+
import { parentPort as _, Worker as H } from "node:worker_threads";
|
|
2
2
|
import { randomUUID as P, createHash as W } from "node:crypto";
|
|
3
3
|
import { promises as h } from "node:fs";
|
|
4
|
-
import
|
|
5
|
-
function Z(e, t,
|
|
6
|
-
if (!
|
|
4
|
+
import v from "node:path";
|
|
5
|
+
function Z(e, t, r) {
|
|
6
|
+
if (!r?.aborted)
|
|
7
7
|
try {
|
|
8
8
|
const o = e?.({ ...t });
|
|
9
9
|
o && typeof o.then == "function" && Promise.resolve(o).catch(() => {
|
|
@@ -11,43 +11,54 @@ function Z(e, t, n) {
|
|
|
11
11
|
} catch {
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
function Q(e
|
|
15
|
-
e
|
|
14
|
+
function Q(e) {
|
|
15
|
+
if (!e || typeof e != "object" || Array.isArray(e)) return !1;
|
|
16
|
+
const t = e, r = (o) => typeof o == "string" && o.trim().length > 0 && o.length <= 256;
|
|
17
|
+
return !r(t.datasetId) || !r(t.field) || t.tableId !== void 0 && !r(t.tableId) ? !1 : t.rowKey === void 0 ? !0 : typeof t.rowKey == "string" ? t.rowKey.trim().length > 0 && t.rowKey.length <= 1024 : typeof t.rowKey == "number" && Number.isFinite(t.rowKey);
|
|
16
18
|
}
|
|
17
|
-
function V(e
|
|
18
|
-
|
|
19
|
+
function V(e) {
|
|
20
|
+
return e === "missing-source" || e === "not-applicable" || e === "not-calculable";
|
|
19
21
|
}
|
|
20
|
-
function
|
|
22
|
+
function G(e) {
|
|
23
|
+
return e.target !== void 0 && !Q(e.target) ? !1 : e.valueState === void 0 || V(e.valueState) && e.target !== void 0;
|
|
24
|
+
}
|
|
25
|
+
function X(e, t, r) {
|
|
26
|
+
e.editable !== void 0 && typeof e.editable != "boolean" && r.push({ path: `${t}.editable`, message: "编辑控制应为布尔值" }), e.valueType !== void 0 && !["text", "number", "boolean"].includes(e.valueType) && r.push({ path: `${t}.valueType`, message: "编辑类型应为 text、number 或 boolean" });
|
|
27
|
+
}
|
|
28
|
+
function Y(e, t, r) {
|
|
29
|
+
X(e, t, r), e.indentMm !== void 0 && (typeof e.indentMm != "number" || !Number.isFinite(e.indentMm) || e.indentMm < 0) && r.push({ path: `${t}.indentMm`, message: "单元格缩进应为有限非负数" }), e.derived !== void 0 && typeof e.derived != "boolean" && r.push({ path: `${t}.derived`, message: "派生结果标记应为布尔值" }), F(e.source, `${t}.source`, r, !0), e.formula !== void 0 && typeof e.formula != "string" && r.push({ path: `${t}.formula`, message: "单元格公式应为字符串" });
|
|
30
|
+
}
|
|
31
|
+
function F(e, t, r, o = !1) {
|
|
21
32
|
if (e === void 0) return;
|
|
22
33
|
if (!e || typeof e != "object" || Array.isArray(e)) {
|
|
23
|
-
|
|
34
|
+
r.push({ path: t, message: "业务来源应为对象" });
|
|
24
35
|
return;
|
|
25
36
|
}
|
|
26
|
-
const
|
|
37
|
+
const n = e;
|
|
27
38
|
for (const s of ["datasetId", ...o ? ["field"] : []])
|
|
28
|
-
(typeof
|
|
39
|
+
(typeof n[s] != "string" || !n[s].trim()) && r.push({ path: `${t}.${s}`, message: "业务标识应为非空字符串" });
|
|
29
40
|
for (const s of ["rowKey", "revision"]) {
|
|
30
|
-
const i =
|
|
31
|
-
i === void 0 && !(o && s === "rowKey") || typeof i != "string" && !(typeof i == "number" && Number.isFinite(i)) &&
|
|
41
|
+
const i = n[s];
|
|
42
|
+
i === void 0 && !(o && s === "rowKey") || typeof i != "string" && !(typeof i == "number" && Number.isFinite(i)) && r.push({ path: `${t}.${s}`, message: "业务键及修订号应为字符串或有限数字" });
|
|
32
43
|
}
|
|
33
|
-
|
|
44
|
+
n.sourceToken !== void 0 && typeof n.sourceToken != "string" && r.push({ path: `${t}.sourceToken`, message: "来源令牌应为字符串" });
|
|
34
45
|
}
|
|
35
|
-
function
|
|
46
|
+
function ee(e) {
|
|
36
47
|
const t = [];
|
|
37
48
|
return e.value !== void 0 && typeof e.value != "string" && t.push({ path: "value", message: "Symbol value must be a string." }), e.symbology !== void 0 && !["code128", "code39", "ean13", "ean8"].includes(e.symbology) && t.push({ path: "symbology", message: "Unsupported barcode symbology." }), e.errorCorrection !== void 0 && !["L", "M", "Q", "H"].includes(e.errorCorrection) && t.push({ path: "errorCorrection", message: "Unsupported QR error correction." }), e.showText !== void 0 && typeof e.showText != "boolean" && t.push({ path: "showText", message: "showText must be a boolean." }), t;
|
|
38
49
|
}
|
|
39
|
-
function
|
|
40
|
-
const
|
|
41
|
-
return t !== "barcode" && t !== "qrcode" &&
|
|
50
|
+
function te(e, t) {
|
|
51
|
+
const r = [];
|
|
52
|
+
return t !== "barcode" && t !== "qrcode" && r.push({ path: "", message: "code is only supported by barcode and qrcode components." }), t === "qrcode" && e.symbology !== void 0 && r.push({ path: "symbology", message: "QR components do not use a linear symbology." }), t === "qrcode" && e.showText === !0 && r.push({ path: "showText", message: "Use a separate text component below a QR code." }), t === "barcode" && e.errorCorrection !== void 0 && r.push({ path: "errorCorrection", message: "Linear barcodes do not use QR error correction." }), r;
|
|
42
53
|
}
|
|
43
|
-
function
|
|
54
|
+
function re(e, t) {
|
|
44
55
|
if (typeof e != "object" || e === null || Array.isArray(e)) return [{ path: "", message: "code must be an object." }];
|
|
45
|
-
const
|
|
46
|
-
for (const i of Object.keys(
|
|
47
|
-
const
|
|
48
|
-
return
|
|
56
|
+
const r = e, o = [...ee(r), ...te(r, t)];
|
|
57
|
+
for (const i of Object.keys(r)) ["value", "symbology", "errorCorrection", "quietZoneModules", "showText"].includes(i) || o.push({ path: i, message: "Unknown symbol option." });
|
|
58
|
+
const n = r.symbology === "ean13" || r.symbology === "ean8", s = t === "qrcode" ? 4 : n ? 11 : 10;
|
|
59
|
+
return r.quietZoneModules !== void 0 && (!Number.isSafeInteger(r.quietZoneModules) || Number(r.quietZoneModules) < s || Number(r.quietZoneModules) > 64) && o.push({ path: "quietZoneModules", message: `Quiet zone must contain ${s}–64 whole modules.` }), o;
|
|
49
60
|
}
|
|
50
|
-
const
|
|
61
|
+
const ne = /* @__PURE__ */ new Set([
|
|
51
62
|
"text",
|
|
52
63
|
"image",
|
|
53
64
|
"barcode",
|
|
@@ -60,118 +71,118 @@ const ee = /* @__PURE__ */ new Set([
|
|
|
60
71
|
function A(e) {
|
|
61
72
|
return typeof e == "object" && e !== null && !Array.isArray(e);
|
|
62
73
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
(typeof
|
|
74
|
+
function oe(e, t, r, o) {
|
|
75
|
+
const n = e[t];
|
|
76
|
+
(typeof n != "number" || !Number.isFinite(n)) && o.push({ path: `${r}.${t}`, message: `应为有限数字,实际 ${JSON.stringify(n)}` });
|
|
66
77
|
}
|
|
67
|
-
function
|
|
78
|
+
function se(e, t, r) {
|
|
68
79
|
if (e !== void 0) {
|
|
69
80
|
const o = `${t}.table`;
|
|
70
|
-
if (!A(e))
|
|
81
|
+
if (!A(e)) r.push({ path: o, message: "逻辑表来源应为对象" });
|
|
71
82
|
else {
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
["header", "body", "group-header", "subtotal", "grand-total"].includes(
|
|
83
|
+
F(e.source, `${o}.source`, r), (typeof e.id != "string" || !e.id.trim()) && r.push({ path: `${o}.id`, message: "逻辑表 ID 应为非空字符串" });
|
|
84
|
+
const n = e.role;
|
|
85
|
+
["header", "body", "group-header", "subtotal", "grand-total"].includes(n) || r.push({ path: `${o}.role`, message: "未知逻辑表行角色" });
|
|
75
86
|
const s = e.rowIndex;
|
|
76
|
-
(typeof s != "number" || !Number.isInteger(s) || (
|
|
87
|
+
(typeof s != "number" || !Number.isInteger(s) || (n === "header" ? s !== -1 : s < 0)) && r.push({ path: `${o}.rowIndex`, message: "表头索引应为 -1,内容行索引应为非负整数" }), (!Array.isArray(e.columnKeys) || e.columnKeys.some((i) => typeof i != "string")) && r.push({ path: `${o}.columnKeys`, message: "逻辑列字段应为字符串数组" }), e.layout !== void 0 && e.layout !== "page" && e.layout !== "wide" && r.push({ path: `${o}.layout`, message: "布局应为 page 或 wide" }), e.title !== void 0 && typeof e.title != "string" && r.push({ path: `${o}.title`, message: "逻辑表名称应为字符串" });
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
|
-
function
|
|
91
|
+
function ie(e, t, r, o) {
|
|
81
92
|
if (e !== void 0)
|
|
82
93
|
if (!A(e) || !Array.isArray(e.cells))
|
|
83
|
-
|
|
94
|
+
r.push({ path: `${t}.grid.cells`, message: "grid.cells 应为二维数组" });
|
|
84
95
|
else {
|
|
85
|
-
const
|
|
86
|
-
|
|
96
|
+
const n = e.paddingMm;
|
|
97
|
+
n !== void 0 && (typeof n != "number" || !Number.isFinite(n) || n < 0) && r.push({ path: `${t}.grid.paddingMm`, message: "单元格内距应为有限非负数" }), e.cells.forEach((s, i) => {
|
|
87
98
|
if (!Array.isArray(s)) {
|
|
88
|
-
|
|
99
|
+
r.push({ path: `${t}.grid.cells.${i}`, message: "行应为数组" });
|
|
89
100
|
return;
|
|
90
101
|
}
|
|
91
102
|
s.forEach((d, y) => {
|
|
92
103
|
if (d == null) return;
|
|
93
104
|
const u = `${t}.grid.cells.${i}.${y}`;
|
|
94
105
|
if (!A(d)) {
|
|
95
|
-
|
|
106
|
+
r.push({ path: u, message: "网格单元格应为对象或 null" });
|
|
96
107
|
return;
|
|
97
108
|
}
|
|
98
|
-
|
|
99
|
-
|
|
109
|
+
Y(d, u, r), Array.isArray(d.children) && d.children.forEach((b, k) => {
|
|
110
|
+
U(b, `${t}.grid.cells.${i}.${y}.children.${k}`, r, o);
|
|
100
111
|
});
|
|
101
112
|
});
|
|
102
113
|
});
|
|
103
114
|
}
|
|
104
115
|
}
|
|
105
|
-
function
|
|
106
|
-
e !== void 0 && (Array.isArray(e) ? e.forEach((o,
|
|
107
|
-
(!A(o) || !Array.isArray(o.segments)) &&
|
|
108
|
-
}) :
|
|
116
|
+
function ae(e, t, r) {
|
|
117
|
+
e !== void 0 && (Array.isArray(e) ? e.forEach((o, n) => {
|
|
118
|
+
(!A(o) || !Array.isArray(o.segments)) && r.push({ path: `${t}.richParagraphs.${n}`, message: "段落缺少 segments 数组" });
|
|
119
|
+
}) : r.push({ path: `${t}.richParagraphs`, message: "richParagraphs 应为数组" }));
|
|
109
120
|
}
|
|
110
|
-
function
|
|
121
|
+
function U(e, t, r, o = []) {
|
|
111
122
|
if (!A(e)) {
|
|
112
|
-
|
|
123
|
+
r.push({ path: t, message: "组件应为对象" });
|
|
113
124
|
return;
|
|
114
125
|
}
|
|
115
|
-
const
|
|
116
|
-
typeof
|
|
126
|
+
const n = e.kind;
|
|
127
|
+
typeof n != "string" ? r.push({ path: `${t}.kind`, message: "组件缺少 kind 字符串" }) : ne.has(n) || o.push({
|
|
117
128
|
path: `${t}.kind`,
|
|
118
|
-
message: `未知组件类型 ${JSON.stringify(
|
|
129
|
+
message: `未知组件类型 ${JSON.stringify(n)},将以兜底方式渲染`
|
|
119
130
|
});
|
|
120
131
|
for (const s of ["leftMm", "topMm", "widthMm", "heightMm"])
|
|
121
|
-
|
|
122
|
-
typeof e.leftMm == "number" && e.leftMm < -100 &&
|
|
132
|
+
oe(e, s, t, r);
|
|
133
|
+
typeof e.leftMm == "number" && e.leftMm < -100 && r.push({ path: `${t}.leftMm`, message: "几何数值异常(leftMm<-100)" });
|
|
123
134
|
for (const s of ["widthMm", "heightMm"])
|
|
124
|
-
typeof e[s] == "number" && e[s] < 0 &&
|
|
125
|
-
|
|
135
|
+
typeof e[s] == "number" && e[s] < 0 && r.push({ path: `${t}.${s}`, message: "组件尺寸不能为负数" });
|
|
136
|
+
se(e.table, t, r), ce(e.code, n, t, r), e.pageAnchor !== void 0 && !["header", "footer"].includes(e.pageAnchor) && r.push({ path: `${t}.pageAnchor`, message: "页面锚点应为 header 或 footer" }), e.lineDirection !== void 0 && !["down", "up"].includes(e.lineDirection) && r.push({ path: `${t}.lineDirection`, message: "线段方向应为 down 或 up" }), ie(e.grid, t, r, o), ae(e.richParagraphs, t, r);
|
|
126
137
|
}
|
|
127
|
-
function
|
|
138
|
+
function ce(e, t, r, o) {
|
|
128
139
|
if (e !== void 0)
|
|
129
|
-
for (const
|
|
140
|
+
for (const n of re(e, t)) o.push({ path: `${r}.code${n.path ? `.${n.path}` : ""}`, message: n.message });
|
|
130
141
|
}
|
|
131
|
-
function
|
|
142
|
+
function C(e, t, r) {
|
|
132
143
|
if (!A(e)) return;
|
|
133
|
-
e.binding !== void 0 &&
|
|
144
|
+
e.binding !== void 0 && r.push({ path: `${t}.binding`, message: "渲染计划不允许未解析字段绑定" });
|
|
134
145
|
const o = e.grid;
|
|
135
|
-
!A(o) || !Array.isArray(o.cells) || o.cells.forEach((
|
|
136
|
-
Array.isArray(
|
|
137
|
-
!A(i) || !Array.isArray(i.children) || i.children.forEach((y, u) =>
|
|
146
|
+
!A(o) || !Array.isArray(o.cells) || o.cells.forEach((n, s) => {
|
|
147
|
+
Array.isArray(n) && n.forEach((i, d) => {
|
|
148
|
+
!A(i) || !Array.isArray(i.children) || i.children.forEach((y, u) => C(y, `${t}.grid.cells.${s}.${d}.children.${u}`, r));
|
|
138
149
|
});
|
|
139
150
|
});
|
|
140
151
|
}
|
|
141
|
-
function
|
|
152
|
+
function fe(e, t, r, o = []) {
|
|
142
153
|
if (!A(e)) {
|
|
143
|
-
|
|
154
|
+
r.push({ path: t, message: "页应为对象" });
|
|
144
155
|
return;
|
|
145
156
|
}
|
|
146
|
-
const
|
|
147
|
-
(typeof
|
|
157
|
+
const n = e.pageWidthMm, s = e.pageHeightMm;
|
|
158
|
+
(typeof n != "number" || !Number.isFinite(n) || n <= 0) && r.push({ path: `${t}.pageWidthMm`, message: `页宽非法: ${JSON.stringify(n)}` }), (typeof s != "number" || !(s > 0 && s < 5e3)) && r.push({ path: `${t}.pageHeightMm`, message: `页高非法: ${JSON.stringify(s)}` }), e.layout !== void 0 && e.layout !== "page" && e.layout !== "wide" && r.push({ path: `${t}.layout`, message: "布局应为 page 或 wide" });
|
|
148
159
|
const i = e.components;
|
|
149
160
|
Array.isArray(i) ? Array.isArray(i) && i.forEach((d, y) => {
|
|
150
|
-
|
|
151
|
-
}) :
|
|
161
|
+
U(d, `${t}.components.${y}`, r, o), C(d, `${t}.components.${y}`, r);
|
|
162
|
+
}) : r.push({ path: `${t}.components`, message: "components 应为数组" });
|
|
152
163
|
}
|
|
153
|
-
function
|
|
154
|
-
const t = [],
|
|
164
|
+
function ue(e) {
|
|
165
|
+
const t = [], r = [], o = A(e) ? e.pages : void 0;
|
|
155
166
|
if (A(e) && e.requiresRecalculation !== void 0 && typeof e.requiresRecalculation != "boolean" && t.push({ path: "$.requiresRecalculation", message: "重算能力要求应为布尔值" }), !Array.isArray(o))
|
|
156
167
|
t.push({
|
|
157
168
|
path: "$.pages",
|
|
158
169
|
message: e == null ? "渲染计划为空" : "渲染计划缺少 pages 数组"
|
|
159
170
|
});
|
|
160
171
|
else {
|
|
161
|
-
o.forEach((s, i) =>
|
|
172
|
+
o.forEach((s, i) => fe(s, `$.pages.${i}`, t, r)), o.length > 2e3 && r.push({
|
|
162
173
|
path: "$.pages",
|
|
163
174
|
message: `页数异常大(${o.length} 页),渲染与打印耗时可能显著增加`
|
|
164
175
|
});
|
|
165
|
-
const
|
|
176
|
+
const n = o.reduce(
|
|
166
177
|
(s, i) => s + (A(i) && Array.isArray(i.components) ? i.components.length : 0),
|
|
167
178
|
0
|
|
168
179
|
);
|
|
169
|
-
|
|
180
|
+
n > 5e4 && r.push({
|
|
170
181
|
path: "$.pages",
|
|
171
|
-
message: `组件总数异常大(${
|
|
182
|
+
message: `组件总数异常大(${n} 个),可能触发浏览器性能限制`
|
|
172
183
|
});
|
|
173
184
|
}
|
|
174
|
-
return { ok: t.length === 0, errors: t, warnings:
|
|
185
|
+
return { ok: t.length === 0, errors: t, warnings: r };
|
|
175
186
|
}
|
|
176
187
|
const M = "mach-report-worker/1";
|
|
177
188
|
class B extends Error {
|
|
@@ -182,38 +193,41 @@ class B extends Error {
|
|
|
182
193
|
function R(e) {
|
|
183
194
|
return !!e && typeof e == "object" && !Array.isArray(e);
|
|
184
195
|
}
|
|
185
|
-
function
|
|
196
|
+
function pe(e) {
|
|
186
197
|
return R(e) ? ["rows", "pages", "cells"].every((t) => typeof e[t] == "number" && Number.isSafeInteger(e[t]) && e[t] >= 0) && typeof e.durationMs == "number" && Number.isFinite(e.durationMs) && e.durationMs >= 0 : !1;
|
|
187
198
|
}
|
|
188
|
-
function
|
|
189
|
-
return Array.isArray(e) && e.every((t) => R(t) && typeof t.code == "string" && typeof t.message == "string" && ["info", "warning", "error"].includes(t.severity));
|
|
199
|
+
function de(e) {
|
|
200
|
+
return Array.isArray(e) && e.every((t) => R(t) && typeof t.code == "string" && typeof t.message == "string" && ["info", "warning", "error"].includes(t.severity) && G(t));
|
|
190
201
|
}
|
|
191
|
-
function
|
|
202
|
+
function me(e) {
|
|
192
203
|
return R(e) && Object.values(e).every((t) => R(t) && (t.revision === void 0 || typeof t.revision == "string") && (t.sourceToken === void 0 || typeof t.sourceToken == "string"));
|
|
193
204
|
}
|
|
194
|
-
function
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
205
|
+
function ye(e) {
|
|
206
|
+
return e === void 0 ? !0 : R(e) && ["heuristic", "provided", "font-bytes"].includes(e.textMetrics) && (e.fontFingerprint === void 0 || typeof e.fontFingerprint == "string" && /^[a-f0-9]{64}$/.test(e.fontFingerprint));
|
|
207
|
+
}
|
|
208
|
+
function le(e, t) {
|
|
209
|
+
if (!R(e) || !pe(e.stats) || !de(e.diagnostics) || !me(e.revisions) || !ye(e.layout)) return !1;
|
|
210
|
+
if (t === "prepare") return ue(e.plan).ok;
|
|
211
|
+
const r = e.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
212
|
+
return e.bytes instanceof Uint8Array && (e.format === "pdf" || e.format === "xlsx") && e.contentType === r;
|
|
199
213
|
}
|
|
200
214
|
function D(e) {
|
|
201
215
|
if (!e || typeof e != "object") return { message: String(e) };
|
|
202
216
|
const t = {};
|
|
203
|
-
for (const
|
|
204
|
-
const o = e[
|
|
205
|
-
typeof o == "string" && (t[
|
|
217
|
+
for (const r of ["code", "path", "field", "message"]) {
|
|
218
|
+
const o = e[r];
|
|
219
|
+
typeof o == "string" && (t[r] = o);
|
|
206
220
|
}
|
|
207
221
|
return t;
|
|
208
222
|
}
|
|
209
|
-
function
|
|
223
|
+
function he(e) {
|
|
210
224
|
const t = D(e);
|
|
211
225
|
if (!R(e)) return t;
|
|
212
|
-
for (const
|
|
213
|
-
for (const
|
|
214
|
-
return Array.isArray(e.componentPath) && e.componentPath.every((
|
|
226
|
+
for (const r of ["format", "severity", "kind", "nid"]) typeof e[r] == "string" && (t[r] = e[r]);
|
|
227
|
+
for (const r of ["pageIndex", "componentIndex"]) Number.isSafeInteger(e[r]) && e[r] >= 0 && (t[r] = e[r]);
|
|
228
|
+
return Array.isArray(e.componentPath) && e.componentPath.every((r) => Number.isSafeInteger(r) && r >= 0) && (t.componentPath = e.componentPath), t;
|
|
215
229
|
}
|
|
216
|
-
function
|
|
230
|
+
function ge(e) {
|
|
217
231
|
if (!(e instanceof Error)) return { name: "Error", message: String(e) };
|
|
218
232
|
const t = e;
|
|
219
233
|
return {
|
|
@@ -222,45 +236,45 @@ function me(e) {
|
|
|
222
236
|
...typeof t.code == "string" ? { code: t.code } : {},
|
|
223
237
|
...typeof t.path == "string" ? { path: t.path } : {},
|
|
224
238
|
...Array.isArray(t.issues) ? { issues: t.issues.map(D) } : {},
|
|
225
|
-
...Array.isArray(t.diagnostics) ? { diagnostics: t.diagnostics.map(
|
|
239
|
+
...Array.isArray(t.diagnostics) ? { diagnostics: t.diagnostics.map(he) } : {}
|
|
226
240
|
};
|
|
227
241
|
}
|
|
228
|
-
function
|
|
242
|
+
function we(e) {
|
|
229
243
|
if (!e || typeof e != "object") return !1;
|
|
230
244
|
const t = e;
|
|
231
|
-
return t.protocol === M && typeof t.id == "string" && (t.operation === "prepare" || t.operation === "export") && !!t.input && typeof t.input == "object";
|
|
245
|
+
return t.protocol === M && typeof t.id == "string" && (t.operation === "prepare" || t.operation === "export" || t.operation === "exportPrepared") && !!t.input && typeof t.input == "object";
|
|
232
246
|
}
|
|
233
|
-
async function
|
|
247
|
+
async function be(e, t, r) {
|
|
234
248
|
try {
|
|
235
|
-
const o = t.operation === "prepare" ? await e.prepare({ ...t.input, onEvent:
|
|
249
|
+
const o = t.operation === "prepare" ? await e.prepare({ ...t.input, onEvent: r }) : t.operation === "exportPrepared" ? await e.exportPrepared({ ...t.input, onEvent: r }) : await e.export({ ...t.input, onEvent: r });
|
|
236
250
|
return { protocol: M, id: t.id, result: o };
|
|
237
251
|
} catch (o) {
|
|
238
|
-
return { protocol: M, id: t.id, error:
|
|
252
|
+
return { protocol: M, id: t.id, error: ge(o) };
|
|
239
253
|
}
|
|
240
254
|
}
|
|
241
|
-
function
|
|
255
|
+
function Ae(e) {
|
|
242
256
|
const t = e.result;
|
|
243
257
|
return !t || !("bytes" in t) || !(t.bytes.buffer instanceof ArrayBuffer) ? [] : [t.bytes.buffer];
|
|
244
258
|
}
|
|
245
|
-
function
|
|
246
|
-
if (!R(e) || typeof e.taskId != "string" || !e.taskId || t.taskId !== void 0 && e.taskId !== t.taskId || e.correlationId !== t.correlationId || e.reportId !== void 0 && (typeof e.reportId != "string" || !t.reportIds.includes(e.reportId)) || !["query", "validate", "layout", "assets", "encode"].includes(e.stage) || !["started", "completed", "failed"].includes(e.status)) return !1;
|
|
247
|
-
for (const
|
|
259
|
+
function xe(e, t) {
|
|
260
|
+
if (!R(e) || typeof e.taskId != "string" || !e.taskId || t.taskId !== void 0 && e.taskId !== t.taskId || e.correlationId !== t.correlationId || e.reportId !== void 0 && (typeof e.reportId != "string" || !("reportIds" in t && t.reportIds.includes(e.reportId))) || !["query", "validate", "layout", "assets", "encode"].includes(e.stage) || !["started", "completed", "failed"].includes(e.status)) return !1;
|
|
261
|
+
for (const r of ["completed", "total"]) if (e[r] !== void 0 && (typeof e[r] != "number" || !Number.isFinite(e[r]) || e[r] < 0)) return !1;
|
|
248
262
|
return e.completed === void 0 || e.total === void 0 || e.completed <= e.total;
|
|
249
263
|
}
|
|
250
|
-
let
|
|
264
|
+
let $e = 0;
|
|
251
265
|
function J(e) {
|
|
252
266
|
const t = new Error("报表 Worker 任务已取消");
|
|
253
267
|
return t.name = "AbortError", Object.defineProperty(t, "cause", { value: e }), t;
|
|
254
268
|
}
|
|
255
|
-
function
|
|
269
|
+
function ke(e, t) {
|
|
256
270
|
if (!e || typeof e != "object") return;
|
|
257
|
-
const
|
|
258
|
-
return
|
|
271
|
+
const r = e;
|
|
272
|
+
return r.protocol === M && r.id === t ? r : void 0;
|
|
259
273
|
}
|
|
260
|
-
function
|
|
261
|
-
const
|
|
262
|
-
if (!Number.isFinite(
|
|
263
|
-
const o = (
|
|
274
|
+
function Ne(e, t = {}) {
|
|
275
|
+
const r = t.timeoutMs ?? 12e4;
|
|
276
|
+
if (!Number.isFinite(r) || r <= 0 || r > 2147483647) throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");
|
|
277
|
+
const o = (n, s, i, d) => i?.aborted ? Promise.reject(J(i.reason)) : new Promise((y, u) => {
|
|
264
278
|
let b;
|
|
265
279
|
try {
|
|
266
280
|
b = e();
|
|
@@ -268,7 +282,7 @@ function Ae(e, t = {}) {
|
|
|
268
282
|
u(l);
|
|
269
283
|
return;
|
|
270
284
|
}
|
|
271
|
-
const k = `mach-report-${Date.now()}-${
|
|
285
|
+
const k = `mach-report-${Date.now()}-${++$e}`;
|
|
272
286
|
let p = !1, f = () => {
|
|
273
287
|
}, c;
|
|
274
288
|
const m = (l, w) => {
|
|
@@ -277,14 +291,14 @@ function Ae(e, t = {}) {
|
|
|
277
291
|
(N) => u(l ?? N)
|
|
278
292
|
));
|
|
279
293
|
}, g = () => m(J(i?.reason)), x = (l) => {
|
|
280
|
-
const w =
|
|
294
|
+
const w = ke(l, k);
|
|
281
295
|
if (!(!w || p)) {
|
|
282
296
|
if ("type" in w && w.type === "event") {
|
|
283
297
|
const N = "event" in w ? w.event : void 0;
|
|
284
|
-
|
|
298
|
+
xe(N, s) ? Z(d, N, i) : m(new Error("报表 Worker 返回无效阶段事件"));
|
|
285
299
|
return;
|
|
286
300
|
}
|
|
287
|
-
w.error && typeof w.error.name == "string" && typeof w.error.message == "string" ? m(new B(w.error)) :
|
|
301
|
+
w.error && typeof w.error.name == "string" && typeof w.error.message == "string" ? m(new B(w.error)) : le(w.result, n) && (n === "prepare" || "format" in w.result && "format" in s && w.result.format === s.format) ? m(void 0, w.result) : m(new Error("报表 Worker 返回无效响应"));
|
|
288
302
|
}
|
|
289
303
|
};
|
|
290
304
|
try {
|
|
@@ -292,18 +306,18 @@ function Ae(e, t = {}) {
|
|
|
292
306
|
f();
|
|
293
307
|
return;
|
|
294
308
|
}
|
|
295
|
-
if (i?.addEventListener("abort", g, { once: !0 }), c = setTimeout(() => m(new B({ name: "ReportRuntimeError", code: "timeout", message: `报表 Worker 执行超过 ${
|
|
309
|
+
if (i?.addEventListener("abort", g, { once: !0 }), c = setTimeout(() => m(new B({ name: "ReportRuntimeError", code: "timeout", message: `报表 Worker 执行超过 ${r}ms` })), r), i?.aborted) g();
|
|
296
310
|
else {
|
|
297
311
|
const { onEvent: l, signal: w, ...N } = s;
|
|
298
|
-
b.postMessage({ protocol: M, id: k, operation:
|
|
312
|
+
b.postMessage({ protocol: M, id: k, operation: n, input: N });
|
|
299
313
|
}
|
|
300
314
|
} catch (l) {
|
|
301
315
|
m(l);
|
|
302
316
|
}
|
|
303
317
|
});
|
|
304
|
-
return { prepare: (
|
|
318
|
+
return { exportPrepared: (n, s, i) => o("exportPrepared", n, s, i), prepare: (n, s, i) => o("prepare", n, s, i), export: (n, s, i) => o("export", n, s, i) };
|
|
305
319
|
}
|
|
306
|
-
const
|
|
320
|
+
const Se = new Uint32Array([
|
|
307
321
|
1116352408,
|
|
308
322
|
1899447441,
|
|
309
323
|
3049323471,
|
|
@@ -369,75 +383,75 @@ const xe = new Uint32Array([
|
|
|
369
383
|
3204031479,
|
|
370
384
|
3329325298
|
|
371
385
|
]), $ = (e, t) => e >>> t | e << 32 - t;
|
|
372
|
-
function
|
|
386
|
+
function ve(e, t, r) {
|
|
373
387
|
const o = new DataView(e.buffer, e.byteOffset + t, 64);
|
|
374
|
-
for (let
|
|
375
|
-
for (let
|
|
376
|
-
const s = n
|
|
377
|
-
n
|
|
388
|
+
for (let n = 0; n < 16; n++) r[n] = o.getUint32(n * 4);
|
|
389
|
+
for (let n = 16; n < 64; n++) {
|
|
390
|
+
const s = r[n - 15], i = r[n - 2], d = $(s, 7) ^ $(s, 18) ^ s >>> 3, y = $(i, 17) ^ $(i, 19) ^ i >>> 10;
|
|
391
|
+
r[n] = r[n - 16] + d + r[n - 7] + y;
|
|
378
392
|
}
|
|
379
393
|
}
|
|
380
|
-
function
|
|
381
|
-
let
|
|
394
|
+
function Re(e, t) {
|
|
395
|
+
let r = e[0], o = e[1], n = e[2], s = e[3], i = e[4], d = e[5], y = e[6], u = e[7];
|
|
382
396
|
for (let b = 0; b < 64; b++) {
|
|
383
|
-
const k = $(i, 6) ^ $(i, 11) ^ $(i, 25), p = i & d ^ ~i & y, f = u + k + p +
|
|
384
|
-
u = y, y = d, d = i, i = s + f >>> 0, s =
|
|
397
|
+
const k = $(i, 6) ^ $(i, 11) ^ $(i, 25), p = i & d ^ ~i & y, f = u + k + p + Se[b] + t[b] >>> 0, c = $(r, 2) ^ $(r, 13) ^ $(r, 22), m = r & o ^ r & n ^ o & n, g = c + m >>> 0;
|
|
398
|
+
u = y, y = d, d = i, i = s + f >>> 0, s = n, n = o, o = r, r = f + g >>> 0;
|
|
385
399
|
}
|
|
386
|
-
e[0] = e[0] +
|
|
400
|
+
e[0] = e[0] + r, e[1] = e[1] + o, e[2] = e[2] + n, e[3] = e[3] + s, e[4] = e[4] + i, e[5] = e[5] + d, e[6] = e[6] + y, e[7] = e[7] + u;
|
|
387
401
|
}
|
|
388
|
-
function
|
|
402
|
+
function Me(e) {
|
|
389
403
|
const t = new Uint8Array(Math.ceil((e.byteLength + 9) / 64) * 64);
|
|
390
404
|
t.set(e), t[e.byteLength] = 128;
|
|
391
|
-
const
|
|
392
|
-
return
|
|
405
|
+
const r = new DataView(t.buffer);
|
|
406
|
+
return r.setUint32(t.length - 8, Math.floor(e.byteLength / 536870912)), r.setUint32(t.length - 4, e.byteLength * 8 >>> 0), t;
|
|
393
407
|
}
|
|
394
|
-
const
|
|
395
|
-
async function
|
|
396
|
-
const t =
|
|
397
|
-
for (let
|
|
398
|
-
|
|
399
|
-
return
|
|
408
|
+
const Ee = () => new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]), Ie = (e) => Array.from(e, (t) => t.toString(16).padStart(8, "0")).join("");
|
|
409
|
+
async function Oe(e) {
|
|
410
|
+
const t = Me(e), r = Ee(), o = new Uint32Array(64);
|
|
411
|
+
for (let n = 0; n < t.length; n += 64)
|
|
412
|
+
n > 0 && n % 262144 === 0 && await new Promise((s) => setTimeout(s, 0)), ve(t, n, o), Re(r, o);
|
|
413
|
+
return Ie(r);
|
|
400
414
|
}
|
|
401
415
|
class a extends Error {
|
|
402
|
-
constructor(t,
|
|
403
|
-
super(
|
|
416
|
+
constructor(t, r) {
|
|
417
|
+
super(r), this.code = t, this.name = "ReportJobError";
|
|
404
418
|
}
|
|
405
419
|
}
|
|
406
420
|
function T(e, t) {
|
|
407
421
|
if (typeof e != "string" || !e.trim() || e.length > 256 || typeof t != "string" || t !== t.trim() || !/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(t)) throw new a("input", "任务范围应非空,ID应为1–128位安全标识");
|
|
408
422
|
}
|
|
409
|
-
function
|
|
410
|
-
const t = Array.isArray(e),
|
|
411
|
-
if (
|
|
423
|
+
function Te(e) {
|
|
424
|
+
const t = Array.isArray(e), r = Object.getPrototypeOf(e), o = Object.keys(e);
|
|
425
|
+
if (r !== (t ? Array.prototype : Object.prototype) && !(r === null && !t)) throw new a("input", "任务对象应为普通 JSON 对象");
|
|
412
426
|
if (Object.getOwnPropertySymbols(e).length) throw new a("input", "任务不能包含Symbol");
|
|
413
427
|
if (Object.getOwnPropertyNames(e).filter((s) => !(t && s === "length")).length !== o.length) throw new a("input", "任务不能包含不可枚举属性");
|
|
414
428
|
if (t && (o.length !== e.length || o.some((s) => s !== String(Number(s)) || !Number.isSafeInteger(Number(s)) || Number(s) < 0 || Number(s) >= e.length))) throw new a("input", "任务数组不能稀疏或包含额外属性");
|
|
415
429
|
return o.sort();
|
|
416
430
|
}
|
|
417
|
-
function
|
|
418
|
-
const
|
|
419
|
-
if (["__proto__", "prototype", "constructor"].includes(t) ||
|
|
420
|
-
return
|
|
431
|
+
function je(e, t) {
|
|
432
|
+
const r = Object.getOwnPropertyDescriptor(e, t);
|
|
433
|
+
if (["__proto__", "prototype", "constructor"].includes(t) || r.get || r.set) throw new a("input", "任务不能包含危险键或访问器");
|
|
434
|
+
return r.value;
|
|
421
435
|
}
|
|
422
|
-
function
|
|
423
|
-
const
|
|
424
|
-
if (!Number.isSafeInteger(
|
|
425
|
-
let
|
|
436
|
+
function S(e, t = {}) {
|
|
437
|
+
const r = t.maxNodes ?? 2e4, o = t.maxCharacters ?? 1e6;
|
|
438
|
+
if (!Number.isSafeInteger(r) || r < 1 || r > 2e4 || !Number.isSafeInteger(o) || o < 1 || o > 1e6) throw new a("input", "任务JSON预算无效");
|
|
439
|
+
let n = 0, s = 0;
|
|
426
440
|
const i = /* @__PURE__ */ new Set();
|
|
427
441
|
function d(u, b) {
|
|
428
|
-
if (++
|
|
442
|
+
if (++n > r || b > 32) throw new a("input", "任务数据超过节点或深度预算");
|
|
429
443
|
if (typeof u == "string") {
|
|
430
444
|
if (s += u.length, s > o) throw new a("input", "任务文本超过预算");
|
|
431
445
|
return u;
|
|
432
446
|
}
|
|
433
447
|
if (u === null || typeof u == "boolean" || typeof u == "number" && Number.isFinite(u)) return u;
|
|
434
448
|
if (!u || typeof u != "object" || i.has(u)) throw new a("input", "任务只允许无循环的有限 JSON 值");
|
|
435
|
-
const k = Array.isArray(u), p =
|
|
449
|
+
const k = Array.isArray(u), p = Te(u);
|
|
436
450
|
i.add(u);
|
|
437
451
|
const f = /* @__PURE__ */ Object.create(null);
|
|
438
452
|
for (const c of p) {
|
|
439
453
|
if (s += c.length, s > o) throw new a("input", "任务文本超过预算");
|
|
440
|
-
f[c] = d(
|
|
454
|
+
f[c] = d(je(u, c), b + 1);
|
|
441
455
|
}
|
|
442
456
|
return i.delete(u), k ? Array.from({ length: u.length }, (c, m) => f[String(m)]) : f;
|
|
443
457
|
}
|
|
@@ -448,20 +462,20 @@ function v(e, t = {}) {
|
|
|
448
462
|
function j(e) {
|
|
449
463
|
return JSON.parse(JSON.stringify(e));
|
|
450
464
|
}
|
|
451
|
-
function
|
|
452
|
-
if (T(t,
|
|
453
|
-
if (![e.createdAt, e.updatedAt, e.attempt].every((
|
|
465
|
+
function K(e, t, r, o) {
|
|
466
|
+
if (T(t, r), e.scope !== t || e.id !== r || e.revision !== (o ?? 0) + 1 || !Number.isSafeInteger(e.revision)) throw new a("input", "任务身份或修订不匹配");
|
|
467
|
+
if (![e.createdAt, e.updatedAt, e.attempt].every((n) => Number.isSafeInteger(n) && n >= 0) || !["queued", "running", "completed", "failed", "cancelled"].includes(e.status)) throw new a("input", "任务状态无效");
|
|
454
468
|
if (e.lease && (!e.lease.owner || !Number.isSafeInteger(e.lease.expiresAt))) throw new a("input", "任务租约无效");
|
|
455
469
|
if (!e.request || typeof e.request.kind != "string" || !e.request.kind.trim() || e.request.kind.length > 128) throw new a("input", "任务类型无效");
|
|
456
|
-
|
|
470
|
+
S(e.request.payload, { maxNodes: 19e3, maxCharacters: 75e4 }), S(e);
|
|
457
471
|
}
|
|
458
|
-
function
|
|
459
|
-
if (e && (e.createdAt !== t.createdAt ||
|
|
472
|
+
function qe(e, t) {
|
|
473
|
+
if (e && (e.createdAt !== t.createdAt || S(e.request) !== S(t.request))) throw new a("input", "任务创建时间与请求不可变更,请使用新任务ID");
|
|
460
474
|
}
|
|
461
|
-
function
|
|
475
|
+
function Be(e, t) {
|
|
462
476
|
return e.status === "queued" || e.status === "running" && (e.lease?.expiresAt ?? 0) <= t;
|
|
463
477
|
}
|
|
464
|
-
function
|
|
478
|
+
function Je(e = {}) {
|
|
465
479
|
const t = {
|
|
466
480
|
maxRecords: e.maxRecords ?? 1e4,
|
|
467
481
|
maxBytes: e.maxBytes ?? 67108864,
|
|
@@ -470,145 +484,145 @@ function Te(e = {}) {
|
|
|
470
484
|
maxTombstones: e.maxTombstones ?? 1e4,
|
|
471
485
|
maxTombstoneBytes: e.maxTombstoneBytes ?? 16777216
|
|
472
486
|
};
|
|
473
|
-
if (!Object.values(t).every((
|
|
487
|
+
if (!Object.values(t).every((r) => Number.isSafeInteger(r) && r > 0) || t.controlReserveBytes < 4096) throw new a("input", "任务容量应为正整数,控制状态预留至少4096字节");
|
|
474
488
|
return t;
|
|
475
489
|
}
|
|
476
490
|
function E(e) {
|
|
477
|
-
return new TextEncoder().encode(
|
|
491
|
+
return new TextEncoder().encode(S(e)).byteLength;
|
|
478
492
|
}
|
|
479
|
-
function
|
|
480
|
-
const
|
|
493
|
+
function L(e, t) {
|
|
494
|
+
const r = { scope: e.scope, id: e.id, revision: 1, request: e.request, status: "queued", createdAt: e.createdAt, updatedAt: e.createdAt, attempt: 0 }, o = { ...e };
|
|
481
495
|
delete o.result;
|
|
482
|
-
const
|
|
483
|
-
if (
|
|
484
|
-
return Math.max(E(
|
|
496
|
+
const n = e.result === void 0 ? 0 : E(e.result);
|
|
497
|
+
if (n > t.maxResultBytes) throw new a("capacity", "任务结果超过独立预算,请保存文件引用");
|
|
498
|
+
return Math.max(E(r) + t.controlReserveBytes, E(o)) + n;
|
|
485
499
|
}
|
|
486
|
-
function
|
|
500
|
+
function z(e) {
|
|
487
501
|
return e.status !== "queued" && e.status !== "running";
|
|
488
502
|
}
|
|
489
|
-
function
|
|
503
|
+
function Pe(e) {
|
|
490
504
|
const t = { ...e, tombstoneRetentionMs: e.tombstoneRetentionMs ?? 6048e5, limit: e.limit ?? 100 };
|
|
491
|
-
if (![t.now, t.terminalBefore].every((
|
|
492
|
-
if (![t.tombstoneRetentionMs, t.limit].every((
|
|
505
|
+
if (![t.now, t.terminalBefore].every((r) => Number.isSafeInteger(r) && r >= 0) || t.terminalBefore > t.now) throw new a("input", "终态清理时间应为不超过当前时间的非负整数");
|
|
506
|
+
if (![t.tombstoneRetentionMs, t.limit].every((r) => Number.isSafeInteger(r) && r > 0) || !Number.isSafeInteger(t.now + t.tombstoneRetentionMs)) throw new a("input", "幂等保留期与清理批量应为正整数");
|
|
493
507
|
return t;
|
|
494
508
|
}
|
|
495
|
-
async function
|
|
496
|
-
const t = new TextEncoder().encode(
|
|
497
|
-
if (!
|
|
498
|
-
const o = await
|
|
499
|
-
return Array.from(new Uint8Array(o), (
|
|
509
|
+
async function We(e) {
|
|
510
|
+
const t = new TextEncoder().encode(S(e)), r = globalThis.crypto?.subtle;
|
|
511
|
+
if (!r) return Oe(t);
|
|
512
|
+
const o = await r.digest("SHA-256", t);
|
|
513
|
+
return Array.from(new Uint8Array(o), (n) => n.toString(16).padStart(2, "0")).join("");
|
|
500
514
|
}
|
|
501
|
-
async function
|
|
502
|
-
if (!
|
|
503
|
-
return { scope: e.scope, id: e.id, revision: e.revision, status: e.status, createdAt: e.createdAt, updatedAt: e.updatedAt, attempt: e.attempt, requestHash: await
|
|
515
|
+
async function Fe(e, t) {
|
|
516
|
+
if (!z(e)) throw new a("input", "只能归档终态任务");
|
|
517
|
+
return { scope: e.scope, id: e.id, revision: e.revision, status: e.status, createdAt: e.createdAt, updatedAt: e.updatedAt, attempt: e.attempt, requestHash: await We(e.request), expiresAt: t };
|
|
504
518
|
}
|
|
505
|
-
function
|
|
519
|
+
function Ue(e) {
|
|
506
520
|
if (!e || !["completed", "failed", "cancelled"].includes(e.status) || !/^[a-f0-9]{64}$/.test(e.requestHash)) throw new a("input", "任务幂等摘要无效");
|
|
507
521
|
if (![e.revision, e.createdAt, e.updatedAt, e.attempt, e.expiresAt].every((t) => Number.isSafeInteger(t) && t >= 0) || e.revision < 1) throw new a("input", "任务幂等摘要时间或修订无效");
|
|
508
522
|
}
|
|
509
|
-
function
|
|
523
|
+
function O(e) {
|
|
510
524
|
return e?.code;
|
|
511
525
|
}
|
|
512
|
-
function
|
|
526
|
+
function I(e, t) {
|
|
513
527
|
return W("sha256").update(JSON.stringify([e, t])).digest("hex") + ".json";
|
|
514
528
|
}
|
|
515
529
|
async function q(e) {
|
|
516
530
|
try {
|
|
517
531
|
return await h.readFile(e, "utf8");
|
|
518
532
|
} catch (t) {
|
|
519
|
-
if (
|
|
533
|
+
if (O(t) === "ENOENT") return;
|
|
520
534
|
throw t;
|
|
521
535
|
}
|
|
522
536
|
}
|
|
523
|
-
async function
|
|
524
|
-
const
|
|
525
|
-
if (
|
|
537
|
+
async function Ce(e, t) {
|
|
538
|
+
const r = await q(e);
|
|
539
|
+
if (r === void 0) return;
|
|
526
540
|
let o;
|
|
527
541
|
try {
|
|
528
|
-
o = JSON.parse(
|
|
542
|
+
o = JSON.parse(r);
|
|
529
543
|
} catch {
|
|
530
544
|
throw new a("conflict", "任务锁尚未完整写入或已损坏,拒绝自动移除");
|
|
531
545
|
}
|
|
532
546
|
if (!o || !Number.isSafeInteger(o.pid) || o.pid < 1) throw new a("conflict", "任务锁身份无效,拒绝自动移除");
|
|
533
547
|
try {
|
|
534
548
|
process.kill(o.pid, 0);
|
|
535
|
-
} catch (
|
|
536
|
-
if (
|
|
549
|
+
} catch (n) {
|
|
550
|
+
if (O(n) === "ESRCH") {
|
|
537
551
|
await h.unlink(e);
|
|
538
552
|
return;
|
|
539
553
|
}
|
|
540
|
-
throw
|
|
554
|
+
throw n;
|
|
541
555
|
}
|
|
542
556
|
throw new a("conflict", "任务目录的写入进程仍在运行");
|
|
543
557
|
}
|
|
544
|
-
async function
|
|
558
|
+
async function De(e, t) {
|
|
545
559
|
if (!t) throw new a("conflict", "任务目录已有写入进程;多实例请使用数据库CAS适配器");
|
|
546
|
-
const
|
|
560
|
+
const r = e + ".recovery";
|
|
547
561
|
let o;
|
|
548
562
|
try {
|
|
549
|
-
o = await h.open(
|
|
550
|
-
} catch (
|
|
551
|
-
throw
|
|
563
|
+
o = await h.open(r, "wx", 384);
|
|
564
|
+
} catch (n) {
|
|
565
|
+
throw O(n) === "EEXIST" ? new a("conflict", "任务目录恢复正在进行,请稍后重试") : n;
|
|
552
566
|
}
|
|
553
567
|
try {
|
|
554
|
-
return await o.writeFile(JSON.stringify({ pid: process.pid })), await
|
|
568
|
+
return await o.writeFile(JSON.stringify({ pid: process.pid })), await Ce(e, !0), await h.open(e, "wx", 384);
|
|
555
569
|
} finally {
|
|
556
|
-
await o.close(), await h.unlink(
|
|
570
|
+
await o.close(), await h.unlink(r);
|
|
557
571
|
}
|
|
558
572
|
}
|
|
559
|
-
async function
|
|
560
|
-
const
|
|
561
|
-
let
|
|
573
|
+
async function Ke(e, t) {
|
|
574
|
+
const r = v.join(e, ".writer-lock"), o = P();
|
|
575
|
+
let n;
|
|
562
576
|
try {
|
|
563
|
-
|
|
577
|
+
n = await h.open(r, "wx", 384);
|
|
564
578
|
} catch (s) {
|
|
565
|
-
if (
|
|
566
|
-
|
|
579
|
+
if (O(s) !== "EEXIST") throw s;
|
|
580
|
+
n = await De(r, t);
|
|
567
581
|
}
|
|
568
582
|
try {
|
|
569
|
-
await
|
|
583
|
+
await n.writeFile(JSON.stringify({ pid: process.pid, token: o })), await n.sync();
|
|
570
584
|
} catch (s) {
|
|
571
|
-
throw await
|
|
585
|
+
throw await n.close(), await h.unlink(r).catch(() => {
|
|
572
586
|
}), s;
|
|
573
587
|
}
|
|
574
|
-
return { file:
|
|
575
|
-
}
|
|
576
|
-
function
|
|
577
|
-
if ("tombstone" in
|
|
578
|
-
const
|
|
579
|
-
if (
|
|
580
|
-
const s = E(
|
|
581
|
-
e.tombstoneBytes += s, e.tombstones.set(t, { value:
|
|
588
|
+
return { file: r, token: o, handle: n };
|
|
589
|
+
}
|
|
590
|
+
function Le(e, t, r, o) {
|
|
591
|
+
if ("tombstone" in r) {
|
|
592
|
+
const n = r.tombstone;
|
|
593
|
+
if (Ue(n), T(n.scope, n.id), I(n.scope, n.id) !== t) throw new a("input", "持久任务摘要身份不匹配");
|
|
594
|
+
const s = E(n);
|
|
595
|
+
e.tombstoneBytes += s, e.tombstones.set(t, { value: n, bytes: s });
|
|
582
596
|
} else {
|
|
583
|
-
if (
|
|
584
|
-
const
|
|
585
|
-
e.bytes +=
|
|
597
|
+
if (K(r, r.scope, r.id, r.revision - 1), I(r.scope, r.id) !== t) throw new a("input", "持久任务文件身份不匹配");
|
|
598
|
+
const n = L(r, o);
|
|
599
|
+
e.bytes += n, e.records.set(t, { record: r, bytes: n });
|
|
586
600
|
}
|
|
587
601
|
if (e.bytes > o.maxBytes || e.records.size > o.maxRecords || e.tombstoneBytes > o.maxTombstoneBytes || e.tombstones.size > o.maxTombstones) throw new a("capacity", "持久任务及控制状态预留超过目录预算");
|
|
588
602
|
}
|
|
589
|
-
async function
|
|
590
|
-
const
|
|
591
|
-
for (const s of
|
|
592
|
-
const o =
|
|
603
|
+
async function ze(e, t) {
|
|
604
|
+
const r = await h.readdir(e);
|
|
605
|
+
for (const s of r.filter((i) => /^\.pending-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(i))) await h.unlink(v.join(e, s));
|
|
606
|
+
const o = r.filter((s) => /^[a-f0-9]{64}\.json$/.test(s));
|
|
593
607
|
if (o.length > t.maxRecords + t.maxTombstones) throw new a("capacity", "持久任务数量超过目录预算");
|
|
594
|
-
const
|
|
608
|
+
const n = { records: /* @__PURE__ */ new Map(), tombstones: /* @__PURE__ */ new Map(), bytes: 0, tombstoneBytes: 0 };
|
|
595
609
|
for (const s of o) {
|
|
596
|
-
const i =
|
|
610
|
+
const i = v.join(e, s);
|
|
597
611
|
if ((await h.stat(i)).size > 4e6) throw new a("capacity", "持久任务文件超过单文件预算");
|
|
598
|
-
|
|
612
|
+
Le(n, s, JSON.parse(await h.readFile(i, "utf8")), t);
|
|
599
613
|
}
|
|
600
|
-
return
|
|
614
|
+
return n;
|
|
601
615
|
}
|
|
602
|
-
async function
|
|
603
|
-
const o =
|
|
616
|
+
async function _e(e, t, r) {
|
|
617
|
+
const o = v.join(e, `.pending-${P()}`);
|
|
604
618
|
try {
|
|
605
|
-
const
|
|
619
|
+
const n = await h.open(o, "wx", 384);
|
|
606
620
|
try {
|
|
607
|
-
await
|
|
621
|
+
await n.writeFile(r), await n.sync();
|
|
608
622
|
} finally {
|
|
609
|
-
await
|
|
623
|
+
await n.close();
|
|
610
624
|
}
|
|
611
|
-
await h.rename(o,
|
|
625
|
+
await h.rename(o, v.join(e, t));
|
|
612
626
|
const s = await h.open(e, "r");
|
|
613
627
|
try {
|
|
614
628
|
await s.sync();
|
|
@@ -616,18 +630,18 @@ async function De(e, t, n) {
|
|
|
616
630
|
await s.close();
|
|
617
631
|
}
|
|
618
632
|
} finally {
|
|
619
|
-
await h.unlink(o).catch((
|
|
620
|
-
if (
|
|
633
|
+
await h.unlink(o).catch((n) => {
|
|
634
|
+
if (O(n) !== "ENOENT") throw n;
|
|
621
635
|
});
|
|
622
636
|
}
|
|
623
637
|
}
|
|
624
|
-
async function
|
|
625
|
-
const t =
|
|
638
|
+
async function Ge(e) {
|
|
639
|
+
const t = v.resolve(e.directory), r = Je(e);
|
|
626
640
|
await h.mkdir(t, { recursive: !0, mode: 448 });
|
|
627
|
-
const o = await
|
|
628
|
-
let
|
|
641
|
+
const o = await Ke(t, e.recoverDeadOwner ?? !1);
|
|
642
|
+
let n;
|
|
629
643
|
try {
|
|
630
|
-
|
|
644
|
+
n = await ze(t, r);
|
|
631
645
|
} catch (p) {
|
|
632
646
|
throw await o.handle.close(), await h.unlink(o.file), p;
|
|
633
647
|
}
|
|
@@ -645,49 +659,49 @@ async function Ke(e) {
|
|
|
645
659
|
}), f;
|
|
646
660
|
}, u = async (p, f, c) => {
|
|
647
661
|
try {
|
|
648
|
-
await
|
|
662
|
+
await _e(t, p, f);
|
|
649
663
|
} catch (m) {
|
|
650
|
-
throw await q(
|
|
664
|
+
throw await q(v.join(t, p)) === f && c(), m;
|
|
651
665
|
}
|
|
652
666
|
c();
|
|
653
667
|
};
|
|
654
668
|
return {
|
|
655
669
|
read: async (p, f) => {
|
|
656
670
|
d(), T(p, f), await i;
|
|
657
|
-
const c =
|
|
671
|
+
const c = n.records.get(I(p, f));
|
|
658
672
|
return c ? j(c.record) : void 0;
|
|
659
673
|
},
|
|
660
674
|
readTombstone: async (p, f) => {
|
|
661
675
|
d(), T(p, f), await i;
|
|
662
|
-
const c =
|
|
676
|
+
const c = n.tombstones.get(I(p, f));
|
|
663
677
|
return c ? j(c.value) : void 0;
|
|
664
678
|
},
|
|
665
|
-
candidates: async (p, f) => (d(), await i, Array.from(
|
|
679
|
+
candidates: async (p, f) => (d(), await i, Array.from(n.records.values(), (c) => c.record).filter((c) => Be(c, p)).sort((c, m) => c.createdAt - m.createdAt).slice(0, f).map(j)),
|
|
666
680
|
compareAndSwap: async (p, f, c, m) => {
|
|
667
|
-
const g = JSON.parse(
|
|
668
|
-
return
|
|
669
|
-
const x =
|
|
670
|
-
if ((l?.record.revision ?? null) !== c ||
|
|
671
|
-
|
|
672
|
-
const w =
|
|
673
|
-
if (N >
|
|
674
|
-
return await u(x,
|
|
675
|
-
|
|
681
|
+
const g = JSON.parse(S(m));
|
|
682
|
+
return K(g, p, f, c), y(async () => {
|
|
683
|
+
const x = I(p, f), l = n.records.get(x);
|
|
684
|
+
if ((l?.record.revision ?? null) !== c || n.tombstones.has(x)) return !1;
|
|
685
|
+
qe(l?.record, g);
|
|
686
|
+
const w = L(g, r), N = n.bytes - (l?.bytes ?? 0) + w;
|
|
687
|
+
if (N > r.maxBytes || !l && n.records.size >= r.maxRecords) throw new a("capacity", "持久任务容量已满,请清理终态任务或扩大显式预算");
|
|
688
|
+
return await u(x, S(g), () => {
|
|
689
|
+
n.records.set(x, { record: g, bytes: w }), n.bytes = N;
|
|
676
690
|
}), !0;
|
|
677
691
|
});
|
|
678
692
|
},
|
|
679
693
|
prune: async (p) => {
|
|
680
|
-
const f =
|
|
694
|
+
const f = Pe(p);
|
|
681
695
|
return y(async () => {
|
|
682
696
|
const c = { archived: 0, expired: 0 };
|
|
683
|
-
for (const [m, g] of
|
|
684
|
-
g.value.expiresAt > f.now || c.expired >= f.limit || (await h.unlink(
|
|
685
|
-
for (const [m, g] of
|
|
686
|
-
if (!
|
|
687
|
-
const x = await
|
|
688
|
-
if (
|
|
689
|
-
await u(m,
|
|
690
|
-
|
|
697
|
+
for (const [m, g] of n.tombstones)
|
|
698
|
+
g.value.expiresAt > f.now || c.expired >= f.limit || (await h.unlink(v.join(t, m)), n.tombstones.delete(m), n.tombstoneBytes -= g.bytes, c.expired++);
|
|
699
|
+
for (const [m, g] of n.records) {
|
|
700
|
+
if (!z(g.record) || g.record.updatedAt > f.terminalBefore || c.archived + c.expired >= f.limit) continue;
|
|
701
|
+
const x = await Fe(g.record, f.now + f.tombstoneRetentionMs), l = E(x);
|
|
702
|
+
if (n.tombstones.size >= r.maxTombstones || n.tombstoneBytes + l > r.maxTombstoneBytes) break;
|
|
703
|
+
await u(m, S({ tombstone: x }), () => {
|
|
704
|
+
n.tombstones.set(m, { value: x, bytes: l }), n.tombstoneBytes += l, n.records.delete(m), n.bytes -= g.bytes;
|
|
691
705
|
}), c.archived++;
|
|
692
706
|
}
|
|
693
707
|
if (c.expired) {
|
|
@@ -709,38 +723,38 @@ async function Ke(e) {
|
|
|
709
723
|
}
|
|
710
724
|
};
|
|
711
725
|
}
|
|
712
|
-
function
|
|
726
|
+
function Xe(e) {
|
|
713
727
|
const t = e.filename ?? e.workerUrl;
|
|
714
728
|
if (!t || e.filename && e.workerUrl) throw new TypeError("请且仅请指定 filename 或 workerUrl");
|
|
715
|
-
return
|
|
716
|
-
const
|
|
729
|
+
return Ne(() => {
|
|
730
|
+
const r = new H(t, e.workerOptions);
|
|
717
731
|
return {
|
|
718
|
-
postMessage: (o) =>
|
|
719
|
-
terminate: () =>
|
|
720
|
-
subscribe: (o,
|
|
721
|
-
const s = (i) =>
|
|
722
|
-
return
|
|
723
|
-
|
|
732
|
+
postMessage: (o) => r.postMessage(o),
|
|
733
|
+
terminate: () => r.terminate(),
|
|
734
|
+
subscribe: (o, n) => {
|
|
735
|
+
const s = (i) => n(new Error(`报表 Worker 在响应前退出(code ${i})`));
|
|
736
|
+
return r.on("message", o), r.on("error", n), r.on("messageerror", n), r.on("exit", s), () => {
|
|
737
|
+
r.off("message", o), r.off("error", n), r.off("messageerror", n), r.off("exit", s);
|
|
724
738
|
};
|
|
725
739
|
}
|
|
726
740
|
};
|
|
727
741
|
}, e);
|
|
728
742
|
}
|
|
729
|
-
function
|
|
730
|
-
const t =
|
|
743
|
+
function Ye(e) {
|
|
744
|
+
const t = _;
|
|
731
745
|
if (!t) throw new Error("serveNodeReportWorker 只能在 worker_threads 中调用");
|
|
732
|
-
const
|
|
733
|
-
|
|
746
|
+
const r = (o) => {
|
|
747
|
+
we(o) && be(e, o, (n) => t.postMessage({ protocol: M, id: o.id, type: "event", event: n })).then((n) => t.postMessage(n, Ae(n)));
|
|
734
748
|
};
|
|
735
|
-
return t.on("message",
|
|
749
|
+
return t.on("message", r), () => t.off("message", r);
|
|
736
750
|
}
|
|
737
|
-
function
|
|
751
|
+
function et(e) {
|
|
738
752
|
return W("sha256").update(e).digest("hex");
|
|
739
753
|
}
|
|
740
754
|
export {
|
|
741
755
|
B as ReportWorkerError,
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
756
|
+
Xe as createNodeReportExecutor,
|
|
757
|
+
Ge as openFileReportJobStore,
|
|
758
|
+
et as reportArtifactSha256,
|
|
759
|
+
Ye as serveNodeReportWorker
|
|
746
760
|
};
|