@agile-team/mach-report 2.8.4 → 2.9.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.
Files changed (94) hide show
  1. package/README.md +27 -9
  2. package/dist/ExcelBindingWizard-DiaxvWpQ.cjs +1 -0
  3. package/dist/ExcelBindingWizard-RLJIXKKG.js +816 -0
  4. package/dist/{ReportPreview-DTWiCH5a.js → ReportPreview-B5ZNEasW.js} +22 -21
  5. package/dist/ReportPreview-DRtVPUYo.cjs +6 -0
  6. package/dist/RuleEditor-N4qnMZ-Z.cjs +1 -0
  7. package/dist/RuleEditor-ynnUEK0s.js +1575 -0
  8. package/dist/TemplateReviewPanel-C_Lmzis6.cjs +1 -0
  9. package/dist/TemplateReviewPanel-Cn32OY4_.js +173 -0
  10. package/dist/analytics.cjs +1 -1
  11. package/dist/analytics.d.cts +188 -5
  12. package/dist/analytics.d.ts +188 -5
  13. package/dist/analytics.js +68 -202
  14. package/dist/{assets-B9qJku3V.js → assets-DDsfEi8R.js} +3 -3
  15. package/dist/{assets-RZan7EyL.cjs → assets-ahTRUXRk.cjs} +1 -1
  16. package/dist/binding-preview-B5834rml.cjs +2 -0
  17. package/dist/binding-preview-ChXjN5L5.js +649 -0
  18. package/dist/{capabilities-joSutDF8.js → capabilities-Cm9hZ3uV.js} +5 -5
  19. package/dist/{capabilities-xGTpnPjJ.cjs → capabilities-DYzWL7KS.cjs} +1 -1
  20. package/dist/dataset-BkRmwgeJ.cjs +1 -0
  21. package/dist/dataset-H5pFuQGU.js +121 -0
  22. package/dist/defaults-DXhiM1ZD.js +10 -0
  23. package/dist/defaults-xhmcLLrf.cjs +1 -0
  24. package/dist/designer.cjs +2 -1
  25. package/dist/designer.d.cts +1373 -6
  26. package/dist/designer.d.ts +1373 -6
  27. package/dist/designer.js +2495 -767
  28. package/dist/grid-geometry-BNptEcMm.js +65 -0
  29. package/dist/grid-geometry-CZ_cYB6O.cjs +1 -0
  30. package/dist/import-template-CNMLJSQw.js +23030 -0
  31. package/dist/import-template-CpxunKVp.cjs +29 -0
  32. package/dist/index.cjs +7 -7
  33. package/dist/index.d.cts +202 -3
  34. package/dist/index.d.ts +202 -3
  35. package/dist/index.js +554 -535
  36. package/dist/matrix-CNPDJxED.js +745 -0
  37. package/dist/matrix-Div9Ilh3.cjs +1 -0
  38. package/dist/pdf.cjs +46 -46
  39. package/dist/pdf.d.cts +2 -0
  40. package/dist/pdf.d.ts +2 -0
  41. package/dist/pdf.js +17 -16
  42. package/dist/{plugin-CQmJXNcA.js → plugin-BWwIgZXV.js} +1 -1
  43. package/dist/{plugin-DSFu51Ua.cjs → plugin-Dg-J1Rbm.cjs} +1 -1
  44. package/dist/progress-7OSZbFok.js +39 -0
  45. package/dist/progress-BnLiS5eH.cjs +1 -0
  46. package/dist/render-plan-7xpGrCEl.cjs +1 -0
  47. package/dist/render-plan-Ck6koX9L.js +13 -0
  48. package/dist/server/node.d.cts +62 -0
  49. package/dist/server/node.d.ts +62 -0
  50. package/dist/server-node.cjs +1 -1
  51. package/dist/server-node.js +373 -145
  52. package/dist/server.cjs +1 -1
  53. package/dist/server.d.cts +311 -0
  54. package/dist/server.d.ts +311 -0
  55. package/dist/server.js +590 -186
  56. package/dist/{style-Dv5o_x6b.js → style-CQ1PK8ZB.js} +5 -5
  57. package/dist/style-UgIJSA1F.cjs +1 -0
  58. package/dist/style.css +1 -1
  59. package/dist/template-registry-CHMYZ7SD.cjs +1 -0
  60. package/dist/template-registry-R61AMCr0.js +433 -0
  61. package/dist/template-review-hvWWQFsi.js +1027 -0
  62. package/dist/template-review-jEcOfmGr.cjs +1 -0
  63. package/dist/textwrap-CWHyzkBH.cjs +4 -0
  64. package/dist/{textwrap-DOl04hCQ.js → textwrap-DE1kgcJB.js} +1 -1
  65. package/dist/{validate-DfHPD8wX.cjs → validate-BDiMqkJC.cjs} +1 -1
  66. package/dist/{validate-S6CgIm5d.js → validate-DWPF7icl.js} +13 -13
  67. package/dist/vue/async.d.cts +186 -0
  68. package/dist/vue/async.d.ts +186 -0
  69. package/dist/vue/index.d.cts +271 -3
  70. package/dist/vue/index.d.ts +271 -3
  71. package/dist/vue-async.cjs +1 -1
  72. package/dist/vue-async.js +3 -3
  73. package/dist/vue.cjs +1 -1
  74. package/dist/vue.js +4 -4
  75. package/dist/worker.cjs +1 -1
  76. package/dist/worker.d.cts +2 -0
  77. package/dist/worker.d.ts +2 -0
  78. package/dist/worker.js +1 -1
  79. package/dist/xlsx.cjs +2 -30
  80. package/dist/xlsx.d.cts +268 -0
  81. package/dist/xlsx.d.ts +268 -0
  82. package/dist/xlsx.js +220 -23440
  83. package/package.json +1 -1
  84. package/dist/ReportPreview-DjGeWHY-.cjs +0 -6
  85. package/dist/progress-DD964VAB.js +0 -102
  86. package/dist/progress-KvhwXZ1Q.cjs +0 -1
  87. package/dist/render-plan-CckPEQyf.cjs +0 -1
  88. package/dist/render-plan-uzZYYSy1.js +0 -19
  89. package/dist/report-source-BXHNy_AD.js +0 -755
  90. package/dist/report-source-CCAvFE3t.cjs +0 -1
  91. package/dist/style-CpwiOPyB.cjs +0 -1
  92. package/dist/template-registry-DWExx0gU.cjs +0 -1
  93. package/dist/template-registry-NpOakidD.js +0 -354
  94. package/dist/textwrap-CnGsEum6.cjs +0 -4
package/dist/server.js CHANGED
@@ -1,245 +1,649 @@
1
- import { d as _, R as E, c as Q, P as W } from "./report-source-BXHNy_AD.js";
2
- import { g as k } from "./report-params-B_VCihAh.js";
3
- import { b as N, r as G, R as U } from "./param-validation-BWNjLcN0.js";
4
- import { c as X } from "./validate-S6CgIm5d.js";
5
- import { r as F, c as C, n as T } from "./task-events-Dpsvf_t2.js";
6
- class b extends Error {
7
- constructor(e, n, s) {
8
- super(n), this.code = e, this.path = s, this.name = "ReportRuntimeError";
1
+ import { R, b as G, a as Y, P as ee, f as te, r as re } from "./template-review-hvWWQFsi.js";
2
+ import { g as M } from "./report-params-B_VCihAh.js";
3
+ import { b as z, r as ne, R as se } from "./param-validation-BWNjLcN0.js";
4
+ import { c as ae } from "./validate-DWPF7icl.js";
5
+ import { d as oe } from "./dataset-H5pFuQGU.js";
6
+ import { r as V, c as D, n as L } from "./task-events-Dpsvf_t2.js";
7
+ import { p as ie } from "./template-registry-R61AMCr0.js";
8
+ class x extends Error {
9
+ constructor(t, r, n) {
10
+ super(r), this.code = t, this.path = n, this.name = "ReportRuntimeError";
9
11
  }
10
12
  }
11
- function y(r) {
12
- if (!r?.aborted) return;
13
- if (r.reason instanceof b) throw r.reason;
14
- const e = new Error("报表执行已取消");
15
- throw e.name = "AbortError", Object.defineProperty(e, "cause", { value: r.reason }), e;
16
- }
17
- function x(r, e, n) {
18
- if (!Number.isFinite(n) || n < 0) throw new b("budget", `${e} 的执行统计无效`, `$.budget.${e}`);
19
- const s = r[e];
20
- if (s !== void 0 && n > s) throw new b("budget", `${e} 超出预算 ${s}(实际 ${n})`, `$.budget.${e}`);
21
- }
22
- function H(r) {
23
- for (const [e, n] of Object.entries(r)) {
24
- if (n !== void 0 && (!Number.isFinite(n) || n <= 0)) throw new b("budget", `${e} 应为正有限数字`, `$.budget.${e}`);
25
- if (e !== "maxDurationMs" && n !== void 0 && !Number.isSafeInteger(n)) throw new b("budget", `${e} 应为正安全整数`, `$.budget.${e}`);
26
- if (e === "maxDurationMs" && n !== void 0 && n > 2147483647) throw new b("budget", "maxDurationMs 不能超过 2147483647", `$.budget.${e}`);
13
+ function v(e) {
14
+ if (!e?.aborted) return;
15
+ if (e.reason instanceof x) throw e.reason;
16
+ const t = new Error("报表执行已取消");
17
+ throw t.name = "AbortError", Object.defineProperty(t, "cause", { value: e.reason }), t;
18
+ }
19
+ function P(e, t, r) {
20
+ if (!Number.isFinite(r) || r < 0) throw new x("budget", `${t} 的执行统计无效`, `$.budget.${t}`);
21
+ const n = e[t];
22
+ if (n !== void 0 && r > n) throw new x("budget", `${t} 超出预算 ${n}(实际 ${r})`, `$.budget.${t}`);
23
+ }
24
+ function ce(e) {
25
+ for (const [t, r] of Object.entries(e)) {
26
+ if (r !== void 0 && (!Number.isFinite(r) || r <= 0)) throw new x("budget", `${t} 应为正有限数字`, `$.budget.${t}`);
27
+ if (t !== "maxDurationMs" && r !== void 0 && !Number.isSafeInteger(r)) throw new x("budget", `${t} 应为正安全整数`, `$.budget.${t}`);
28
+ if (t === "maxDurationMs" && r !== void 0 && r > 2147483647) throw new x("budget", "maxDurationMs 不能超过 2147483647", `$.budget.${t}`);
27
29
  }
28
30
  }
29
- async function A(r, e, n) {
30
- const s = new AbortController(), t = () => s.abort(r?.reason);
31
- r?.addEventListener("abort", t, { once: !0 }), r?.aborted && t();
32
- const a = Date.now(), u = e === void 0 ? void 0 : setTimeout(() => s.abort(new b("timeout", `报表执行超过 ${e}ms`)), e);
33
- let d;
31
+ async function T(e, t, r) {
32
+ const n = new AbortController(), s = () => n.abort(e?.reason);
33
+ e?.addEventListener("abort", s, { once: !0 }), e?.aborted && s();
34
+ const a = Date.now(), c = t === void 0 ? void 0 : setTimeout(() => n.abort(new x("timeout", `报表执行超过 ${t}ms`)), t);
35
+ let g;
34
36
  try {
35
- y(s.signal);
36
- const m = new Promise((w, i) => {
37
- d = () => {
37
+ v(n.signal);
38
+ const p = new Promise((u, i) => {
39
+ g = () => {
38
40
  try {
39
- y(s.signal);
40
- } catch (g) {
41
- i(g);
41
+ v(n.signal);
42
+ } catch (f) {
43
+ i(f);
42
44
  }
43
- }, s.signal.addEventListener("abort", d, { once: !0 });
44
- }), c = await Promise.race([n(s.signal), m]);
45
- if (y(s.signal), e !== void 0 && Date.now() - a > e) throw new b("timeout", `报表执行超过 ${e}ms`);
46
- return c;
45
+ }, n.signal.addEventListener("abort", g, { once: !0 });
46
+ }), o = await Promise.race([r(n.signal), p]);
47
+ if (v(n.signal), t !== void 0 && Date.now() - a > t) throw new x("timeout", `报表执行超过 ${t}ms`);
48
+ return o;
47
49
  } finally {
48
- u !== void 0 && clearTimeout(u), d && s.signal.removeEventListener("abort", d), r?.removeEventListener("abort", t);
50
+ c !== void 0 && clearTimeout(c), g && n.signal.removeEventListener("abort", g), e?.removeEventListener("abort", s);
49
51
  }
50
52
  }
51
- function z(r, e) {
52
- if (e.length === 0) throw new E("config", "缺少报表 ID");
53
- return e.map((n) => {
54
- if (!Object.prototype.hasOwnProperty.call(r, n)) throw new E("config", `未注册报表 ${n}`);
55
- return r[n];
53
+ function H(e, t) {
54
+ if (t.length === 0) throw new R("config", "缺少报表 ID");
55
+ return t.map((r) => {
56
+ if (!Object.prototype.hasOwnProperty.call(e, r)) throw new R("config", `未注册报表 ${r}`);
57
+ return e[r];
56
58
  });
57
59
  }
58
- function D(r) {
59
- return r.grid?.cells.reduce((e, n) => e + n.reduce((s, t) => s + (t ? 1 + (t.children?.reduce((a, u) => a + D(u), 0) ?? 0) : 0), 0), 0) ?? 0;
60
+ function C(e) {
61
+ return e.grid?.cells.reduce((t, r) => t + r.reduce((n, s) => n + (s ? 1 + (s.children?.reduce((a, c) => a + C(c), 0) ?? 0) : 0), 0), 0) ?? 0;
60
62
  }
61
- function K(r, e) {
62
- return r.pages.reduce((n, s) => n + s.components.reduce((t, a) => {
63
- if (a.kind !== "list") return t + D(a);
64
- const u = e[a.dataset]?.length ?? 0;
65
- return t + a.columns.length * (u + (a.headerGrid?.cells.length ?? 1));
66
- }, 0), 0);
63
+ function ue(e, t, r) {
64
+ return e.pages.reduce((n, s) => n + s.components.reduce((a, c) => c.kind !== "list" ? a + C(c) : a + te(c, t, r), 0), 0);
67
65
  }
68
- function Y(r, e = Object.keys(r)) {
69
- return z(r, e).map((n, s) => {
70
- const t = e[s], a = k(r, [t]);
66
+ function le(e, t = Object.keys(e)) {
67
+ return H(e, t).map((r, n) => {
68
+ const s = t[n], a = M(e, [s]);
71
69
  return {
72
- id: t,
70
+ id: s,
73
71
  params: JSON.parse(JSON.stringify(a)),
74
- paramsSchema: G(a),
75
- datasetsSchema: Object.fromEntries(Object.entries(n.dataSchema ?? {}).map(([u, d]) => [u, _(d)])),
72
+ paramsSchema: ne(a),
73
+ datasetsSchema: Object.fromEntries(Object.entries(r.dataSchema ?? {}).map(([c, g]) => [c, oe(g)])),
76
74
  capabilities: {
77
- save: !!n.provider?.save,
78
- export: !!n.provider?.export,
79
- templates: !!n.provider?.templates
75
+ save: !!r.provider?.save,
76
+ export: !!r.provider?.export,
77
+ templates: !!r.provider?.templates
80
78
  }
81
79
  };
82
80
  });
83
81
  }
84
- function J(r, e) {
85
- z(r, e.reportIds);
86
- const n = N(k(r, e.reportIds), e.params), s = e.reportIds.flatMap((a) => N(k(r, [a]), e.params).issues), t = new Map(s.map((a) => [JSON.stringify(a), a]));
87
- return { ...n, ok: t.size === 0, issues: [...t.values()] };
88
- }
89
- function Z(r, e) {
90
- const n = X(r.plan);
91
- if (!n.ok) throw new E("validate", `执行器返回无效计划:${n.errors[0]?.path}`);
92
- const s = r.plan.pages.length, t = r.plan.pages.reduce((a, u) => a + u.components.reduce((d, m) => d + D(m), 0), 0);
93
- return x(e, "maxRows", r.stats.rows), x(e, "maxPages", s), x(e, "maxCells", t), { ...r, stats: { ...r.stats, pages: s, cells: t } };
94
- }
95
- function M(r, e) {
96
- const n = J(r.reports, e);
97
- if (!n.ok) throw new U(n.issues);
98
- }
99
- function q(r = []) {
100
- return r.map(({ code: e, message: n, severity: s, pageIndex: t, componentIndex: a }) => ({ code: e, message: n, severity: s, path: `$.pages.${t}.components.${a}` }));
101
- }
102
- function ae(r) {
103
- const e = { maxRows: 1e5, maxPages: 1e4, maxCells: 2e6, maxOutputBytes: 1e8, maxDurationMs: 12e4, ...r.budget };
104
- H(e);
105
- const n = async (t, a) => {
106
- const u = Date.now();
107
- let d = 0, m = 0;
108
- const c = [], w = {}, i = Object.fromEntries(Object.entries(r.reports).map(([l, o]) => [l, {
109
- ...o,
110
- pagination: { ...r.pagination, ...o.pagination, ...a ? { measurer: a } : {} },
82
+ function K(e, t) {
83
+ H(e, t.reportIds);
84
+ const r = z(M(e, t.reportIds), t.params), n = t.reportIds.flatMap((a) => z(M(e, [a]), t.params).issues), s = new Map(n.map((a) => [JSON.stringify(a), a]));
85
+ return { ...r, ok: s.size === 0, issues: [...s.values()] };
86
+ }
87
+ function de(e, t) {
88
+ const r = ae(e.plan);
89
+ if (!r.ok) throw new R("validate", `执行器返回无效计划:${r.errors[0]?.path}`);
90
+ const n = e.plan.pages.length, s = e.plan.pages.reduce((a, c) => a + c.components.reduce((g, p) => g + C(p), 0), 0);
91
+ return P(t, "maxRows", e.stats.rows), P(t, "maxPages", n), P(t, "maxCells", s), { ...e, stats: { ...e.stats, pages: n, cells: s } };
92
+ }
93
+ function Q(e, t) {
94
+ const r = K(e.reports, t);
95
+ if (!r.ok) throw new se(r.issues);
96
+ }
97
+ function X(e = []) {
98
+ return e.map(({ code: t, message: r, severity: n, pageIndex: s, componentIndex: a }) => ({ code: t, message: r, severity: n, path: `$.pages.${s}.components.${a}` }));
99
+ }
100
+ function fe(e) {
101
+ const t = { maxRows: 1e5, maxPages: 1e4, maxCells: 2e6, maxOutputBytes: 1e8, maxDurationMs: 12e4, ...e.budget };
102
+ ce(t);
103
+ const r = async (s, a) => {
104
+ const c = Date.now();
105
+ let g = 0, p = 0;
106
+ const o = [], u = {}, i = Object.fromEntries(Object.entries(e.reports).map(([d, l]) => [d, {
107
+ ...l,
108
+ pagination: { ...e.pagination, ...l.pagination, ...a ? { measurer: a } : {} },
111
109
  dataValidation: {
112
- ...o.dataValidation,
113
- maxRows: Math.min(e.maxRows ?? 1e5, o.dataValidation?.maxRows ?? 1 / 0),
114
- maxCells: Math.min(e.maxCells ?? 2e6, o.dataValidation?.maxCells ?? 1 / 0)
110
+ ...l.dataValidation,
111
+ maxRows: Math.min(t.maxRows ?? 1e5, l.dataValidation?.maxRows ?? 1 / 0),
112
+ maxCells: Math.min(t.maxCells ?? 2e6, l.dataValidation?.maxCells ?? 1 / 0)
115
113
  }
116
- }])), p = await Q(i, { maxPages: e.maxPages, onDatasets: (l, o, v) => {
117
- d += Object.values(o).reduce((P, S) => P + S.length, 0), x(e, "maxRows", d), m += K(v, o), x(e, "maxCells", m);
118
- } })({ ...t, params: t.params ?? {}, onWarning: (l) => c.push({ code: "layout", message: l, severity: "warning" }), onQueryResult: (l, o) => {
119
- Object.defineProperty(w, l, { value: { revision: o.revision, sourceToken: o.sourceToken }, enumerable: !0, writable: !0 }), c.push(...o.diagnostics ?? []);
120
- } }).catch((l) => {
121
- throw l instanceof E && l.cause instanceof W ? new b("budget", l.cause.message, "$.budget.maxPages") : l;
114
+ }])), m = await G(i, { maxPages: t.maxPages, maxCells: t.maxCells, onDatasets: (d, l, y) => {
115
+ g += Object.values(l).reduce((S, J) => S + J.length, 0), P(t, "maxRows", g), p += ue(y, l, i[d]?.pagination), P(t, "maxCells", p);
116
+ } })({ ...s, params: s.params ?? {}, onWarning: (d) => o.push({ code: "layout", message: d, severity: "warning" }), onQueryResult: (d, l) => {
117
+ Object.defineProperty(u, d, { value: { revision: l.revision, sourceToken: l.sourceToken }, enumerable: !0, writable: !0 }), o.push(...l.diagnostics ?? []);
118
+ } }).catch((d) => {
119
+ throw d instanceof R && d.cause instanceof Y ? new x("budget", d.cause.message, "$.budget.maxPages") : d instanceof R && d.cause instanceof ee ? new x("budget", d.cause.message, "$.budget.maxCells") : d;
122
120
  });
123
- y(t.signal);
124
- const f = p.pages.reduce((l, o) => l + o.components.reduce((v, P) => v + D(P), 0), 0);
125
- return x(e, "maxPages", p.pages.length), x(e, "maxCells", f), { plan: p, diagnostics: c, revisions: w, stats: { rows: d, pages: p.pages.length, cells: f, durationMs: Date.now() - u } };
126
- }, s = async (t) => {
121
+ v(s.signal);
122
+ const h = m.pages.reduce((d, l) => d + l.components.reduce((y, S) => y + C(S), 0), 0);
123
+ return P(t, "maxPages", m.pages.length), P(t, "maxCells", h), { plan: m, diagnostics: o, revisions: u, stats: { rows: g, pages: m.pages.length, cells: h, durationMs: Date.now() - c } };
124
+ }, n = async (s) => {
127
125
  const a = Date.now();
128
- if (t.format !== "pdf" && t.format !== "xlsx") throw new E("config", "不支持的报表导出格式");
129
- const u = t.format === "pdf" ? await import("@agile-team/mach-report/pdf") : void 0;
130
- y(t.signal);
131
- const d = t.pdf?.customFontFaces ?? (t.pdf?.customFontBytes ? { regular: t.pdf.customFontBytes } : void 0), m = u && d ? u.createFontBytesMeasurer(d) : void 0, c = await n(t, m);
132
- y(t.signal);
133
- const w = C(t), i = await w.run("encode", async () => {
134
- let f;
135
- if (t.format === "pdf") {
136
- y(t.signal);
137
- const l = await u.renderPlanToPdf(c.plan, { ...t.pdf, ...m ? { measurer: m } : {}, fidelity: t.fidelity, signal: t.signal, onProgress: (o, v) => w.progress("encode", o, v) });
138
- f = l.bytes, c.diagnostics.push(...q(l.diagnostics)), c.diagnostics.push(...l.fidelityWarnings.map((o) => ({ code: "pdf-fidelity", message: o, severity: "warning" })), ...l.pageErrors.map((o) => ({ code: "pdf-page", message: o, severity: "error" }))), l.unsupportedTextCount && c.diagnostics.push({ code: "pdf-font", message: `${l.unsupportedTextCount} 段文本包含当前字体不支持的字符`, severity: "warning" });
126
+ if (s.format !== "pdf" && s.format !== "xlsx") throw new R("config", "不支持的报表导出格式");
127
+ const c = s.format === "pdf" ? await import("@agile-team/mach-report/pdf") : void 0;
128
+ v(s.signal);
129
+ const g = s.pdf?.customFontFaces ?? (s.pdf?.customFontBytes ? { regular: s.pdf.customFontBytes } : void 0), p = c && g ? c.createFontBytesMeasurer(g) : void 0, o = await r(s, p);
130
+ v(s.signal);
131
+ const u = D(s), i = await u.run("encode", async () => {
132
+ let h;
133
+ if (s.format === "pdf") {
134
+ v(s.signal);
135
+ const d = await c.renderPlanToPdf(o.plan, { ...s.pdf, ...p ? { measurer: p } : {}, fidelity: s.fidelity, signal: s.signal, onProgress: (l, y) => u.progress("encode", l, y) });
136
+ h = d.bytes, o.diagnostics.push(...X(d.diagnostics)), o.diagnostics.push(...d.fidelityWarnings.map((l) => ({ code: "pdf-fidelity", message: l, severity: "warning" })), ...d.pageErrors.map((l) => ({ code: "pdf-page", message: l, severity: "error" }))), d.unsupportedTextCount && o.diagnostics.push({ code: "pdf-font", message: `${d.unsupportedTextCount} 段文本包含当前字体不支持的字符`, severity: "warning" });
139
137
  } else {
140
- const { renderPlanToXlsx: l } = await import("@agile-team/mach-report/xlsx");
141
- y(t.signal);
142
- const o = await l(c.plan, { ...t.xlsx, fidelity: t.fidelity, signal: t.signal, onProgress: (v, P) => w.progress("encode", v, P) });
143
- f = new Uint8Array(o.buffer), c.diagnostics.push(...q(o.diagnostics)), c.diagnostics.push(...o.warnings.map((v) => ({ code: "xlsx-fidelity", message: v, severity: "warning" })));
138
+ const { renderPlanToXlsx: d } = await import("@agile-team/mach-report/xlsx");
139
+ v(s.signal);
140
+ const l = await d(o.plan, { ...s.xlsx, fidelity: s.fidelity, signal: s.signal, onProgress: (y, S) => u.progress("encode", y, S) });
141
+ h = new Uint8Array(l.buffer), o.diagnostics.push(...X(l.diagnostics)), o.diagnostics.push(...l.warnings.map((y) => ({ code: "xlsx-fidelity", message: y, severity: "warning" })));
144
142
  }
145
- return y(t.signal), f;
143
+ return v(s.signal), h;
146
144
  });
147
- x(e, "maxOutputBytes", i.byteLength);
148
- const { plan: g, ...p } = c;
149
- return { ...p, bytes: i, format: t.format, contentType: t.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", stats: { ...p.stats, durationMs: Date.now() - a, outputBytes: i.byteLength } };
145
+ P(t, "maxOutputBytes", i.byteLength);
146
+ const { plan: f, ...m } = o;
147
+ return { ...m, bytes: i, format: s.format, contentType: s.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", stats: { ...m.stats, durationMs: Date.now() - a, outputBytes: i.byteLength } };
150
148
  };
151
149
  return {
152
- describe: (t) => Y(r.reports, t),
153
- validate: (t) => J(r.reports, t),
154
- prepare: (t) => A(t.signal, e.maxDurationMs, async (a) => {
155
- const { signal: u, onEvent: d, ...m } = t, c = { ...m, taskId: m.taskId ?? F() }, w = d ? (p) => T(d, p, a) : void 0, i = { ...c, signal: a, onEvent: w };
156
- C(i).runSync("validate", () => M(r, c));
157
- const g = r.executor ? await r.executor.prepare(c, a, w) : await n(i);
158
- return Z(g, e);
150
+ describe: (s) => le(e.reports, s),
151
+ validate: (s) => K(e.reports, s),
152
+ prepare: (s) => T(s.signal, t.maxDurationMs, async (a) => {
153
+ const { signal: c, onEvent: g, ...p } = s, o = { ...p, taskId: p.taskId ?? V() }, u = g ? (m) => L(g, m, a) : void 0, i = { ...o, signal: a, onEvent: u };
154
+ D(i).runSync("validate", () => Q(e, o));
155
+ const f = e.executor ? await e.executor.prepare(o, a, u) : await r(i);
156
+ return de(f, t);
159
157
  }),
160
- export: (t) => A(t.signal, e.maxDurationMs, async (a) => {
161
- const { signal: u, onEvent: d, ...m } = t, c = { ...m, taskId: m.taskId ?? F() }, w = d ? (p) => T(d, p, a) : void 0, i = { ...c, signal: a, onEvent: w };
162
- if (C(i).runSync("validate", () => M(r, c)), c.format !== "pdf" && c.format !== "xlsx") throw new E("config", "不支持的报表导出格式");
163
- const g = r.executor ? await r.executor.export(c, a, w) : await s(i);
164
- return x(e, "maxRows", g.stats.rows), x(e, "maxPages", g.stats.pages), x(e, "maxCells", g.stats.cells), x(e, "maxOutputBytes", g.bytes.byteLength), { ...g, stats: { ...g.stats, outputBytes: g.bytes.byteLength } };
158
+ export: (s) => T(s.signal, t.maxDurationMs, async (a) => {
159
+ const { signal: c, onEvent: g, ...p } = s, o = { ...p, taskId: p.taskId ?? V() }, u = g ? (m) => L(g, m, a) : void 0, i = { ...o, signal: a, onEvent: u };
160
+ if (D(i).runSync("validate", () => Q(e, o)), o.format !== "pdf" && o.format !== "xlsx") throw new R("config", "不支持的报表导出格式");
161
+ const f = e.executor ? await e.executor.export(o, a, u) : await n(i);
162
+ return P(t, "maxRows", f.stats.rows), P(t, "maxPages", f.stats.pages), P(t, "maxCells", f.stats.cells), P(t, "maxOutputBytes", f.bytes.byteLength), { ...f, stats: { ...f.stats, outputBytes: f.bytes.byteLength } };
165
163
  })
166
164
  };
167
165
  }
168
- function oe(r = {}) {
169
- const e = r.concurrency ?? 1, n = r.maxQueued ?? 20;
170
- if (!Number.isSafeInteger(e) || e < 1 || !Number.isSafeInteger(n) || n < 0) throw new b("budget", "队列并发应为正整数,排队上限应为非负整数");
171
- const s = [], t = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
172
- let u = !1, d = 0;
173
- const m = () => {
174
- for (; !u && t.size < e && s.length; ) s.shift().start();
166
+ function ke(e = {}) {
167
+ const t = e.concurrency ?? 1, r = e.maxQueued ?? 20;
168
+ if (!Number.isSafeInteger(t) || t < 1 || !Number.isSafeInteger(r) || r < 0) throw new x("budget", "队列并发应为正整数,排队上限应为非负整数");
169
+ const n = [], s = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
170
+ let c = !1, g = 0;
171
+ const p = () => {
172
+ for (; !c && s.size < t && n.length; ) n.shift().start();
175
173
  };
176
174
  return {
177
175
  get active() {
178
- return t.size;
176
+ return s.size;
179
177
  },
180
178
  get pending() {
181
- return s.length;
179
+ return n.length;
182
180
  },
183
- enqueue: (w, i = {}) => {
184
- if (u) throw new b("closed", "任务队列已关闭");
185
- if (y(i.signal), t.size >= e && s.length >= n) throw new b("queue-full", "报表任务队列已满");
186
- const g = i.id ?? `report-${++d}`;
187
- if (a.has(g)) throw new b("queue-full", "任务 ID 正在执行或排队");
188
- const p = new AbortController();
189
- let f = "queued", l, o, v, P;
190
- const S = new Promise((h, R) => {
191
- v = h, P = R;
192
- }), j = () => {
193
- i.signal?.removeEventListener("abort", L), a.delete(g);
194
- }, I = (h) => {
195
- if (f !== "queued" && f !== "running") return;
196
- const R = f === "queued";
197
- f = "cancelled", p.abort(h);
181
+ enqueue: (u, i = {}) => {
182
+ if (c) throw new x("closed", "任务队列已关闭");
183
+ if (v(i.signal), s.size >= t && n.length >= r) throw new x("queue-full", "报表任务队列已满");
184
+ const f = i.id ?? `report-${++g}`;
185
+ if (a.has(f)) throw new x("queue-full", "任务 ID 正在执行或排队");
186
+ const m = new AbortController();
187
+ let h = "queued", d, l, y, S;
188
+ const J = new Promise((b, A) => {
189
+ y = b, S = A;
190
+ }), F = () => {
191
+ i.signal?.removeEventListener("abort", B), a.delete(f);
192
+ }, E = (b) => {
193
+ if (h !== "queued" && h !== "running") return;
194
+ const A = h === "queued";
195
+ h = "cancelled", m.abort(b);
198
196
  try {
199
- y(p.signal);
200
- } catch (O) {
201
- P(O);
197
+ v(m.signal);
198
+ } catch (I) {
199
+ S(I);
202
200
  }
203
- if (R) {
204
- const O = s.indexOf($);
205
- O >= 0 && s.splice(O, 1), j(), m();
201
+ if (A) {
202
+ const I = n.indexOf($);
203
+ I >= 0 && n.splice(I, 1), F(), p();
206
204
  }
207
- }, L = () => I(i.signal?.reason), B = (h, R) => {
208
- f === "running" && (!Number.isFinite(h) || h < 0 || R !== void 0 && (!Number.isFinite(R) || R < h) || (l = { completed: h, ...R === void 0 ? {} : { total: R } }));
209
- }, V = (h) => {
210
- f !== "running" || p.signal.aborted || (o = { ...h, taskId: g }, h.completed !== void 0 && B(h.completed, h.total), T(i.onEvent, o, p.signal));
205
+ }, B = () => E(i.signal?.reason), _ = (b, A) => {
206
+ h === "running" && (!Number.isFinite(b) || b < 0 || A !== void 0 && (!Number.isFinite(A) || A < b) || (d = { completed: b, ...A === void 0 ? {} : { total: A } }));
207
+ }, U = (b) => {
208
+ h !== "running" || m.signal.aborted || (l = { ...b, taskId: f }, b.completed !== void 0 && _(b.completed, b.total), L(i.onEvent, l, m.signal));
211
209
  }, $ = {
212
- cancel: I,
210
+ cancel: E,
213
211
  start: () => {
214
- f === "queued" && (f = "running", t.add($), Promise.resolve().then(() => (y(p.signal), w({ taskId: g, signal: p.signal, reportProgress: B, onEvent: V }))).then(
215
- (h) => {
216
- f === "running" && (f = "completed", v(h));
212
+ h === "queued" && (h = "running", s.add($), Promise.resolve().then(() => (v(m.signal), u({ taskId: f, signal: m.signal, reportProgress: _, onEvent: U }))).then(
213
+ (b) => {
214
+ h === "running" && (h = "completed", y(b));
217
215
  },
218
- (h) => {
219
- f === "running" && (f = "failed", P(h));
216
+ (b) => {
217
+ h === "running" && (h = "failed", S(b));
220
218
  }
221
219
  ).finally(() => {
222
- t.delete($), j(), m();
220
+ s.delete($), F(), p();
223
221
  }));
224
222
  }
225
223
  };
226
- return a.add(g), i.signal?.addEventListener("abort", L, { once: !0 }), i.signal?.aborted ? I(i.signal.reason) : t.size < e ? $.start() : s.push($), { id: g, get status() {
227
- return f;
224
+ return a.add(f), i.signal?.addEventListener("abort", B, { once: !0 }), i.signal?.aborted ? E(i.signal.reason) : s.size < t ? $.start() : n.push($), { id: f, get status() {
225
+ return h;
228
226
  }, get progress() {
229
- return l;
227
+ return d;
230
228
  }, get event() {
231
- return o;
232
- }, result: S, cancel: I };
229
+ return l;
230
+ }, result: J, cancel: E };
231
+ },
232
+ close: (u = {}) => {
233
+ c = !0;
234
+ for (const i of [...n]) i.cancel(new x("closed", "任务队列已关闭"));
235
+ if (u.cancelRunning) for (const i of s) i.cancel(new x("closed", "任务队列已关闭"));
236
+ }
237
+ };
238
+ }
239
+ class w extends Error {
240
+ constructor(t, r) {
241
+ super(r), this.code = t, this.name = "ReportJobError";
242
+ }
243
+ }
244
+ function k(e, t) {
245
+ if (typeof e != "string" || !e.trim() || e.length > 256 || typeof t != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(t)) throw new w("input", "任务范围应非空,ID应为1–128位安全标识");
246
+ }
247
+ function ge(e) {
248
+ const t = Array.isArray(e), r = Object.getPrototypeOf(e), n = Object.keys(e);
249
+ if (r !== (t ? Array.prototype : Object.prototype) && !(r === null && !t)) throw new w("input", "任务对象应为普通 JSON 对象");
250
+ if (Object.getOwnPropertySymbols(e).length) throw new w("input", "任务不能包含Symbol");
251
+ if (Object.getOwnPropertyNames(e).filter((a) => !(t && a === "length")).length !== n.length) throw new w("input", "任务不能包含不可枚举属性");
252
+ if (t && (n.length !== e.length || n.some((a) => !/^(0|[1-9]\d*)$/.test(a) || Number(a) >= e.length))) throw new w("input", "任务数组不能稀疏或包含额外属性");
253
+ return n.sort();
254
+ }
255
+ function we(e, t) {
256
+ const r = Object.getOwnPropertyDescriptor(e, t);
257
+ if (["__proto__", "prototype", "constructor"].includes(t) || r.get || r.set) throw new w("input", "任务不能包含危险键或访问器");
258
+ return r.value;
259
+ }
260
+ function O(e, t = {}) {
261
+ const r = t.maxNodes ?? 2e4, n = t.maxCharacters ?? 1e6;
262
+ if (!Number.isSafeInteger(r) || r < 1 || r > 2e4 || !Number.isSafeInteger(n) || n < 1 || n > 1e6) throw new w("input", "任务JSON预算无效");
263
+ let s = 0, a = 0;
264
+ const c = /* @__PURE__ */ new Set();
265
+ function g(o, u) {
266
+ if (++s > r || u > 32) throw new w("input", "任务数据超过节点或深度预算");
267
+ if (typeof o == "string") {
268
+ if (a += o.length, a > n) throw new w("input", "任务文本超过预算");
269
+ return o;
270
+ }
271
+ if (o === null || typeof o == "boolean" || typeof o == "number" && Number.isFinite(o)) return o;
272
+ if (!o || typeof o != "object" || c.has(o)) throw new w("input", "任务只允许无循环的有限 JSON 值");
273
+ const i = Array.isArray(o), f = ge(o);
274
+ c.add(o);
275
+ const m = /* @__PURE__ */ Object.create(null);
276
+ for (const h of f) {
277
+ if (a += h.length, a > n) throw new w("input", "任务文本超过预算");
278
+ m[h] = g(we(o, h), u + 1);
279
+ }
280
+ return c.delete(o), i ? Array.from({ length: o.length }, (h, d) => m[String(d)]) : m;
281
+ }
282
+ const p = JSON.stringify(g(e, 0));
283
+ if (p.length > n) throw new w("input", "任务序列化数据超过字符预算");
284
+ return p;
285
+ }
286
+ function N(e) {
287
+ return JSON.parse(JSON.stringify(e));
288
+ }
289
+ function pe(e, t, r, n) {
290
+ if (k(t, r), e.scope !== t || e.id !== r || e.revision !== (n ?? 0) + 1 || !Number.isSafeInteger(e.revision)) throw new w("input", "任务身份或修订不匹配");
291
+ if (![e.createdAt, e.updatedAt, e.attempt].every((s) => Number.isSafeInteger(s) && s >= 0) || !["queued", "running", "completed", "failed", "cancelled"].includes(e.status)) throw new w("input", "任务状态无效");
292
+ if (e.lease && (!e.lease.owner || !Number.isSafeInteger(e.lease.expiresAt))) throw new w("input", "任务租约无效");
293
+ if (!e.request || typeof e.request.kind != "string" || !e.request.kind.trim() || e.request.kind.length > 128) throw new w("input", "任务类型无效");
294
+ O(e.request.payload, { maxNodes: 19e3, maxCharacters: 75e4 }), O(e);
295
+ }
296
+ function me(e, t) {
297
+ if (e && (e.createdAt !== t.createdAt || O(e.request) !== O(t.request))) throw new w("input", "任务创建时间与请求不可变更,请使用新任务ID");
298
+ }
299
+ function he(e, t) {
300
+ return e.status === "queued" || e.status === "running" && (e.lease?.expiresAt ?? 0) <= t;
301
+ }
302
+ function je() {
303
+ const e = /* @__PURE__ */ new Map(), t = (r, n) => JSON.stringify([r, n]);
304
+ return {
305
+ read: async (r, n) => {
306
+ const s = e.get(t(r, n));
307
+ return s ? N(s) : void 0;
308
+ },
309
+ candidates: async (r, n) => Array.from(e.values()).filter((s) => he(s, r)).sort((s, a) => s.createdAt - a.createdAt).slice(0, n).map(N),
310
+ compareAndSwap: async (r, n, s, a) => {
311
+ pe(a, r, n, s);
312
+ const c = e.get(t(r, n));
313
+ return (c?.revision ?? null) !== s ? !1 : (me(c, a), e.set(t(r, n), N(a)), !0);
314
+ }
315
+ };
316
+ }
317
+ function ye(e) {
318
+ let t, r;
319
+ const n = new Promise((s, a) => {
320
+ t = s, r = a;
321
+ });
322
+ return n.catch(() => {
323
+ }), { progress: e, promise: n, resolve: t, reject: r };
324
+ }
325
+ function W(e) {
326
+ const t = Promise.reject(e);
327
+ return t.catch(() => {
328
+ }), t;
329
+ }
330
+ function be(e, t) {
331
+ let r, n, s = !0, a;
332
+ function c(o) {
333
+ a ??= o ?? new Error("任务心跳更新失败"), n?.reject(a), n = void 0, t(a);
334
+ }
335
+ function g(o) {
336
+ const u = Promise.resolve().then(() => e(o?.progress)).then(
337
+ () => o?.resolve(),
338
+ (i) => {
339
+ o?.reject(i), c(i);
340
+ }
341
+ ).finally(() => {
342
+ r = void 0;
343
+ const i = n;
344
+ n = void 0, i && a === void 0 && g(i);
345
+ });
346
+ r = u, u.catch((i) => {
347
+ c(i);
348
+ });
349
+ }
350
+ function p(o) {
351
+ if (!s)
352
+ return W(
353
+ new w("closed", "任务进度上报已结束")
354
+ );
355
+ if (a !== void 0) return W(a);
356
+ n ? n.progress = o : n = ye(o);
357
+ const u = n;
358
+ return r || (n = void 0, g(u)), u.promise;
359
+ }
360
+ return {
361
+ progress: p,
362
+ pulse() {
363
+ s && !r && a === void 0 && g();
233
364
  },
234
- close: (w = {}) => {
235
- u = !0;
236
- for (const i of [...s]) i.cancel(new b("closed", "任务队列已关闭"));
237
- if (w.cancelRunning) for (const i of t) i.cancel(new b("closed", "任务队列已关闭"));
365
+ async finish() {
366
+ for (s = !1; r; ) await r;
367
+ if (a !== void 0) throw a;
238
368
  }
239
369
  };
240
370
  }
371
+ function ve(e) {
372
+ const t = e.concurrency ?? 1, r = e.leaseMs ?? 3e4, n = e.heartbeatMs ?? 1e4;
373
+ if (![t, r, n].every(
374
+ (a) => Number.isSafeInteger(a) && a > 0
375
+ ) || n * 2 > r)
376
+ throw new w(
377
+ "input",
378
+ "并发、租约、心跳应为正整数,租约至少为心跳的两倍"
379
+ );
380
+ if (n > 2147483647)
381
+ throw new w(
382
+ "input",
383
+ "心跳间隔超过平台定时器上限(2147483647毫秒)"
384
+ );
385
+ return { concurrency: t, leaseMs: r, heartbeatMs: n, now: () => {
386
+ const a = (e.now ?? Date.now)();
387
+ if (!Number.isSafeInteger(a) || a < 0)
388
+ throw new w("input", "任务时钟应返回非负整数毫秒");
389
+ return a;
390
+ } };
391
+ }
392
+ async function j(e, t, r) {
393
+ k(t, r);
394
+ const n = await e.read(t, r);
395
+ if (!n) throw new w("missing", "报表任务不存在");
396
+ return n;
397
+ }
398
+ async function q(e, t, r, n = []) {
399
+ const s = { ...t, ...r, revision: t.revision + 1 };
400
+ for (const a of n) delete s[a];
401
+ if (!await e.compareAndSwap(
402
+ t.scope,
403
+ t.id,
404
+ t.revision,
405
+ s
406
+ ))
407
+ throw new w("conflict", "报表任务已被其他请求更新");
408
+ return N(s);
409
+ }
410
+ async function xe(e, t, r, n) {
411
+ if (!t.trim() || t.length > 128)
412
+ throw new w("input", "workerId应为1–128位标识");
413
+ for (const s of await e.store.candidates(n, 100)) {
414
+ const a = s.cancelRequested ? {
415
+ ...s,
416
+ revision: s.revision + 1,
417
+ status: "cancelled",
418
+ updatedAt: n
419
+ } : {
420
+ ...s,
421
+ revision: s.revision + 1,
422
+ status: "running",
423
+ attempt: s.attempt + 1,
424
+ updatedAt: n,
425
+ lease: { owner: t, expiresAt: n + r }
426
+ };
427
+ if (a.status === "cancelled" && delete a.lease, await e.store.compareAndSwap(
428
+ s.scope,
429
+ s.id,
430
+ s.revision,
431
+ a
432
+ ))
433
+ return a;
434
+ }
435
+ }
436
+ function Z(e, t, r, n) {
437
+ return e.status === "running" && e.attempt === n && e.lease?.owner === t && e.lease.expiresAt > r;
438
+ }
439
+ async function Se(e, t, r, n) {
440
+ const { scope: s, id: a } = r, c = r.lease.owner;
441
+ let g;
442
+ const p = be(
443
+ async (l) => {
444
+ const y = await j(e.store, s, a), S = t.now();
445
+ if (!Z(y, c, S, r.attempt))
446
+ throw new w("lease", "报表任务租约已失效");
447
+ if (y.cancelRequested) {
448
+ n.abort(new w("closed", "任务已请求取消"));
449
+ return;
450
+ }
451
+ await q(e.store, y, {
452
+ updatedAt: S,
453
+ lease: { owner: c, expiresAt: S + t.leaseMs },
454
+ ...l ? { progress: l } : {}
455
+ });
456
+ },
457
+ (l) => {
458
+ g = l, n.abort(l);
459
+ }
460
+ ), o = (l, y) => !Number.isFinite(l) || l < 0 || y !== void 0 && (!Number.isFinite(y) || y < l) ? Promise.reject(new w("input", "任务进度无效")) : p.progress({
461
+ completed: l,
462
+ ...y === void 0 ? {} : { total: y }
463
+ }), u = setInterval(() => {
464
+ p.pulse();
465
+ }, t.heartbeatMs);
466
+ let i, f;
467
+ try {
468
+ const l = Object.prototype.hasOwnProperty.call(
469
+ e.handlers,
470
+ r.request.kind
471
+ ) ? e.handlers[r.request.kind] : void 0;
472
+ if (!l) throw new w("input", "报表任务处理器未注册");
473
+ if (!n.signal.aborted) {
474
+ const y = await l(N(r.request.payload), {
475
+ scope: s,
476
+ taskId: a,
477
+ signal: n.signal,
478
+ reportProgress: o
479
+ });
480
+ i = JSON.parse(O(y));
481
+ }
482
+ } catch (l) {
483
+ f = l ?? new Error("报表任务执行失败");
484
+ } finally {
485
+ clearInterval(u), await p.finish().catch(() => {
486
+ });
487
+ }
488
+ const m = await j(e.store, s, a), h = t.now();
489
+ if (!Z(m, c, h, r.attempt))
490
+ throw new w("lease", "任务租约已失效,迟到结果不会写回");
491
+ const d = { ...m, updatedAt: h };
492
+ delete d.lease, f ??= g, m.cancelRequested || n.signal.aborted && g === void 0 ? d.status = "cancelled" : f !== void 0 ? (d.status = "failed", d.error = {
493
+ code: f instanceof w ? f.code : "execution",
494
+ message: f instanceof Error ? f.message.slice(0, 500) : "报表任务执行失败"
495
+ }) : (d.status = "completed", d.result = i);
496
+ try {
497
+ O(d);
498
+ } catch {
499
+ delete d.result, d.status = "failed", d.error = {
500
+ code: "result-budget",
501
+ message: "任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"
502
+ };
503
+ }
504
+ return q(e.store, m, d, ["lease"]);
505
+ }
506
+ function qe(e) {
507
+ e = { ...e, handlers: { ...e.handlers } };
508
+ const t = ve(e), r = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
509
+ let s = !1, a = 0;
510
+ const c = (o, u) => (k(o, u), e.store.read(o, u));
511
+ return {
512
+ submit: async (o) => {
513
+ if (o = { ...o }, k(o.scope, o.id), !Object.prototype.hasOwnProperty.call(e.handlers, o.kind) || typeof e.handlers[o.kind] != "function")
514
+ throw new w("input", "报表任务处理器未注册");
515
+ const u = {
516
+ kind: o.kind,
517
+ payload: JSON.parse(
518
+ O(o.payload, {
519
+ maxNodes: 19e3,
520
+ maxCharacters: 75e4
521
+ })
522
+ )
523
+ }, i = await c(o.scope, o.id);
524
+ if (i) {
525
+ if (O(i.request) !== O(u))
526
+ throw new w("conflict", "相同任务ID不能提交不同内容");
527
+ return i;
528
+ }
529
+ const f = t.now(), m = {
530
+ scope: o.scope,
531
+ id: o.id,
532
+ revision: 1,
533
+ request: u,
534
+ status: "queued",
535
+ createdAt: f,
536
+ updatedAt: f,
537
+ attempt: 0
538
+ };
539
+ if (!await e.store.compareAndSwap(o.scope, o.id, null, m)) {
540
+ const h = await c(o.scope, o.id);
541
+ if (h && O(h.request) === O(u))
542
+ return h;
543
+ throw new w("conflict", "报表任务提交发生冲突");
544
+ }
545
+ return N(m);
546
+ },
547
+ get: c,
548
+ runNext: (o) => {
549
+ if (s)
550
+ return Promise.reject(new w("closed", "报表任务服务已关闭"));
551
+ if (a >= t.concurrency)
552
+ return Promise.reject(
553
+ new w("capacity", "报表任务执行槽位已满")
554
+ );
555
+ a++;
556
+ const u = new AbortController();
557
+ r.add(u);
558
+ const i = (async () => {
559
+ try {
560
+ const f = await xe(
561
+ e,
562
+ o,
563
+ t.leaseMs,
564
+ t.now()
565
+ );
566
+ return f?.status === "running" ? await Se(e, t, f, u) : f;
567
+ } finally {
568
+ a--, r.delete(u);
569
+ }
570
+ })();
571
+ return n.add(i), i.then(
572
+ () => n.delete(i),
573
+ () => n.delete(i)
574
+ ), i;
575
+ },
576
+ get active() {
577
+ return a;
578
+ },
579
+ cancel: async (o, u) => {
580
+ const i = await j(e.store, o, u);
581
+ return i.status !== "queued" && i.status !== "running" ? i : q(e.store, i, {
582
+ updatedAt: t.now(),
583
+ ...i.status === "queued" ? { status: "cancelled" } : { cancelRequested: !0 }
584
+ });
585
+ },
586
+ retry: async (o, u, i) => {
587
+ const f = await j(e.store, o, u);
588
+ if (f.revision !== i || f.status !== "failed")
589
+ throw new w("conflict", "仅可重试当前修订的失败任务");
590
+ const m = {
591
+ ...f,
592
+ status: "queued",
593
+ updatedAt: t.now()
594
+ };
595
+ return delete m.error, delete m.progress, q(e.store, f, m, ["error", "progress"]);
596
+ },
597
+ close: async () => {
598
+ s = !0;
599
+ for (const o of r)
600
+ o.abort(new w("closed", "任务服务正在关闭"));
601
+ await Promise.allSettled([...n]);
602
+ }
603
+ };
604
+ }
605
+ async function Pe(e, t, r, n, s) {
606
+ const a = fe({ reports: { sample: { template: r, datasets: e.datasets } }, budget: {
607
+ maxRows: n.maxSampleRows ?? 1e3,
608
+ maxPages: n.maxPages ?? 100,
609
+ maxCells: n.maxCells ?? 25e4,
610
+ maxOutputBytes: n.maxOutputBytes ?? 2e7,
611
+ maxDurationMs: n.maxDurationMs ?? 3e4
612
+ } });
613
+ try {
614
+ const { result: c, digest: g } = await T(n.signal, n.maxDurationMs ?? 3e4, async (p) => {
615
+ const o = await a.export({ reportIds: ["sample"], params: e.params, format: t, signal: p, fidelity: n.strictOutputs ? "strict" : "warn", pdf: n.pdf, xlsx: n.xlsx }), u = await n.digest?.(o.bytes);
616
+ return v(p), await n.onArtifact?.(e.name, o), v(p), { result: o, digest: u };
617
+ });
618
+ s.artifacts.push({ fixture: e.name, format: t, bytes: c.bytes.byteLength, pages: c.stats.pages, ...g ? { digest: g } : {} }), s.issues.push(...c.diagnostics.map((p) => ({ code: "output", severity: n.strictOutputs || p.severity === "error" ? "error" : "warning", path: "$.template", fixture: e.name, message: `${t}: ${p.message}` })));
619
+ } catch (c) {
620
+ v(n.signal), s.issues.push({ code: "output", severity: "error", path: "$.template", fixture: e.name, message: `${t}: ${c instanceof Error ? c.message : String(c)}` });
621
+ }
622
+ }
623
+ async function Ce(e, t = {}) {
624
+ v(t.signal);
625
+ const r = { ...re(e, t), artifacts: [] };
626
+ if (!r.ok) return r;
627
+ const n = ie(e).template, s = [...new Set(t.formats ?? ["pdf", "xlsx"])];
628
+ if (!s.length || s.some((a) => a !== "pdf" && a !== "xlsx"))
629
+ return r.issues.push({ code: "output", severity: "error", path: "$.formats", message: "真实文件验收应至少选择PDF/XLSX之一" }), r.ok = !1, r;
630
+ for (const a of t.fixtures ?? [])
631
+ for (const c of s)
632
+ v(t.signal), !(c !== "pdf" && c !== "xlsx") && await Pe(a, c, n, t, r);
633
+ return r.ok = r.issues.every((a) => a.severity !== "error"), r;
634
+ }
241
635
  export {
242
- b as ReportRuntimeError,
243
- ae as createReportRuntime,
244
- oe as createReportTaskQueue
636
+ w as ReportJobError,
637
+ x as ReportRuntimeError,
638
+ k as checkJobIdentity,
639
+ N as cloneJob,
640
+ je as createMemoryReportJobStore,
641
+ qe as createReportJobService,
642
+ fe as createReportRuntime,
643
+ ke as createReportTaskQueue,
644
+ Ce as reviewReportPublication,
645
+ he as runnableJob,
646
+ O as serializeJobJson,
647
+ pe as validateJobRecord,
648
+ me as validateJobTransition
245
649
  };