@agile-team/mach-report 2.9.1 → 2.11.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 +11 -7
- package/dist/ExcelBindingWizard-CjIiVox-.cjs +1 -0
- package/dist/ExcelBindingWizard-Dxm-K5HL.js +1240 -0
- package/dist/ParamEditor-D-Hf5xfO.cjs +1 -0
- package/dist/ParamEditor-DRGxzxeO.js +381 -0
- package/dist/ReportBatchPanel-BYgg0EDB.cjs +1 -0
- package/dist/ReportBatchPanel-Bby5yLzU.js +287 -0
- package/dist/ReportPreview-DWXROHBP.cjs +6 -0
- package/dist/ReportPreview-DiNXhQI0.js +4138 -0
- package/dist/ReportTemplateLibrary-C6CO7YCT.cjs +1 -0
- package/dist/ReportTemplateLibrary-DfzDXRvr.js +260 -0
- package/dist/RuleEditor-C2QsOHOs.cjs +1 -0
- package/dist/RuleEditor-D9wQHrkf.js +2024 -0
- package/dist/TemplateReviewPanel-BKofGrV9.js +222 -0
- package/dist/TemplateReviewPanel-DwtOcLue.cjs +1 -0
- package/dist/analytics.cjs +1 -1
- package/dist/analytics.d.cts +4 -0
- package/dist/analytics.d.ts +4 -0
- package/dist/analytics.js +40 -39
- package/dist/{assets-ahTRUXRk.cjs → assets-Bu6UohJx.cjs} +1 -1
- package/dist/{assets-DDsfEi8R.js → assets-DegqDNqY.js} +1 -1
- package/dist/batch-Bt3Fd27Z.cjs +1 -0
- package/dist/batch-mRqhhhjt.js +364 -0
- package/dist/{capabilities-Cm9hZ3uV.js → capabilities-CK_7hizc.js} +16 -16
- package/dist/capabilities-CsZ-pNHR.cjs +1 -0
- package/dist/computed-Bvk0W15F.js +521 -0
- package/dist/computed-CGV2a809.cjs +1 -0
- package/dist/config-B612mw0x.js +525 -0
- package/dist/config-BRoLo2oj.cjs +1 -0
- package/dist/designer.cjs +2 -2
- package/dist/designer.d.cts +695 -50
- package/dist/designer.d.ts +695 -50
- package/dist/designer.js +2213 -1748
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +205 -6
- package/dist/index.d.ts +205 -6
- package/dist/index.js +808 -1033
- package/dist/injection-keys-Db_DyLkm.cjs +1 -0
- package/dist/injection-keys-e85udZCp.js +7 -0
- package/dist/list-cell-BuYn4tGF.cjs +1 -0
- package/dist/list-cell-ClFra1zS.js +173 -0
- package/dist/matrix-DVyWiYsd.cjs +1 -0
- package/dist/matrix-yZsGnldA.js +227 -0
- package/dist/param-validation-BlHHXs6u.js +153 -0
- package/dist/param-validation-DCK039V1.cjs +1 -0
- package/dist/pdf.cjs +49 -49
- package/dist/pdf.d.cts +31 -1
- package/dist/pdf.d.ts +31 -1
- package/dist/pdf.js +4797 -4650
- package/dist/plugin-BDTU4D94.cjs +1 -0
- package/dist/plugin-Cd5G2QQn.js +22 -0
- package/dist/region-binding-workflow-CXDmt9Bs.js +977 -0
- package/dist/region-binding-workflow-DhQvu1co.cjs +3 -0
- package/dist/{report-params-B_VCihAh.js → report-params-B44imUd4.js} +1 -1
- package/dist/{report-params-CjWrjPl6.cjs → report-params-SJfhKgaX.cjs} +1 -1
- package/dist/server/node.d.cts +48 -5
- package/dist/server/node.d.ts +48 -5
- package/dist/server-node.cjs +1 -1
- package/dist/server-node.js +503 -317
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +252 -4
- package/dist/server.d.ts +252 -4
- package/dist/server.js +567 -469
- package/dist/style.css +1 -1
- package/dist/template-registry-WNXdkiET.js +506 -0
- package/dist/template-registry-ukBGlm8N.cjs +1 -0
- package/dist/template-review-BXp2oyqg.cjs +1 -0
- package/dist/template-review-BdcXSYbx.js +1616 -0
- package/dist/tree-BX380Rr7.cjs +1 -0
- package/dist/tree-CqcQ99NM.js +172 -0
- package/dist/useLocalDraft-C07SYRnC.js +11 -0
- package/dist/useLocalDraft-Yiw1wFgI.cjs +1 -0
- package/dist/{validate-DWPF7icl.js → validate-7s0yn6ii.js} +26 -26
- package/dist/validate-DsRiNw8h.cjs +1 -0
- package/dist/vue/async.d.cts +118 -6
- package/dist/vue/async.d.ts +118 -6
- package/dist/vue/index.d.cts +177 -11
- package/dist/vue/index.d.ts +177 -11
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +5 -5
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +116 -113
- package/dist/{import-template-CNMLJSQw.js → workbook-session-BKOTwcoq.js} +4290 -4227
- package/dist/{import-template-CpxunKVp.cjs → workbook-session-CLYLhZWu.cjs} +17 -17
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.cts +9 -2
- package/dist/worker.d.ts +9 -2
- package/dist/worker.js +1 -1
- package/dist/xlsx.cjs +4 -2
- package/dist/xlsx.d.cts +159 -3
- package/dist/xlsx.d.ts +159 -3
- package/dist/xlsx.js +354 -192
- package/package.json +1 -1
- package/dist/ExcelBindingWizard-DiaxvWpQ.cjs +0 -1
- package/dist/ExcelBindingWizard-RLJIXKKG.js +0 -816
- package/dist/ReportPreview-B5ZNEasW.js +0 -4439
- package/dist/ReportPreview-DRtVPUYo.cjs +0 -6
- package/dist/RuleEditor-CskN5Fr3.cjs +0 -1
- package/dist/RuleEditor-CtJFzKuY.js +0 -1578
- package/dist/TemplateReviewPanel-C_Lmzis6.cjs +0 -1
- package/dist/TemplateReviewPanel-Cn32OY4_.js +0 -173
- package/dist/binding-preview-B5834rml.cjs +0 -2
- package/dist/binding-preview-ChXjN5L5.js +0 -649
- package/dist/capabilities-DYzWL7KS.cjs +0 -1
- package/dist/matrix-CNPDJxED.js +0 -745
- package/dist/matrix-Div9Ilh3.cjs +0 -1
- package/dist/param-validation-BWNjLcN0.js +0 -116
- package/dist/param-validation-CiTxFeZ8.cjs +0 -1
- package/dist/plugin-BWwIgZXV.js +0 -25
- package/dist/plugin-Dg-J1Rbm.cjs +0 -1
- package/dist/template-registry-CHMYZ7SD.cjs +0 -1
- package/dist/template-registry-R61AMCr0.js +0 -433
- package/dist/template-review-hvWWQFsi.js +0 -1027
- package/dist/template-review-jEcOfmGr.cjs +0 -1
- package/dist/validate-BDiMqkJC.cjs +0 -1
package/dist/server.js
CHANGED
|
@@ -1,649 +1,747 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { g as
|
|
3
|
-
import {
|
|
4
|
-
import { c as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
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;
|
|
36
|
-
try {
|
|
37
|
-
v(n.signal);
|
|
38
|
-
const p = new Promise((u, i) => {
|
|
39
|
-
g = () => {
|
|
40
|
-
try {
|
|
41
|
-
v(n.signal);
|
|
42
|
-
} catch (f) {
|
|
43
|
-
i(f);
|
|
44
|
-
}
|
|
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;
|
|
49
|
-
} finally {
|
|
50
|
-
c !== void 0 && clearTimeout(c), g && n.signal.removeEventListener("abort", g), e?.removeEventListener("abort", s);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
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];
|
|
1
|
+
import { A as oe, b as P, k as ie, B as ce, a as le, P as ue, n as de, y as fe } from "./template-review-BdcXSYbx.js";
|
|
2
|
+
import { g as T } from "./report-params-B44imUd4.js";
|
|
3
|
+
import { d as H, r as pe, R as Y } from "./param-validation-BlHHXs6u.js";
|
|
4
|
+
import { v as ge, c as q, a as R, t as b, R as A, b as v, d as $, s as I, e as D, j as we, f as me } from "./batch-mRqhhhjt.js";
|
|
5
|
+
import { g as et, r as tt, h as rt, i as st, k as nt, l as at } from "./batch-mRqhhhjt.js";
|
|
6
|
+
import { c as ee } from "./validate-7s0yn6ii.js";
|
|
7
|
+
import { r as Q, c as M, n as z } from "./task-events-Dpsvf_t2.js";
|
|
8
|
+
import { T as ye } from "./tree-CqcQ99NM.js";
|
|
9
|
+
import { p as he } from "./template-registry-WNXdkiET.js";
|
|
10
|
+
function te(e, t) {
|
|
11
|
+
if (t.length === 0) throw new P("config", "缺少报表 ID");
|
|
12
|
+
return t.map((s) => {
|
|
13
|
+
if (!Object.prototype.hasOwnProperty.call(e, s)) throw new P("config", `未注册报表 ${s}`);
|
|
14
|
+
return e[s];
|
|
58
15
|
});
|
|
59
16
|
}
|
|
60
17
|
function C(e) {
|
|
61
|
-
return e.grid?.cells.reduce((t,
|
|
18
|
+
return e.grid?.cells.reduce((t, s) => t + s.reduce((a, r) => a + (r ? 1 + (r.children?.reduce((n, i) => n + C(i), 0) ?? 0) : 0), 0), 0) ?? 0;
|
|
62
19
|
}
|
|
63
|
-
function
|
|
64
|
-
return e.pages.reduce((
|
|
20
|
+
function ve(e, t, s) {
|
|
21
|
+
return e.pages.reduce((a, r) => a + r.components.reduce((n, i) => i.kind !== "list" ? n + C(i) : n + de(i, t, s), 0), 0);
|
|
65
22
|
}
|
|
66
|
-
function
|
|
67
|
-
return
|
|
68
|
-
const
|
|
23
|
+
function be(e, t = Object.keys(e)) {
|
|
24
|
+
return te(e, t).map((s, a) => {
|
|
25
|
+
const r = t[a], n = T(e, [r]);
|
|
69
26
|
return {
|
|
70
|
-
id:
|
|
71
|
-
params: JSON.parse(JSON.stringify(
|
|
72
|
-
paramsSchema:
|
|
73
|
-
datasetsSchema: Object.fromEntries(Object.entries(
|
|
27
|
+
id: r,
|
|
28
|
+
params: JSON.parse(JSON.stringify(n)),
|
|
29
|
+
paramsSchema: pe(n),
|
|
30
|
+
datasetsSchema: Object.fromEntries(Object.entries(s.dataSchema ?? {}).map(([i, l]) => [i, oe(typeof s.template == "function" ? void 0 : s.template, i, l)])),
|
|
74
31
|
capabilities: {
|
|
75
|
-
save: !!
|
|
76
|
-
export: !!
|
|
77
|
-
templates: !!
|
|
32
|
+
save: !!s.provider?.save,
|
|
33
|
+
export: !!s.provider?.export,
|
|
34
|
+
templates: !!s.provider?.templates
|
|
78
35
|
}
|
|
79
36
|
};
|
|
80
37
|
});
|
|
81
38
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
return { ...
|
|
39
|
+
function re(e, t) {
|
|
40
|
+
te(e, t.reportIds);
|
|
41
|
+
const s = H(T(e, t.reportIds), t.params), a = t.reportIds.flatMap((n) => H(T(e, [n]), t.params).issues), r = new Map(a.map((n) => [JSON.stringify(n), n]));
|
|
42
|
+
return { ...s, ok: r.size === 0, issues: [...r.values()] };
|
|
86
43
|
}
|
|
87
|
-
function
|
|
88
|
-
const
|
|
89
|
-
if (!
|
|
90
|
-
const
|
|
91
|
-
return
|
|
44
|
+
function xe(e, t) {
|
|
45
|
+
const s = ee(e.plan);
|
|
46
|
+
if (!s.ok) throw new P("validate", `执行器返回无效计划:${s.errors[0]?.path}`);
|
|
47
|
+
const a = e.plan.pages.length, r = e.plan.pages.reduce((n, i) => n + i.components.reduce((l, f) => l + C(f), 0), 0);
|
|
48
|
+
return R(t, "maxRows", e.stats.rows), R(t, "maxPages", a), R(t, "maxCells", r), { ...e, stats: { ...e.stats, pages: a, cells: r } };
|
|
92
49
|
}
|
|
93
|
-
function
|
|
94
|
-
const
|
|
95
|
-
if (!
|
|
50
|
+
function X(e, t) {
|
|
51
|
+
const s = re(e.reports, t);
|
|
52
|
+
if (!s.ok) throw new Y(s.issues);
|
|
96
53
|
}
|
|
97
|
-
function
|
|
98
|
-
return e.map(({ code: t, message:
|
|
54
|
+
function G(e = []) {
|
|
55
|
+
return e.map(({ code: t, message: s, severity: a, pageIndex: r, componentIndex: n }) => ({ code: t, message: s, severity: a, path: `$.pages.${r}.components.${n}` }));
|
|
99
56
|
}
|
|
100
|
-
function
|
|
57
|
+
function Se(e) {
|
|
101
58
|
const t = { maxRows: 1e5, maxPages: 1e4, maxCells: 2e6, maxOutputBytes: 1e8, maxDurationMs: 12e4, ...e.budget };
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
let
|
|
106
|
-
const o = [], u = {},
|
|
107
|
-
...
|
|
108
|
-
pagination: { ...e.pagination, ...
|
|
59
|
+
ge(t);
|
|
60
|
+
const s = async (r, n) => {
|
|
61
|
+
const i = Date.now();
|
|
62
|
+
let l = 0, f = 0;
|
|
63
|
+
const o = [], u = {}, c = Object.fromEntries(Object.entries(e.reports).map(([g, p]) => [g, {
|
|
64
|
+
...p,
|
|
65
|
+
pagination: { ...e.pagination, ...p.pagination, ...n ? { measurer: n } : {} },
|
|
109
66
|
dataValidation: {
|
|
110
|
-
...
|
|
111
|
-
maxRows: Math.min(t.maxRows ?? 1e5,
|
|
112
|
-
maxCells: Math.min(t.maxCells ?? 2e6,
|
|
67
|
+
...p.dataValidation,
|
|
68
|
+
maxRows: Math.min(t.maxRows ?? 1e5, p.dataValidation?.maxRows ?? 1 / 0),
|
|
69
|
+
maxCells: Math.min(t.maxCells ?? 2e6, p.dataValidation?.maxCells ?? 1 / 0)
|
|
70
|
+
}
|
|
71
|
+
}])), m = await ie(c, { maxPages: t.maxPages, maxCells: t.maxCells, onDatasets: (g, p, h) => {
|
|
72
|
+
try {
|
|
73
|
+
l += ce(h, p, { maxRows: t.maxRows, signal: r.signal });
|
|
74
|
+
} catch (S) {
|
|
75
|
+
throw S instanceof ye ? new A("budget", S.message, "$.budget.maxRows") : S;
|
|
113
76
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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;
|
|
77
|
+
R(t, "maxRows", l), f += ve(h, p, c[g]?.pagination), R(t, "maxCells", f);
|
|
78
|
+
} })({ ...r, params: r.params ?? {}, onWarning: (g) => o.push({ code: "layout", message: g, severity: "warning" }), onQueryResult: (g, p) => {
|
|
79
|
+
Object.defineProperty(u, g, { value: { revision: p.revision, sourceToken: p.sourceToken }, enumerable: !0, writable: !0 }), o.push(...p.diagnostics ?? []);
|
|
80
|
+
} }).catch((g) => {
|
|
81
|
+
throw g instanceof P && g.cause instanceof le ? new A("budget", g.cause.message, "$.budget.maxPages") : g instanceof P && g.cause instanceof ue ? new A("budget", g.cause.message, "$.budget.maxCells") : g;
|
|
120
82
|
});
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
return
|
|
124
|
-
},
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
const u =
|
|
132
|
-
let
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
83
|
+
b(r.signal);
|
|
84
|
+
const y = m.pages.reduce((g, p) => g + p.components.reduce((h, S) => h + C(S), 0), 0);
|
|
85
|
+
return R(t, "maxPages", m.pages.length), R(t, "maxCells", y), { plan: m, diagnostics: o, revisions: u, stats: { rows: l, pages: m.pages.length, cells: y, durationMs: Date.now() - i } };
|
|
86
|
+
}, a = async (r) => {
|
|
87
|
+
const n = Date.now();
|
|
88
|
+
if (r.format !== "pdf" && r.format !== "xlsx") throw new P("config", "不支持的报表导出格式");
|
|
89
|
+
const i = r.format === "pdf" ? await import("@agile-team/mach-report/pdf") : void 0;
|
|
90
|
+
b(r.signal);
|
|
91
|
+
const l = r.pdf?.customFontFaces ?? (r.pdf?.customFontBytes ? { regular: r.pdf.customFontBytes } : void 0), f = i && l ? i.createFontBytesMeasurer(l) : void 0, o = await s(r, f);
|
|
92
|
+
b(r.signal);
|
|
93
|
+
const u = M(r), c = await u.run("encode", async () => {
|
|
94
|
+
let y;
|
|
95
|
+
if (r.format === "pdf") {
|
|
96
|
+
b(r.signal);
|
|
97
|
+
const g = await i.renderPlanToPdf(o.plan, { ...r.pdf, ...f ? { measurer: f } : {}, fidelity: r.fidelity, signal: r.signal, onProgress: (p, h) => u.progress("encode", p, h) });
|
|
98
|
+
y = g.bytes, o.diagnostics.push(...G(g.diagnostics)), o.diagnostics.push(...g.fidelityWarnings.map((p) => ({ code: "pdf-fidelity", message: p, severity: "warning" })), ...g.pageErrors.map((p) => ({ code: "pdf-page", message: p, severity: "error" }))), g.unsupportedTextCount && o.diagnostics.push({ code: "pdf-font", message: `${g.unsupportedTextCount} 段文本包含当前字体不支持的字符`, severity: "warning" });
|
|
137
99
|
} else {
|
|
138
|
-
const { renderPlanToXlsx:
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
|
|
100
|
+
const { renderPlanToXlsx: g } = await import("@agile-team/mach-report/xlsx");
|
|
101
|
+
b(r.signal);
|
|
102
|
+
const p = await g(o.plan, { ...r.xlsx, fidelity: r.fidelity, signal: r.signal, onProgress: (h, S) => u.progress("encode", h, S) });
|
|
103
|
+
y = new Uint8Array(p.buffer), o.diagnostics.push(...G(p.diagnostics)), o.diagnostics.push(...p.warnings.map((h) => ({ code: "xlsx-fidelity", message: h, severity: "warning" })));
|
|
142
104
|
}
|
|
143
|
-
return
|
|
105
|
+
return b(r.signal), y;
|
|
144
106
|
});
|
|
145
|
-
|
|
146
|
-
const { plan:
|
|
147
|
-
return { ...m, bytes:
|
|
107
|
+
R(t, "maxOutputBytes", c.byteLength);
|
|
108
|
+
const { plan: d, ...m } = o;
|
|
109
|
+
return { ...m, bytes: c, format: r.format, contentType: r.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", stats: { ...m.stats, durationMs: Date.now() - n, outputBytes: c.byteLength } };
|
|
148
110
|
};
|
|
149
111
|
return {
|
|
150
|
-
describe: (
|
|
151
|
-
validate: (
|
|
152
|
-
prepare: (
|
|
153
|
-
const { signal:
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
return
|
|
112
|
+
describe: (r) => be(e.reports, r),
|
|
113
|
+
validate: (r) => re(e.reports, r),
|
|
114
|
+
prepare: (r) => q(r.signal, t.maxDurationMs, async (n) => {
|
|
115
|
+
const { signal: i, onEvent: l, ...f } = r, o = { ...f, taskId: f.taskId ?? Q() }, u = l ? (m) => z(l, m, n) : void 0, c = { ...o, signal: n, onEvent: u };
|
|
116
|
+
M(c).runSync("validate", () => X(e, o));
|
|
117
|
+
const d = e.executor ? await e.executor.prepare(o, n, u) : await s(c);
|
|
118
|
+
return xe(d, t);
|
|
157
119
|
}),
|
|
158
|
-
export: (
|
|
159
|
-
const { signal:
|
|
160
|
-
if (
|
|
161
|
-
const
|
|
162
|
-
return
|
|
120
|
+
export: (r) => q(r.signal, t.maxDurationMs, async (n) => {
|
|
121
|
+
const { signal: i, onEvent: l, ...f } = r, o = { ...f, taskId: f.taskId ?? Q() }, u = l ? (m) => z(l, m, n) : void 0, c = { ...o, signal: n, onEvent: u };
|
|
122
|
+
if (M(c).runSync("validate", () => X(e, o)), o.format !== "pdf" && o.format !== "xlsx") throw new P("config", "不支持的报表导出格式");
|
|
123
|
+
const d = e.executor ? await e.executor.export(o, n, u) : await a(c);
|
|
124
|
+
return R(t, "maxRows", d.stats.rows), R(t, "maxPages", d.stats.pages), R(t, "maxCells", d.stats.cells), R(t, "maxOutputBytes", d.bytes.byteLength), { ...d, stats: { ...d.stats, outputBytes: d.bytes.byteLength } };
|
|
163
125
|
})
|
|
164
126
|
};
|
|
165
127
|
}
|
|
166
|
-
function
|
|
167
|
-
const t = e.concurrency ?? 1,
|
|
168
|
-
if (!Number.isSafeInteger(t) || t < 1 || !Number.isSafeInteger(
|
|
169
|
-
const
|
|
170
|
-
let
|
|
171
|
-
const
|
|
172
|
-
for (; !
|
|
128
|
+
function Qe(e = {}) {
|
|
129
|
+
const t = e.concurrency ?? 1, s = e.maxQueued ?? 20;
|
|
130
|
+
if (!Number.isSafeInteger(t) || t < 1 || !Number.isSafeInteger(s) || s < 0) throw new A("budget", "队列并发应为正整数,排队上限应为非负整数");
|
|
131
|
+
const a = [], r = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
132
|
+
let i = !1, l = 0;
|
|
133
|
+
const f = () => {
|
|
134
|
+
for (; !i && r.size < t && a.length; ) a.shift().start();
|
|
173
135
|
};
|
|
174
136
|
return {
|
|
175
137
|
get active() {
|
|
176
|
-
return
|
|
138
|
+
return r.size;
|
|
177
139
|
},
|
|
178
140
|
get pending() {
|
|
179
|
-
return
|
|
141
|
+
return a.length;
|
|
180
142
|
},
|
|
181
|
-
enqueue: (u,
|
|
182
|
-
if (
|
|
183
|
-
if (
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
143
|
+
enqueue: (u, c = {}) => {
|
|
144
|
+
if (i) throw new A("closed", "任务队列已关闭");
|
|
145
|
+
if (b(c.signal), r.size >= t && a.length >= s) throw new A("queue-full", "报表任务队列已满");
|
|
146
|
+
const d = c.id ?? `report-${++l}`;
|
|
147
|
+
if (n.has(d)) throw new A("queue-full", "任务 ID 正在执行或排队");
|
|
186
148
|
const m = new AbortController();
|
|
187
|
-
let
|
|
188
|
-
const
|
|
189
|
-
|
|
149
|
+
let y = "queued", g, p, h, S;
|
|
150
|
+
const ne = new Promise((x, O) => {
|
|
151
|
+
h = x, S = O;
|
|
190
152
|
}), F = () => {
|
|
191
|
-
|
|
192
|
-
}, E = (
|
|
193
|
-
if (
|
|
194
|
-
const
|
|
195
|
-
|
|
153
|
+
c.signal?.removeEventListener("abort", _), n.delete(d);
|
|
154
|
+
}, E = (x) => {
|
|
155
|
+
if (y !== "queued" && y !== "running") return;
|
|
156
|
+
const O = y === "queued";
|
|
157
|
+
y = "cancelled", m.abort(x);
|
|
196
158
|
try {
|
|
197
|
-
|
|
198
|
-
} catch (
|
|
199
|
-
S(
|
|
159
|
+
b(m.signal);
|
|
160
|
+
} catch (J) {
|
|
161
|
+
S(J);
|
|
200
162
|
}
|
|
201
|
-
if (
|
|
202
|
-
const
|
|
203
|
-
|
|
163
|
+
if (O) {
|
|
164
|
+
const J = a.indexOf(k);
|
|
165
|
+
J >= 0 && a.splice(J, 1), F(), f();
|
|
204
166
|
}
|
|
205
|
-
},
|
|
206
|
-
|
|
207
|
-
},
|
|
208
|
-
|
|
209
|
-
},
|
|
167
|
+
}, _ = () => E(c.signal?.reason), V = (x, O) => {
|
|
168
|
+
y === "running" && (!Number.isFinite(x) || x < 0 || O !== void 0 && (!Number.isFinite(O) || O < x) || (g = { completed: x, ...O === void 0 ? {} : { total: O } }));
|
|
169
|
+
}, ae = (x) => {
|
|
170
|
+
y !== "running" || m.signal.aborted || (p = { ...x, taskId: d }, x.completed !== void 0 && V(x.completed, x.total), z(c.onEvent, p, m.signal));
|
|
171
|
+
}, k = {
|
|
210
172
|
cancel: E,
|
|
211
173
|
start: () => {
|
|
212
|
-
|
|
213
|
-
(
|
|
214
|
-
|
|
174
|
+
y === "queued" && (y = "running", r.add(k), Promise.resolve().then(() => (b(m.signal), u({ taskId: d, signal: m.signal, reportProgress: V, onEvent: ae }))).then(
|
|
175
|
+
(x) => {
|
|
176
|
+
y === "running" && (y = "completed", h(x));
|
|
215
177
|
},
|
|
216
|
-
(
|
|
217
|
-
|
|
178
|
+
(x) => {
|
|
179
|
+
y === "running" && (y = "failed", S(x));
|
|
218
180
|
}
|
|
219
181
|
).finally(() => {
|
|
220
|
-
|
|
182
|
+
r.delete(k), F(), f();
|
|
221
183
|
}));
|
|
222
184
|
}
|
|
223
185
|
};
|
|
224
|
-
return
|
|
225
|
-
return
|
|
186
|
+
return n.add(d), c.signal?.addEventListener("abort", _, { once: !0 }), c.signal?.aborted ? E(c.signal.reason) : r.size < t ? k.start() : a.push(k), { id: d, get status() {
|
|
187
|
+
return y;
|
|
226
188
|
}, get progress() {
|
|
227
|
-
return
|
|
189
|
+
return g;
|
|
228
190
|
}, get event() {
|
|
229
|
-
return
|
|
230
|
-
}, result:
|
|
191
|
+
return p;
|
|
192
|
+
}, result: ne, cancel: E };
|
|
231
193
|
},
|
|
232
194
|
close: (u = {}) => {
|
|
233
|
-
|
|
234
|
-
for (const
|
|
235
|
-
if (u.cancelRunning) for (const
|
|
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);
|
|
195
|
+
i = !0;
|
|
196
|
+
for (const c of [...a]) c.cancel(new A("closed", "任务队列已关闭"));
|
|
197
|
+
if (u.cancelRunning) for (const c of r) c.cancel(new A("closed", "任务队列已关闭"));
|
|
314
198
|
}
|
|
315
199
|
};
|
|
316
200
|
}
|
|
317
|
-
function
|
|
318
|
-
let t,
|
|
319
|
-
const
|
|
320
|
-
t =
|
|
201
|
+
function Re(e) {
|
|
202
|
+
let t, s;
|
|
203
|
+
const a = new Promise((r, n) => {
|
|
204
|
+
t = r, s = n;
|
|
321
205
|
});
|
|
322
|
-
return
|
|
323
|
-
}), { progress: e, promise:
|
|
206
|
+
return a.catch(() => {
|
|
207
|
+
}), { progress: e, promise: a, resolve: t, reject: s };
|
|
324
208
|
}
|
|
325
|
-
function
|
|
209
|
+
function U(e) {
|
|
326
210
|
const t = Promise.reject(e);
|
|
327
211
|
return t.catch(() => {
|
|
328
212
|
}), t;
|
|
329
213
|
}
|
|
330
|
-
function
|
|
331
|
-
let
|
|
332
|
-
function
|
|
333
|
-
|
|
214
|
+
function Ie(e, t) {
|
|
215
|
+
let s, a, r = !0, n;
|
|
216
|
+
function i(o) {
|
|
217
|
+
n ??= o ?? new Error("任务心跳更新失败"), a?.reject(n), a = void 0, t(n);
|
|
334
218
|
}
|
|
335
|
-
function
|
|
219
|
+
function l(o) {
|
|
336
220
|
const u = Promise.resolve().then(() => e(o?.progress)).then(
|
|
337
221
|
() => o?.resolve(),
|
|
338
|
-
(
|
|
339
|
-
o?.reject(
|
|
222
|
+
(c) => {
|
|
223
|
+
o?.reject(c), i(c);
|
|
340
224
|
}
|
|
341
225
|
).finally(() => {
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
|
|
226
|
+
s = void 0;
|
|
227
|
+
const c = a;
|
|
228
|
+
a = void 0, c && n === void 0 && l(c);
|
|
345
229
|
});
|
|
346
|
-
|
|
347
|
-
c
|
|
230
|
+
s = u, u.catch((c) => {
|
|
231
|
+
i(c);
|
|
348
232
|
});
|
|
349
233
|
}
|
|
350
|
-
function
|
|
351
|
-
if (!
|
|
352
|
-
return
|
|
353
|
-
new
|
|
234
|
+
function f(o) {
|
|
235
|
+
if (!r)
|
|
236
|
+
return U(
|
|
237
|
+
new v("closed", "任务进度上报已结束")
|
|
354
238
|
);
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
const u =
|
|
358
|
-
return
|
|
239
|
+
if (n !== void 0) return U(n);
|
|
240
|
+
a ? a.progress = o : a = Re(o);
|
|
241
|
+
const u = a;
|
|
242
|
+
return s || (a = void 0, l(u)), u.promise;
|
|
359
243
|
}
|
|
360
244
|
return {
|
|
361
|
-
progress:
|
|
245
|
+
progress: f,
|
|
362
246
|
pulse() {
|
|
363
|
-
|
|
247
|
+
r && !s && n === void 0 && l();
|
|
364
248
|
},
|
|
365
249
|
async finish() {
|
|
366
|
-
for (
|
|
367
|
-
if (
|
|
250
|
+
for (r = !1; s; ) await s;
|
|
251
|
+
if (n !== void 0) throw n;
|
|
368
252
|
}
|
|
369
253
|
};
|
|
370
254
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
255
|
+
class W extends v {
|
|
256
|
+
constructor() {
|
|
257
|
+
super("capacity", "任务结果超过独立预算,请保存文件引用");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function Oe(e) {
|
|
261
|
+
const t = e.concurrency ?? 1, s = e.leaseMs ?? 3e4, a = e.heartbeatMs ?? 1e4, r = e.maxResultBytes ?? 256 * 1024;
|
|
262
|
+
if (![t, s, a, r].every(
|
|
263
|
+
(i) => Number.isSafeInteger(i) && i > 0
|
|
264
|
+
) || a * 2 > s)
|
|
265
|
+
throw new v(
|
|
377
266
|
"input",
|
|
378
267
|
"并发、租约、心跳应为正整数,租约至少为心跳的两倍"
|
|
379
268
|
);
|
|
380
|
-
if (
|
|
381
|
-
throw new
|
|
269
|
+
if (a > 2147483647)
|
|
270
|
+
throw new v(
|
|
382
271
|
"input",
|
|
383
272
|
"心跳间隔超过平台定时器上限(2147483647毫秒)"
|
|
384
273
|
);
|
|
385
|
-
return { concurrency: t, leaseMs:
|
|
386
|
-
const
|
|
387
|
-
if (!Number.isSafeInteger(
|
|
388
|
-
throw new
|
|
389
|
-
return
|
|
274
|
+
return { concurrency: t, leaseMs: s, heartbeatMs: a, maxResultBytes: r, now: () => {
|
|
275
|
+
const i = (e.now ?? Date.now)();
|
|
276
|
+
if (!Number.isSafeInteger(i) || i < 0)
|
|
277
|
+
throw new v("input", "任务时钟应返回非负整数毫秒");
|
|
278
|
+
return i;
|
|
390
279
|
} };
|
|
391
280
|
}
|
|
392
|
-
async function
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
if (!
|
|
396
|
-
return
|
|
281
|
+
async function B(e, t, s) {
|
|
282
|
+
$(t, s);
|
|
283
|
+
const a = await e.read(t, s);
|
|
284
|
+
if (!a) throw new v("missing", "报表任务不存在");
|
|
285
|
+
return a;
|
|
397
286
|
}
|
|
398
|
-
async function
|
|
399
|
-
const
|
|
400
|
-
for (const
|
|
287
|
+
async function j(e, t, s, a = []) {
|
|
288
|
+
const r = { ...t, ...s, revision: t.revision + 1 };
|
|
289
|
+
for (const n of a) delete r[n];
|
|
401
290
|
if (!await e.compareAndSwap(
|
|
402
291
|
t.scope,
|
|
403
292
|
t.id,
|
|
404
293
|
t.revision,
|
|
405
|
-
|
|
294
|
+
r
|
|
406
295
|
))
|
|
407
|
-
throw new
|
|
408
|
-
return
|
|
296
|
+
throw new v("conflict", "报表任务已被其他请求更新");
|
|
297
|
+
return D(r);
|
|
409
298
|
}
|
|
410
|
-
async function
|
|
299
|
+
async function Ae(e, t, s, a) {
|
|
411
300
|
if (!t.trim() || t.length > 128)
|
|
412
|
-
throw new
|
|
413
|
-
for (const
|
|
414
|
-
const
|
|
415
|
-
...
|
|
416
|
-
revision:
|
|
301
|
+
throw new v("input", "workerId应为1–128位标识");
|
|
302
|
+
for (const r of await e.store.candidates(a, 100)) {
|
|
303
|
+
const n = r.cancelRequested ? {
|
|
304
|
+
...r,
|
|
305
|
+
revision: r.revision + 1,
|
|
417
306
|
status: "cancelled",
|
|
418
|
-
updatedAt:
|
|
307
|
+
updatedAt: a
|
|
419
308
|
} : {
|
|
420
|
-
...
|
|
421
|
-
revision:
|
|
309
|
+
...r,
|
|
310
|
+
revision: r.revision + 1,
|
|
422
311
|
status: "running",
|
|
423
|
-
attempt:
|
|
424
|
-
updatedAt:
|
|
425
|
-
lease: { owner: t, expiresAt:
|
|
312
|
+
attempt: r.attempt + 1,
|
|
313
|
+
updatedAt: a,
|
|
314
|
+
lease: { owner: t, expiresAt: a + s }
|
|
426
315
|
};
|
|
427
|
-
if (
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
316
|
+
if (n.status === "cancelled" && delete n.lease, await e.store.compareAndSwap(
|
|
317
|
+
r.scope,
|
|
318
|
+
r.id,
|
|
319
|
+
r.revision,
|
|
320
|
+
n
|
|
432
321
|
))
|
|
433
|
-
return
|
|
322
|
+
return n;
|
|
434
323
|
}
|
|
435
324
|
}
|
|
436
|
-
function Z(e, t,
|
|
437
|
-
return e.status === "running" && e.attempt ===
|
|
438
|
-
}
|
|
439
|
-
async function
|
|
440
|
-
const { scope:
|
|
441
|
-
let
|
|
442
|
-
const
|
|
443
|
-
async (
|
|
444
|
-
const
|
|
445
|
-
if (!Z(
|
|
446
|
-
throw new
|
|
447
|
-
if (
|
|
448
|
-
|
|
325
|
+
function Z(e, t, s, a) {
|
|
326
|
+
return e.status === "running" && e.attempt === a && e.lease?.owner === t && e.lease.expiresAt > s;
|
|
327
|
+
}
|
|
328
|
+
async function Pe(e, t, s, a) {
|
|
329
|
+
const { scope: r, id: n } = s, i = s.lease.owner;
|
|
330
|
+
let l;
|
|
331
|
+
const f = Ie(
|
|
332
|
+
async (p) => {
|
|
333
|
+
const h = await B(e.store, r, n), S = t.now();
|
|
334
|
+
if (!Z(h, i, S, s.attempt))
|
|
335
|
+
throw new v("lease", "报表任务租约已失效");
|
|
336
|
+
if (h.cancelRequested) {
|
|
337
|
+
a.abort(new v("closed", "任务已请求取消"));
|
|
449
338
|
return;
|
|
450
339
|
}
|
|
451
|
-
await
|
|
340
|
+
await j(e.store, h, {
|
|
452
341
|
updatedAt: S,
|
|
453
|
-
lease: { owner:
|
|
454
|
-
...
|
|
342
|
+
lease: { owner: i, expiresAt: S + t.leaseMs },
|
|
343
|
+
...p ? { progress: p } : {}
|
|
455
344
|
});
|
|
456
345
|
},
|
|
457
|
-
(
|
|
458
|
-
|
|
346
|
+
(p) => {
|
|
347
|
+
l = p, a.abort(p);
|
|
459
348
|
}
|
|
460
|
-
), o = (
|
|
461
|
-
completed:
|
|
462
|
-
...
|
|
349
|
+
), o = (p, h) => !Number.isFinite(p) || p < 0 || h !== void 0 && (!Number.isFinite(h) || h < p) ? Promise.reject(new v("input", "任务进度无效")) : f.progress({
|
|
350
|
+
completed: p,
|
|
351
|
+
...h === void 0 ? {} : { total: h }
|
|
463
352
|
}), u = setInterval(() => {
|
|
464
|
-
|
|
353
|
+
f.pulse();
|
|
465
354
|
}, t.heartbeatMs);
|
|
466
|
-
let
|
|
355
|
+
let c, d;
|
|
467
356
|
try {
|
|
468
|
-
const
|
|
357
|
+
const p = Object.prototype.hasOwnProperty.call(
|
|
469
358
|
e.handlers,
|
|
470
|
-
|
|
471
|
-
) ? e.handlers[
|
|
472
|
-
if (!
|
|
473
|
-
if (!
|
|
474
|
-
const
|
|
475
|
-
scope:
|
|
476
|
-
taskId:
|
|
477
|
-
signal:
|
|
359
|
+
s.request.kind
|
|
360
|
+
) ? e.handlers[s.request.kind] : void 0;
|
|
361
|
+
if (!p) throw new v("input", "报表任务处理器未注册");
|
|
362
|
+
if (!a.signal.aborted) {
|
|
363
|
+
const h = await p(D(s.request.payload), {
|
|
364
|
+
scope: r,
|
|
365
|
+
taskId: n,
|
|
366
|
+
signal: a.signal,
|
|
478
367
|
reportProgress: o
|
|
479
368
|
});
|
|
480
|
-
|
|
369
|
+
if (c = JSON.parse(I(h)), we(c) > t.maxResultBytes) throw new W();
|
|
481
370
|
}
|
|
482
|
-
} catch (
|
|
483
|
-
|
|
371
|
+
} catch (p) {
|
|
372
|
+
d = p ?? new Error("报表任务执行失败");
|
|
484
373
|
} finally {
|
|
485
|
-
clearInterval(u), await
|
|
374
|
+
clearInterval(u), await f.finish().catch(() => {
|
|
486
375
|
});
|
|
487
376
|
}
|
|
488
|
-
const m = await
|
|
489
|
-
if (!Z(m,
|
|
490
|
-
throw new
|
|
491
|
-
const
|
|
492
|
-
delete
|
|
493
|
-
code:
|
|
494
|
-
message:
|
|
495
|
-
}) : (
|
|
377
|
+
const m = await B(e.store, r, n), y = t.now();
|
|
378
|
+
if (!Z(m, i, y, s.attempt))
|
|
379
|
+
throw new v("lease", "任务租约已失效,迟到结果不会写回");
|
|
380
|
+
const g = { ...m, updatedAt: y };
|
|
381
|
+
delete g.lease, d ??= l, m.cancelRequested || a.signal.aborted && l === void 0 ? g.status = "cancelled" : d !== void 0 ? (g.status = "failed", g.error = {
|
|
382
|
+
code: d instanceof W ? "result-budget" : d instanceof v ? d.code : "execution",
|
|
383
|
+
message: d instanceof Error ? d.message.slice(0, 500) : "报表任务执行失败"
|
|
384
|
+
}) : (g.status = "completed", g.result = c);
|
|
496
385
|
try {
|
|
497
|
-
|
|
386
|
+
I(g);
|
|
498
387
|
} catch {
|
|
499
|
-
delete
|
|
388
|
+
delete g.result, g.status = "failed", g.error = {
|
|
500
389
|
code: "result-budget",
|
|
501
390
|
message: "任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"
|
|
502
391
|
};
|
|
503
392
|
}
|
|
504
|
-
return
|
|
393
|
+
return ke(e.store, m, g);
|
|
394
|
+
}
|
|
395
|
+
async function ke(e, t, s) {
|
|
396
|
+
try {
|
|
397
|
+
return await j(e, t, s, ["lease"]);
|
|
398
|
+
} catch (a) {
|
|
399
|
+
if (!(a instanceof v) || a.code !== "capacity" || s.status !== "completed") throw a;
|
|
400
|
+
return delete s.result, s.status = "failed", s.error = { code: "result-budget", message: "任务结果超过存储剩余预算,请保存文件引用而非文件内容" }, j(e, t, s, ["lease", "result"]);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
async function K(e, t, s, a) {
|
|
404
|
+
const r = await e.readTombstone?.(t, s);
|
|
405
|
+
if (r) {
|
|
406
|
+
if (r.requestHash !== await me(a)) throw new v("conflict", "相同任务ID不能提交不同内容(幂等保留期内)");
|
|
407
|
+
return { scope: t, id: s, revision: r.revision, request: D(a), status: r.status, createdAt: r.createdAt, updatedAt: r.updatedAt, attempt: r.attempt, archived: !0 };
|
|
408
|
+
}
|
|
505
409
|
}
|
|
506
|
-
function
|
|
410
|
+
function Xe(e) {
|
|
507
411
|
e = { ...e, handlers: { ...e.handlers } };
|
|
508
|
-
const t =
|
|
509
|
-
let
|
|
510
|
-
const
|
|
412
|
+
const t = Oe(e), s = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
|
|
413
|
+
let r = !1, n = 0;
|
|
414
|
+
const i = (o, u) => ($(o, u), e.store.read(o, u));
|
|
511
415
|
return {
|
|
512
416
|
submit: async (o) => {
|
|
513
|
-
if (o = { ...o },
|
|
514
|
-
throw new
|
|
417
|
+
if (o = { ...o }, $(o.scope, o.id), !Object.prototype.hasOwnProperty.call(e.handlers, o.kind) || typeof e.handlers[o.kind] != "function")
|
|
418
|
+
throw new v("input", "报表任务处理器未注册");
|
|
515
419
|
const u = {
|
|
516
420
|
kind: o.kind,
|
|
517
421
|
payload: JSON.parse(
|
|
518
|
-
|
|
422
|
+
I(o.payload, {
|
|
519
423
|
maxNodes: 19e3,
|
|
520
424
|
maxCharacters: 75e4
|
|
521
425
|
})
|
|
522
426
|
)
|
|
523
|
-
},
|
|
524
|
-
if (
|
|
525
|
-
if (
|
|
526
|
-
throw new
|
|
527
|
-
return
|
|
427
|
+
}, c = await i(o.scope, o.id);
|
|
428
|
+
if (c) {
|
|
429
|
+
if (I(c.request) !== I(u))
|
|
430
|
+
throw new v("conflict", "相同任务ID不能提交不同内容");
|
|
431
|
+
return c;
|
|
528
432
|
}
|
|
529
|
-
const
|
|
433
|
+
const d = await K(e.store, o.scope, o.id, u);
|
|
434
|
+
if (d) return d;
|
|
435
|
+
const m = t.now(), y = {
|
|
530
436
|
scope: o.scope,
|
|
531
437
|
id: o.id,
|
|
532
438
|
revision: 1,
|
|
533
439
|
request: u,
|
|
534
440
|
status: "queued",
|
|
535
|
-
createdAt:
|
|
536
|
-
updatedAt:
|
|
441
|
+
createdAt: m,
|
|
442
|
+
updatedAt: m,
|
|
537
443
|
attempt: 0
|
|
538
444
|
};
|
|
539
|
-
if (!await e.store.compareAndSwap(o.scope, o.id, null,
|
|
540
|
-
const
|
|
541
|
-
if (
|
|
542
|
-
return
|
|
543
|
-
|
|
445
|
+
if (!await e.store.compareAndSwap(o.scope, o.id, null, y)) {
|
|
446
|
+
const g = await i(o.scope, o.id);
|
|
447
|
+
if (g && I(g.request) === I(u))
|
|
448
|
+
return g;
|
|
449
|
+
const p = await K(e.store, o.scope, o.id, u);
|
|
450
|
+
if (p) return p;
|
|
451
|
+
throw new v("conflict", "报表任务提交发生冲突");
|
|
544
452
|
}
|
|
545
|
-
return
|
|
453
|
+
return D(y);
|
|
546
454
|
},
|
|
547
|
-
get:
|
|
455
|
+
get: i,
|
|
548
456
|
runNext: (o) => {
|
|
549
|
-
if (
|
|
550
|
-
return Promise.reject(new
|
|
551
|
-
if (
|
|
457
|
+
if (r)
|
|
458
|
+
return Promise.reject(new v("closed", "报表任务服务已关闭"));
|
|
459
|
+
if (n >= t.concurrency)
|
|
552
460
|
return Promise.reject(
|
|
553
|
-
new
|
|
461
|
+
new v("capacity", "报表任务执行槽位已满")
|
|
554
462
|
);
|
|
555
|
-
|
|
463
|
+
n++;
|
|
556
464
|
const u = new AbortController();
|
|
557
|
-
|
|
558
|
-
const
|
|
465
|
+
s.add(u);
|
|
466
|
+
const c = (async () => {
|
|
559
467
|
try {
|
|
560
|
-
const
|
|
468
|
+
const d = await Ae(
|
|
561
469
|
e,
|
|
562
470
|
o,
|
|
563
471
|
t.leaseMs,
|
|
564
472
|
t.now()
|
|
565
473
|
);
|
|
566
|
-
return
|
|
474
|
+
return d?.status === "running" ? await Pe(e, t, d, u) : d;
|
|
567
475
|
} finally {
|
|
568
|
-
|
|
476
|
+
n--, s.delete(u);
|
|
569
477
|
}
|
|
570
478
|
})();
|
|
571
|
-
return
|
|
572
|
-
() =>
|
|
573
|
-
() =>
|
|
574
|
-
),
|
|
479
|
+
return a.add(c), c.then(
|
|
480
|
+
() => a.delete(c),
|
|
481
|
+
() => a.delete(c)
|
|
482
|
+
), c;
|
|
575
483
|
},
|
|
576
484
|
get active() {
|
|
577
|
-
return
|
|
485
|
+
return n;
|
|
578
486
|
},
|
|
579
487
|
cancel: async (o, u) => {
|
|
580
|
-
const
|
|
581
|
-
return
|
|
488
|
+
const c = await B(e.store, o, u);
|
|
489
|
+
return c.status !== "queued" && c.status !== "running" ? c : j(e.store, c, {
|
|
582
490
|
updatedAt: t.now(),
|
|
583
|
-
...
|
|
491
|
+
...c.status === "queued" ? { status: "cancelled" } : { cancelRequested: !0 }
|
|
584
492
|
});
|
|
585
493
|
},
|
|
586
|
-
retry: async (o, u,
|
|
587
|
-
const
|
|
588
|
-
if (
|
|
589
|
-
throw new
|
|
494
|
+
retry: async (o, u, c) => {
|
|
495
|
+
const d = await B(e.store, o, u);
|
|
496
|
+
if (d.revision !== c || d.status !== "failed")
|
|
497
|
+
throw new v("conflict", "仅可重试当前修订的失败任务");
|
|
590
498
|
const m = {
|
|
591
|
-
...
|
|
499
|
+
...d,
|
|
592
500
|
status: "queued",
|
|
593
501
|
updatedAt: t.now()
|
|
594
502
|
};
|
|
595
|
-
return delete m.error, delete m.progress,
|
|
503
|
+
return delete m.error, delete m.progress, j(e.store, d, m, ["error", "progress"]);
|
|
504
|
+
},
|
|
505
|
+
prune: async (o) => {
|
|
506
|
+
if (!e.store.prune || !e.store.readTombstone) throw new v("input", "当前任务适配器未实现可选终态保留能力");
|
|
507
|
+
return e.store.prune({ ...o, now: t.now() });
|
|
596
508
|
},
|
|
597
509
|
close: async () => {
|
|
598
|
-
|
|
599
|
-
for (const o of
|
|
600
|
-
o.abort(new
|
|
601
|
-
await Promise.allSettled([...
|
|
510
|
+
r = !0;
|
|
511
|
+
for (const o of s)
|
|
512
|
+
o.abort(new v("closed", "任务服务正在关闭"));
|
|
513
|
+
await Promise.allSettled([...a]);
|
|
602
514
|
}
|
|
603
515
|
};
|
|
604
516
|
}
|
|
605
|
-
async function
|
|
606
|
-
const
|
|
607
|
-
maxRows:
|
|
608
|
-
maxPages:
|
|
609
|
-
maxCells:
|
|
610
|
-
maxOutputBytes:
|
|
611
|
-
maxDurationMs:
|
|
517
|
+
async function Ne(e, t, s, a, r) {
|
|
518
|
+
const n = Se({ reports: { sample: { template: s, datasets: e.datasets } }, budget: {
|
|
519
|
+
maxRows: a.maxSampleRows ?? 1e3,
|
|
520
|
+
maxPages: a.maxPages ?? 100,
|
|
521
|
+
maxCells: a.maxCells ?? 25e4,
|
|
522
|
+
maxOutputBytes: a.maxOutputBytes ?? 2e7,
|
|
523
|
+
maxDurationMs: a.maxDurationMs ?? 3e4
|
|
612
524
|
} });
|
|
613
525
|
try {
|
|
614
|
-
const { result:
|
|
615
|
-
const o = await
|
|
616
|
-
return
|
|
526
|
+
const { result: i, digest: l } = await q(a.signal, a.maxDurationMs ?? 3e4, async (f) => {
|
|
527
|
+
const o = await n.export({ reportIds: ["sample"], params: e.params, format: t, signal: f, fidelity: a.strictOutputs ? "strict" : "warn", pdf: a.pdf, xlsx: a.xlsx }), u = await a.digest?.(o.bytes);
|
|
528
|
+
return b(f), await a.onArtifact?.(e.name, o), b(f), { result: o, digest: u };
|
|
617
529
|
});
|
|
618
|
-
|
|
619
|
-
} catch (
|
|
620
|
-
|
|
530
|
+
r.artifacts.push({ fixture: e.name, format: t, bytes: i.bytes.byteLength, pages: i.stats.pages, ...l ? { digest: l } : {} }), r.issues.push(...i.diagnostics.map((f) => ({ code: "output", severity: a.strictOutputs || f.severity === "error" ? "error" : "warning", path: "$.template", fixture: e.name, message: `${t}: ${f.message}` })));
|
|
531
|
+
} catch (i) {
|
|
532
|
+
b(a.signal), r.issues.push({ code: "output", severity: "error", path: "$.template", fixture: e.name, message: `${t}: ${i instanceof Error ? i.message : String(i)}` });
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function Ge(e, t = {}) {
|
|
536
|
+
b(t.signal);
|
|
537
|
+
const s = { ...fe(e, t), artifacts: [] };
|
|
538
|
+
if (!s.ok) return s;
|
|
539
|
+
const a = he(e).template, r = [...new Set(t.formats ?? ["pdf", "xlsx"])];
|
|
540
|
+
if (!r.length || r.some((n) => n !== "pdf" && n !== "xlsx"))
|
|
541
|
+
return s.issues.push({ code: "output", severity: "error", path: "$.formats", message: "真实文件验收应至少选择PDF/XLSX之一" }), s.ok = !1, s;
|
|
542
|
+
for (const n of t.fixtures ?? [])
|
|
543
|
+
for (const i of r)
|
|
544
|
+
b(t.signal), !(i !== "pdf" && i !== "xlsx") && await Ne(n, i, a, t, s);
|
|
545
|
+
return s.ok = s.issues.every((n) => n.severity !== "error"), s;
|
|
546
|
+
}
|
|
547
|
+
class w extends Error {
|
|
548
|
+
constructor(t, s) {
|
|
549
|
+
super(s), this.code = t, this.name = "ReportInstanceError";
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
function N(e, t) {
|
|
553
|
+
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 w("input", "实例范围应非空,ID 应为安全标识");
|
|
554
|
+
}
|
|
555
|
+
function je(e, t) {
|
|
556
|
+
const s = Object.getPrototypeOf(e);
|
|
557
|
+
if (s !== (t ? Array.prototype : Object.prototype) && !(s === null && !t) || Object.getOwnPropertySymbols(e).length) throw new w("input", "实例应为普通 JSON 对象");
|
|
558
|
+
if (t && Object.keys(e).some((r) => r !== String(Number(r)) || !Number.isSafeInteger(Number(r)) || Number(r) < 0 || Number(r) >= e.length)) throw new w("input", "实例数组不能包含额外属性");
|
|
559
|
+
if (Object.getOwnPropertyNames(e).filter((r) => !(t && r === "length")).length !== Object.keys(e).length) throw new w("input", "实例不能包含不可枚举属性");
|
|
560
|
+
}
|
|
561
|
+
function Ee(e) {
|
|
562
|
+
if (!Number.isSafeInteger(e.revision) || e.revision < 1 || typeof e.title != "string" || !e.title.trim() || e.title.length > 512) throw new w("input", "实例修订或标题无效");
|
|
563
|
+
if (typeof e.generatedAt != "string" || !Number.isFinite(Date.parse(e.generatedAt)) || new Date(e.generatedAt).toISOString() !== e.generatedAt) throw new w("input", "实例生成时间应为 ISO UTC 字符串");
|
|
564
|
+
if (!Array.isArray(e.reportIds) || !e.reportIds.length || e.reportIds.length > 100 || e.reportIds.some((t) => typeof t != "string" || !t.trim()) || new Set(e.reportIds).size !== e.reportIds.length) throw new w("input", "实例报表 ID 应非空且唯一");
|
|
565
|
+
}
|
|
566
|
+
function Je(e) {
|
|
567
|
+
return e === null || typeof e == "boolean" || typeof e == "string" || typeof e == "number" && Number.isFinite(e);
|
|
568
|
+
}
|
|
569
|
+
function se(e, t) {
|
|
570
|
+
if (!Number.isSafeInteger(t) || t < 1) throw new w("input", "实例快照字节预算应为正安全整数");
|
|
571
|
+
let s = 0, a = 0;
|
|
572
|
+
const r = /* @__PURE__ */ new Set();
|
|
573
|
+
function n(l, f) {
|
|
574
|
+
if (++s > 1e6 || f > 64) throw new w("capacity", "实例节点或嵌套深度超过预算");
|
|
575
|
+
if (typeof l == "string" && (a += l.length, a > t))
|
|
576
|
+
throw new w("capacity", "实例文本超过预算");
|
|
577
|
+
if (Je(l)) return l;
|
|
578
|
+
if (!l || typeof l != "object" || r.has(l)) throw new w("input", "实例只允许无循环的有限 JSON 值");
|
|
579
|
+
const o = Array.isArray(l);
|
|
580
|
+
je(l, o), r.add(l);
|
|
581
|
+
const u = /* @__PURE__ */ Object.create(null);
|
|
582
|
+
for (const c of Object.keys(l)) {
|
|
583
|
+
if (a += c.length, a > t) throw new w("capacity", "实例文本超过预算");
|
|
584
|
+
const d = Object.getOwnPropertyDescriptor(l, c);
|
|
585
|
+
if (d.get || d.set || ["__proto__", "constructor", "prototype"].includes(c)) throw new w("input", "实例不能包含访问器或危险键");
|
|
586
|
+
d.value !== void 0 && (u[c] = n(d.value, f + 1));
|
|
587
|
+
}
|
|
588
|
+
if (r.delete(l), o) {
|
|
589
|
+
if (Object.keys(u).length !== l.length) throw new w("input", "实例数组不能稀疏或包含额外属性");
|
|
590
|
+
return Array.from({ length: l.length }, (c, d) => u[String(d)]);
|
|
591
|
+
}
|
|
592
|
+
return u;
|
|
593
|
+
}
|
|
594
|
+
const i = JSON.stringify(n(e, 0));
|
|
595
|
+
if (new TextEncoder().encode(i).byteLength > t) throw new w("capacity", "实例快照超过单条字节预算");
|
|
596
|
+
return i;
|
|
597
|
+
}
|
|
598
|
+
function L(e, t = 8e6) {
|
|
599
|
+
const s = JSON.parse(se(e, t));
|
|
600
|
+
N(s.scope, s.id);
|
|
601
|
+
const a = /* @__PURE__ */ new Set(["scope", "id", "revision", "title", "generatedAt", "reportIds", "params", "templateRevisions", "sourceRevisions", "plan", "artifacts"]);
|
|
602
|
+
if (Object.keys(s).some((n) => !a.has(n))) throw new w("input", "实例包含未知字段");
|
|
603
|
+
Ee(s);
|
|
604
|
+
for (const n of [s.params, s.templateRevisions, s.sourceRevisions])
|
|
605
|
+
if (!n || typeof n != "object" || Array.isArray(n) || Object.values(n).some((i) => typeof i != "string")) throw new w("input", "实例参数和修订应为字符串字典");
|
|
606
|
+
if (s.reportIds.some((n) => !s.templateRevisions[n])) throw new w("input", "每张报表都应记录生成时的模板修订");
|
|
607
|
+
const r = ee(s.plan);
|
|
608
|
+
if (!r.ok) throw new w("input", `实例渲染计划无效:${r.errors[0]?.path}`);
|
|
609
|
+
return s.artifacts !== void 0 && Be(s.artifacts), s;
|
|
610
|
+
}
|
|
611
|
+
function Be(e) {
|
|
612
|
+
if (!Array.isArray(e) || e.length > 100) throw new w("input", "实例文件列表无效");
|
|
613
|
+
const t = /* @__PURE__ */ new Set();
|
|
614
|
+
for (const s of e) {
|
|
615
|
+
if (!s || typeof s.key != "string" || !s.key.trim() || s.key.length > 1024 || t.has(s.key) || !["pdf", "xlsx"].includes(s.format) || !Number.isSafeInteger(s.bytes) || s.bytes < 0 || s.sha256 !== void 0 && (typeof s.sha256 != "string" || s.sha256.length !== 64 || !/^[a-f0-9]{64}$/i.test(s.sha256))) throw new w("input", "实例文件应包含唯一存储键、格式、大小和可选 SHA256");
|
|
616
|
+
t.add(s.key);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
function De(e) {
|
|
620
|
+
const { scope: t, id: s, revision: a, title: r, generatedAt: n, reportIds: i, params: l, templateRevisions: f, sourceRevisions: o } = e;
|
|
621
|
+
return JSON.parse(JSON.stringify({ scope: t, id: s, revision: a, title: r, generatedAt: n, reportIds: i, params: l, templateRevisions: f, sourceRevisions: o }));
|
|
622
|
+
}
|
|
623
|
+
function Ce(e) {
|
|
624
|
+
const t = { maxInstances: 100, maxRevisions: 20, maxBytes: 64e6, maxSnapshotBytes: 8e6, ...e };
|
|
625
|
+
if (Object.values(t).some((s) => !Number.isSafeInteger(s) || s < 1)) throw new w("input", "实例存储预算应为正安全整数");
|
|
626
|
+
return t;
|
|
627
|
+
}
|
|
628
|
+
function Ue(e = {}) {
|
|
629
|
+
const t = Ce(e), s = /* @__PURE__ */ new Map();
|
|
630
|
+
let a = 0;
|
|
631
|
+
return {
|
|
632
|
+
read: async (r, n, i, l) => {
|
|
633
|
+
b(l), N(r, n);
|
|
634
|
+
const f = s.get(JSON.stringify([r, n])), o = f?.get(i ?? f.size);
|
|
635
|
+
return o ? L(o, t.maxSnapshotBytes) : void 0;
|
|
636
|
+
},
|
|
637
|
+
list: async (r, n = {}) => {
|
|
638
|
+
b(n.signal), N(r, "list");
|
|
639
|
+
const i = n.limit ?? 25;
|
|
640
|
+
if (!Number.isSafeInteger(i) || i < 1 || i > 100) throw new w("input", "实例每页数量应为 1–100");
|
|
641
|
+
const l = Array.from(s.values(), (f) => f.get(f.size)).filter((f) => f.scope === r && (!n.after || f.id > n.after) && (!n.reportId || f.reportIds.includes(n.reportId))).sort((f, o) => f.id < o.id ? -1 : 1).slice(0, i + 1);
|
|
642
|
+
return { items: l.slice(0, i).map(De), ...l.length > i ? { next: l[i - 1].id } : {} };
|
|
643
|
+
},
|
|
644
|
+
compareAndSwap: async (r, n, i, l, f) => {
|
|
645
|
+
b(f), N(r, n);
|
|
646
|
+
const o = L(l, t.maxSnapshotBytes);
|
|
647
|
+
if (o.scope !== r || o.id !== n || o.revision !== (i ?? 0) + 1) throw new w("input", "实例身份或修订不一致");
|
|
648
|
+
const u = JSON.stringify([r, n]), c = s.get(u) ?? /* @__PURE__ */ new Map();
|
|
649
|
+
if ((c.size || null) !== i) return !1;
|
|
650
|
+
const d = new TextEncoder().encode(JSON.stringify(o)).byteLength;
|
|
651
|
+
if (c.size >= t.maxRevisions || a + d > t.maxBytes || !c.size && s.size >= t.maxInstances) throw new w("capacity", "实例存储达到预算,请使用持久化归档策略或显式调整容量");
|
|
652
|
+
return c.set(o.revision, o), s.set(u, c), a += d, !0;
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function Me(e, t = {}) {
|
|
657
|
+
const s = t.maxSnapshotBytes ?? 8e6;
|
|
658
|
+
if (!Number.isSafeInteger(s) || s < 1) throw new w("input", "实例快照字节预算应为正安全整数");
|
|
659
|
+
return {
|
|
660
|
+
read: e.read.bind(e),
|
|
661
|
+
list: e.list.bind(e),
|
|
662
|
+
save: async (a, r) => {
|
|
663
|
+
const n = r.expectedRevision;
|
|
664
|
+
if (n !== null && (!Number.isSafeInteger(n) || n < 1 || n >= Number.MAX_SAFE_INTEGER)) throw new w("input", "实例预期修订无效");
|
|
665
|
+
const i = JSON.parse(se(a, s)), l = L({ ...i, revision: (n ?? 0) + 1 }, s);
|
|
666
|
+
if (b(r.signal), !await e.compareAndSwap(l.scope, l.id, n, l, r.signal)) throw new w("conflict", "实例已存在或已变化,请显式确认修订后保存");
|
|
667
|
+
return l;
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
function We(e, t) {
|
|
672
|
+
return I({ reportIds: e, params: t });
|
|
673
|
+
}
|
|
674
|
+
function Te(e) {
|
|
675
|
+
if (!e || typeof e != "object" || Object.getOwnPropertySymbols(e).length) throw new w("input", "生成请求应为普通对象");
|
|
676
|
+
const t = /* @__PURE__ */ Object.create(null);
|
|
677
|
+
let s;
|
|
678
|
+
const a = /* @__PURE__ */ new Set(["scope", "id", "title", "reportIds", "params", "expectedRevision", "signal"]);
|
|
679
|
+
for (const r of Object.getOwnPropertyNames(e)) {
|
|
680
|
+
const n = Object.getOwnPropertyDescriptor(e, r);
|
|
681
|
+
if (!a.has(r) || !n.enumerable || n.get || n.set) throw new w("input", "生成请求不能包含未知字段或访问器");
|
|
682
|
+
r === "signal" ? s = n.value : n.value !== void 0 && (t[r] = n.value);
|
|
621
683
|
}
|
|
684
|
+
return { signal: s, request: JSON.parse(I(t)) };
|
|
622
685
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
686
|
+
function Ze(e) {
|
|
687
|
+
const t = JSON.parse(I(e.templateRevisions)), s = Me(e.instances, { maxSnapshotBytes: e.maxSnapshotBytes });
|
|
688
|
+
return {
|
|
689
|
+
async generate(a) {
|
|
690
|
+
const { signal: r, request: n } = Te(a);
|
|
691
|
+
if (N(n.scope, n.id), n.expectedRevision !== null && (!Number.isSafeInteger(n.expectedRevision) || n.expectedRevision < 1)) throw new w("input", "实例预期修订无效");
|
|
692
|
+
const i = e.runtime.validate(n);
|
|
693
|
+
if (!i.ok) throw new Y(i.issues);
|
|
694
|
+
const l = /* @__PURE__ */ Object.create(null);
|
|
695
|
+
for (const c of n.reportIds) {
|
|
696
|
+
if (typeof t[c] != "string" || !t[c]) throw new TypeError(`报表 ${c} 缺少生成时的模板修订`);
|
|
697
|
+
l[c] = t[c];
|
|
698
|
+
}
|
|
699
|
+
if (b(r), ((await e.instances.read(n.scope, n.id, void 0, r))?.revision ?? null) !== n.expectedRevision)
|
|
700
|
+
throw new w("conflict", "实例已存在或已变化,请显式确认修订后生成");
|
|
701
|
+
const o = await e.runtime.prepare({ reportIds: n.reportIds, params: i.values, signal: r });
|
|
702
|
+
b(r);
|
|
703
|
+
const u = /* @__PURE__ */ Object.create(null);
|
|
704
|
+
for (const [c, d] of Object.entries(o.revisions)) d.revision !== void 0 && (u[c] = d.revision);
|
|
705
|
+
return s.save({
|
|
706
|
+
scope: n.scope,
|
|
707
|
+
id: n.id,
|
|
708
|
+
title: n.title,
|
|
709
|
+
reportIds: n.reportIds,
|
|
710
|
+
params: i.values,
|
|
711
|
+
templateRevisions: l,
|
|
712
|
+
sourceRevisions: u,
|
|
713
|
+
generatedAt: (e.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
714
|
+
plan: o.plan
|
|
715
|
+
}, { expectedRevision: n.expectedRevision, signal: r });
|
|
716
|
+
},
|
|
717
|
+
read: s.read,
|
|
718
|
+
list: s.list,
|
|
719
|
+
/** Instance edits are explicit snapshots; source business persistence remains the Provider.save responsibility. */
|
|
720
|
+
save: s.save
|
|
721
|
+
};
|
|
634
722
|
}
|
|
635
723
|
export {
|
|
636
|
-
w as
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
N as
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
724
|
+
w as ReportInstanceError,
|
|
725
|
+
v as ReportJobError,
|
|
726
|
+
A as ReportRuntimeError,
|
|
727
|
+
N as checkInstanceIdentity,
|
|
728
|
+
$ as checkJobIdentity,
|
|
729
|
+
D as cloneJob,
|
|
730
|
+
Ue as createMemoryReportInstanceStore,
|
|
731
|
+
et as createMemoryReportJobStore,
|
|
732
|
+
Ze as createReportGenerationService,
|
|
733
|
+
Me as createReportInstanceManager,
|
|
734
|
+
Xe as createReportJobService,
|
|
735
|
+
Se as createReportRuntime,
|
|
736
|
+
Qe as createReportTaskQueue,
|
|
737
|
+
We as reportInstanceParameterKey,
|
|
738
|
+
De as reportInstanceSummary,
|
|
739
|
+
Ge as reviewReportPublication,
|
|
740
|
+
tt as runReportBatch,
|
|
741
|
+
rt as runnableJob,
|
|
742
|
+
I as serializeJobJson,
|
|
743
|
+
st as snapshotReportBatchCases,
|
|
744
|
+
L as snapshotReportInstance,
|
|
745
|
+
nt as validateJobRecord,
|
|
746
|
+
at as validateJobTransition
|
|
649
747
|
};
|