@agile-team/mach-report 2.10.0 → 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 +6 -2
- 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 +2 -0
- package/dist/analytics.d.ts +2 -0
- package/dist/analytics.js +29 -29
- package/dist/batch-Bt3Fd27Z.cjs +1 -0
- package/dist/batch-mRqhhhjt.js +364 -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 +659 -9
- package/dist/designer.d.ts +659 -9
- package/dist/designer.js +2030 -1824
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +147 -3
- package/dist/index.d.ts +147 -3
- package/dist/index.js +639 -592
- 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-Dxyi7DOw.js → list-cell-ClFra1zS.js} +54 -40
- 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 +25 -25
- package/dist/pdf.d.cts +3 -0
- package/dist/pdf.d.ts +3 -0
- package/dist/pdf.js +677 -677
- 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 +5 -2
- package/dist/server/node.d.ts +5 -2
- package/dist/server-node.cjs +1 -1
- package/dist/server-node.js +87 -87
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +201 -2
- package/dist/server.d.ts +201 -2
- package/dist/server.js +557 -658
- 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/{validate-UUy9yP4K.js → validate-7s0yn6ii.js} +44 -44
- package/dist/validate-DsRiNw8h.cjs +1 -0
- package/dist/vue/async.d.cts +93 -4
- package/dist/vue/async.d.ts +93 -4
- package/dist/vue/index.d.cts +145 -7
- package/dist/vue/index.d.ts +145 -7
- 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/{workbook-session-B-bW5_yR.js → workbook-session-BKOTwcoq.js} +1 -1
- package/dist/{workbook-session-D7RtdNo0.cjs → workbook-session-CLYLhZWu.cjs} +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.cts +5 -2
- package/dist/worker.d.ts +5 -2
- package/dist/worker.js +1 -1
- package/dist/xlsx.cjs +3 -3
- package/dist/xlsx.d.cts +129 -2
- package/dist/xlsx.d.ts +129 -2
- package/dist/xlsx.js +336 -242
- package/package.json +1 -1
- package/dist/ExcelBindingWizard-CF7RplWm.cjs +0 -1
- package/dist/ExcelBindingWizard-qhwEderR.js +0 -842
- package/dist/ReportPreview-BE1tCHqE.js +0 -4604
- package/dist/ReportPreview-QKRKQOe3.cjs +0 -6
- package/dist/RuleEditor-BA36yIV6.js +0 -1723
- package/dist/RuleEditor-CczJ6mJm.cjs +0 -1
- package/dist/TemplateReviewPanel-CHi4Alqa.cjs +0 -1
- package/dist/TemplateReviewPanel-Dz0G5o83.js +0 -217
- package/dist/binding-preview-BWsdf_z2.cjs +0 -2
- package/dist/binding-preview-DILq0-0f.js +0 -649
- package/dist/decimal-CI1OAczk.js +0 -87
- package/dist/decimal-CQA0xJex.cjs +0 -1
- package/dist/list-cell-CyM1ZlRN.cjs +0 -1
- package/dist/matrix-BbXarwyk.js +0 -661
- package/dist/matrix-Cm65WLLP.cjs +0 -1
- package/dist/param-validation-BWNjLcN0.js +0 -116
- package/dist/param-validation-CiTxFeZ8.cjs +0 -1
- package/dist/plugin-CThk42vJ.cjs +0 -1
- package/dist/plugin-tGn7-5oF.js +0 -25
- package/dist/template-registry-CGWTLtIA.cjs +0 -1
- package/dist/template-registry-DzlQs3OF.js +0 -434
- package/dist/template-review-D1RoNCPw.cjs +0 -1
- package/dist/template-review-fnteXRng.js +0 -1473
- package/dist/validate-Bf6ccFr2.cjs +0 -1
package/dist/server-node.js
CHANGED
|
@@ -15,9 +15,9 @@ function V(e, t, n) {
|
|
|
15
15
|
e.editable !== void 0 && typeof e.editable != "boolean" && n.push({ path: `${t}.editable`, message: "编辑控制应为布尔值" }), e.valueType !== void 0 && !["text", "number", "boolean"].includes(e.valueType) && n.push({ path: `${t}.valueType`, message: "编辑类型应为 text、number 或 boolean" });
|
|
16
16
|
}
|
|
17
17
|
function G(e, t, n) {
|
|
18
|
-
V(e, t, n), e.derived !== void 0 && typeof e.derived != "boolean" && n.push({ path: `${t}.derived`, message: "派生结果标记应为布尔值" }),
|
|
18
|
+
V(e, t, n), e.indentMm !== void 0 && (typeof e.indentMm != "number" || !Number.isFinite(e.indentMm) || e.indentMm < 0) && n.push({ path: `${t}.indentMm`, message: "单元格缩进应为有限非负数" }), e.derived !== void 0 && typeof e.derived != "boolean" && n.push({ path: `${t}.derived`, message: "派生结果标记应为布尔值" }), F(e.source, `${t}.source`, n, !0), e.formula !== void 0 && typeof e.formula != "string" && n.push({ path: `${t}.formula`, message: "单元格公式应为字符串" });
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function F(e, t, n, o = !1) {
|
|
21
21
|
if (e === void 0) return;
|
|
22
22
|
if (!e || typeof e != "object" || Array.isArray(e)) {
|
|
23
23
|
n.push({ path: t, message: "业务来源应为对象" });
|
|
@@ -54,7 +54,7 @@ function Q(e, t, n) {
|
|
|
54
54
|
const o = `${t}.table`;
|
|
55
55
|
if (!N(e)) n.push({ path: o, message: "逻辑表来源应为对象" });
|
|
56
56
|
else {
|
|
57
|
-
|
|
57
|
+
F(e.source, `${o}.source`, n), (typeof e.id != "string" || !e.id.trim()) && n.push({ path: `${o}.id`, message: "逻辑表 ID 应为非空字符串" });
|
|
58
58
|
const r = e.role;
|
|
59
59
|
["header", "body", "group-header", "subtotal", "grand-total"].includes(r) || n.push({ path: `${o}.role`, message: "未知逻辑表行角色" });
|
|
60
60
|
const s = e.rowIndex;
|
|
@@ -73,15 +73,15 @@ function Y(e, t, n, o) {
|
|
|
73
73
|
n.push({ path: `${t}.grid.cells.${i}`, message: "行应为数组" });
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
s.forEach((
|
|
77
|
-
if (
|
|
76
|
+
s.forEach((m, h) => {
|
|
77
|
+
if (m == null) return;
|
|
78
78
|
const u = `${t}.grid.cells.${i}.${h}`;
|
|
79
|
-
if (!N(
|
|
79
|
+
if (!N(m)) {
|
|
80
80
|
n.push({ path: u, message: "网格单元格应为对象或 null" });
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
|
-
G(
|
|
84
|
-
|
|
83
|
+
G(m, u, n), Array.isArray(m.children) && m.children.forEach((b, k) => {
|
|
84
|
+
D(b, `${t}.grid.cells.${i}.${h}.children.${k}`, n, o);
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
});
|
|
@@ -92,7 +92,7 @@ function ee(e, t, n) {
|
|
|
92
92
|
(!N(o) || !Array.isArray(o.segments)) && n.push({ path: `${t}.richParagraphs.${r}`, message: "段落缺少 segments 数组" });
|
|
93
93
|
}) : n.push({ path: `${t}.richParagraphs`, message: "richParagraphs 应为数组" }));
|
|
94
94
|
}
|
|
95
|
-
function
|
|
95
|
+
function D(e, t, n, o = []) {
|
|
96
96
|
if (!N(e)) {
|
|
97
97
|
n.push({ path: t, message: "组件应为对象" });
|
|
98
98
|
return;
|
|
@@ -118,7 +118,7 @@ function te(e, t, n, o = []) {
|
|
|
118
118
|
(typeof r != "number" || !Number.isFinite(r) || r <= 0) && n.push({ path: `${t}.pageWidthMm`, message: `页宽非法: ${JSON.stringify(r)}` }), (typeof s != "number" || !(s > 0 && s < 5e3)) && n.push({ path: `${t}.pageHeightMm`, message: `页高非法: ${JSON.stringify(s)}` }), e.layout !== void 0 && e.layout !== "page" && e.layout !== "wide" && n.push({ path: `${t}.layout`, message: "布局应为 page 或 wide" });
|
|
119
119
|
const i = e.components;
|
|
120
120
|
Array.isArray(i) ? Array.isArray(i) && i.forEach(
|
|
121
|
-
(
|
|
121
|
+
(m, h) => D(m, `${t}.components.${h}`, n, o)
|
|
122
122
|
) : n.push({ path: `${t}.components`, message: "components 应为数组" });
|
|
123
123
|
}
|
|
124
124
|
function ne(e) {
|
|
@@ -218,12 +218,12 @@ function de(e, t) {
|
|
|
218
218
|
for (const n of ["completed", "total"]) if (e[n] !== void 0 && (typeof e[n] != "number" || !Number.isFinite(e[n]) || e[n] < 0)) return !1;
|
|
219
219
|
return e.completed === void 0 || e.total === void 0 || e.completed <= e.total;
|
|
220
220
|
}
|
|
221
|
-
let
|
|
221
|
+
let me = 0;
|
|
222
222
|
function P(e) {
|
|
223
223
|
const t = new Error("报表 Worker 任务已取消");
|
|
224
224
|
return t.name = "AbortError", Object.defineProperty(t, "cause", { value: e }), t;
|
|
225
225
|
}
|
|
226
|
-
function
|
|
226
|
+
function ye(e, t) {
|
|
227
227
|
if (!e || typeof e != "object") return;
|
|
228
228
|
const n = e;
|
|
229
229
|
return n.protocol === E && n.id === t ? n : void 0;
|
|
@@ -231,45 +231,45 @@ function me(e, t) {
|
|
|
231
231
|
function le(e, t = {}) {
|
|
232
232
|
const n = t.timeoutMs ?? 12e4;
|
|
233
233
|
if (!Number.isFinite(n) || n <= 0 || n > 2147483647) throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");
|
|
234
|
-
const o = (r, s, i,
|
|
234
|
+
const o = (r, s, i, m) => i?.aborted ? Promise.reject(P(i.reason)) : new Promise((h, u) => {
|
|
235
235
|
let b;
|
|
236
236
|
try {
|
|
237
237
|
b = e();
|
|
238
|
-
} catch (
|
|
239
|
-
u(
|
|
238
|
+
} catch (y) {
|
|
239
|
+
u(y);
|
|
240
240
|
return;
|
|
241
241
|
}
|
|
242
|
-
const
|
|
242
|
+
const k = `mach-report-${Date.now()}-${++me}`;
|
|
243
243
|
let p = !1, f = () => {
|
|
244
244
|
}, c;
|
|
245
|
-
const d = (
|
|
246
|
-
p || (p = !0, c && clearTimeout(c), f(), i?.removeEventListener("abort",
|
|
247
|
-
() =>
|
|
248
|
-
($) => u(
|
|
245
|
+
const d = (y, w) => {
|
|
246
|
+
p || (p = !0, c && clearTimeout(c), f(), i?.removeEventListener("abort", g), Promise.resolve().then(() => b.terminate()).then(
|
|
247
|
+
() => y === void 0 ? h(w) : u(y),
|
|
248
|
+
($) => u(y ?? $)
|
|
249
249
|
));
|
|
250
|
-
},
|
|
251
|
-
const
|
|
252
|
-
if (!(!
|
|
253
|
-
if ("type" in
|
|
254
|
-
const $ = "event" in
|
|
255
|
-
de($, s) ? K(
|
|
250
|
+
}, g = () => d(P(i?.reason)), A = (y) => {
|
|
251
|
+
const w = ye(y, k);
|
|
252
|
+
if (!(!w || p)) {
|
|
253
|
+
if ("type" in w && w.type === "event") {
|
|
254
|
+
const $ = "event" in w ? w.event : void 0;
|
|
255
|
+
de($, s) ? K(m, $, i) : d(new Error("报表 Worker 返回无效阶段事件"));
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
258
|
-
|
|
258
|
+
w.error && typeof w.error.name == "string" && typeof w.error.message == "string" ? d(new B(w.error)) : ie(w.result, r) && (r !== "export" || "format" in w.result && "format" in s && w.result.format === s.format) ? d(void 0, w.result) : d(new Error("报表 Worker 返回无效响应"));
|
|
259
259
|
}
|
|
260
260
|
};
|
|
261
261
|
try {
|
|
262
|
-
if (f = b.subscribe(A, (
|
|
262
|
+
if (f = b.subscribe(A, (y) => d(y ?? new Error("报表 Worker 执行失败"))), p) {
|
|
263
263
|
f();
|
|
264
264
|
return;
|
|
265
265
|
}
|
|
266
|
-
if (i?.addEventListener("abort",
|
|
266
|
+
if (i?.addEventListener("abort", g, { once: !0 }), c = setTimeout(() => d(new B({ name: "ReportRuntimeError", code: "timeout", message: `报表 Worker 执行超过 ${n}ms` })), n), i?.aborted) g();
|
|
267
267
|
else {
|
|
268
|
-
const { onEvent:
|
|
269
|
-
b.postMessage({ protocol: E, id:
|
|
268
|
+
const { onEvent: y, signal: w, ...$ } = s;
|
|
269
|
+
b.postMessage({ protocol: E, id: k, operation: r, input: $ });
|
|
270
270
|
}
|
|
271
|
-
} catch (
|
|
272
|
-
d(
|
|
271
|
+
} catch (y) {
|
|
272
|
+
d(y);
|
|
273
273
|
}
|
|
274
274
|
});
|
|
275
275
|
return { prepare: (r, s, i) => o("prepare", r, s, i), export: (r, s, i) => o("export", r, s, i) };
|
|
@@ -339,22 +339,22 @@ const he = new Uint32Array([
|
|
|
339
339
|
2756734187,
|
|
340
340
|
3204031479,
|
|
341
341
|
3329325298
|
|
342
|
-
]),
|
|
343
|
-
function
|
|
342
|
+
]), x = (e, t) => e >>> t | e << 32 - t;
|
|
343
|
+
function ge(e, t, n) {
|
|
344
344
|
const o = new DataView(e.buffer, e.byteOffset + t, 64);
|
|
345
345
|
for (let r = 0; r < 16; r++) n[r] = o.getUint32(r * 4);
|
|
346
346
|
for (let r = 16; r < 64; r++) {
|
|
347
|
-
const s = n[r - 15], i = n[r - 2],
|
|
348
|
-
n[r] = n[r - 16] +
|
|
347
|
+
const s = n[r - 15], i = n[r - 2], m = x(s, 7) ^ x(s, 18) ^ s >>> 3, h = x(i, 17) ^ x(i, 19) ^ i >>> 10;
|
|
348
|
+
n[r] = n[r - 16] + m + n[r - 7] + h;
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
|
-
function
|
|
352
|
-
let n = e[0], o = e[1], r = e[2], s = e[3], i = e[4],
|
|
351
|
+
function we(e, t) {
|
|
352
|
+
let n = e[0], o = e[1], r = e[2], s = e[3], i = e[4], m = e[5], h = e[6], u = e[7];
|
|
353
353
|
for (let b = 0; b < 64; b++) {
|
|
354
|
-
const
|
|
355
|
-
u = h, h =
|
|
354
|
+
const k = x(i, 6) ^ x(i, 11) ^ x(i, 25), p = i & m ^ ~i & h, f = u + k + p + he[b] + t[b] >>> 0, c = x(n, 2) ^ x(n, 13) ^ x(n, 22), d = n & o ^ n & r ^ o & r, g = c + d >>> 0;
|
|
355
|
+
u = h, h = m, m = i, i = s + f >>> 0, s = r, r = o, o = n, n = f + g >>> 0;
|
|
356
356
|
}
|
|
357
|
-
e[0] = e[0] + n, e[1] = e[1] + o, e[2] = e[2] + r, e[3] = e[3] + s, e[4] = e[4] + i, e[5] = e[5] +
|
|
357
|
+
e[0] = e[0] + n, e[1] = e[1] + o, e[2] = e[2] + r, e[3] = e[3] + s, e[4] = e[4] + i, e[5] = e[5] + m, e[6] = e[6] + h, e[7] = e[7] + u;
|
|
358
358
|
}
|
|
359
359
|
function be(e) {
|
|
360
360
|
const t = new Uint8Array(Math.ceil((e.byteLength + 9) / 64) * 64);
|
|
@@ -362,12 +362,12 @@ function be(e) {
|
|
|
362
362
|
const n = new DataView(t.buffer);
|
|
363
363
|
return n.setUint32(t.length - 8, Math.floor(e.byteLength / 536870912)), n.setUint32(t.length - 4, e.byteLength * 8 >>> 0), t;
|
|
364
364
|
}
|
|
365
|
-
const Ae = () => new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]),
|
|
366
|
-
async function
|
|
365
|
+
const Ae = () => new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]), xe = (e) => Array.from(e, (t) => t.toString(16).padStart(8, "0")).join("");
|
|
366
|
+
async function ke(e) {
|
|
367
367
|
const t = be(e), n = Ae(), o = new Uint32Array(64);
|
|
368
368
|
for (let r = 0; r < t.length; r += 64)
|
|
369
|
-
r > 0 && r % 262144 === 0 && await new Promise((s) => setTimeout(s, 0)),
|
|
370
|
-
return
|
|
369
|
+
r > 0 && r % 262144 === 0 && await new Promise((s) => setTimeout(s, 0)), ge(t, r, o), we(n, o);
|
|
370
|
+
return xe(n);
|
|
371
371
|
}
|
|
372
372
|
class a extends Error {
|
|
373
373
|
constructor(t, n) {
|
|
@@ -375,14 +375,14 @@ class a extends Error {
|
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
function T(e, t) {
|
|
378
|
-
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 a("input", "任务范围应非空,ID应为1–128位安全标识");
|
|
378
|
+
if (typeof e != "string" || !e.trim() || e.length > 256 || typeof t != "string" || t !== t.trim() || !/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(t)) throw new a("input", "任务范围应非空,ID应为1–128位安全标识");
|
|
379
379
|
}
|
|
380
380
|
function $e(e) {
|
|
381
381
|
const t = Array.isArray(e), n = Object.getPrototypeOf(e), o = Object.keys(e);
|
|
382
382
|
if (n !== (t ? Array.prototype : Object.prototype) && !(n === null && !t)) throw new a("input", "任务对象应为普通 JSON 对象");
|
|
383
383
|
if (Object.getOwnPropertySymbols(e).length) throw new a("input", "任务不能包含Symbol");
|
|
384
384
|
if (Object.getOwnPropertyNames(e).filter((s) => !(t && s === "length")).length !== o.length) throw new a("input", "任务不能包含不可枚举属性");
|
|
385
|
-
if (t && (o.length !== e.length || o.some((s) =>
|
|
385
|
+
if (t && (o.length !== e.length || o.some((s) => s !== String(Number(s)) || !Number.isSafeInteger(Number(s)) || Number(s) < 0 || Number(s) >= e.length))) throw new a("input", "任务数组不能稀疏或包含额外属性");
|
|
386
386
|
return o.sort();
|
|
387
387
|
}
|
|
388
388
|
function Ne(e, t) {
|
|
@@ -395,7 +395,7 @@ function S(e, t = {}) {
|
|
|
395
395
|
if (!Number.isSafeInteger(n) || n < 1 || n > 2e4 || !Number.isSafeInteger(o) || o < 1 || o > 1e6) throw new a("input", "任务JSON预算无效");
|
|
396
396
|
let r = 0, s = 0;
|
|
397
397
|
const i = /* @__PURE__ */ new Set();
|
|
398
|
-
function
|
|
398
|
+
function m(u, b) {
|
|
399
399
|
if (++r > n || b > 32) throw new a("input", "任务数据超过节点或深度预算");
|
|
400
400
|
if (typeof u == "string") {
|
|
401
401
|
if (s += u.length, s > o) throw new a("input", "任务文本超过预算");
|
|
@@ -403,16 +403,16 @@ function S(e, t = {}) {
|
|
|
403
403
|
}
|
|
404
404
|
if (u === null || typeof u == "boolean" || typeof u == "number" && Number.isFinite(u)) return u;
|
|
405
405
|
if (!u || typeof u != "object" || i.has(u)) throw new a("input", "任务只允许无循环的有限 JSON 值");
|
|
406
|
-
const
|
|
406
|
+
const k = Array.isArray(u), p = $e(u);
|
|
407
407
|
i.add(u);
|
|
408
408
|
const f = /* @__PURE__ */ Object.create(null);
|
|
409
409
|
for (const c of p) {
|
|
410
410
|
if (s += c.length, s > o) throw new a("input", "任务文本超过预算");
|
|
411
|
-
f[c] =
|
|
411
|
+
f[c] = m(Ne(u, c), b + 1);
|
|
412
412
|
}
|
|
413
|
-
return i.delete(u),
|
|
413
|
+
return i.delete(u), k ? Array.from({ length: u.length }, (c, d) => f[String(d)]) : f;
|
|
414
414
|
}
|
|
415
|
-
const h = JSON.stringify(
|
|
415
|
+
const h = JSON.stringify(m(e, 0));
|
|
416
416
|
if (h.length > o) throw new a("input", "任务序列化数据超过字符预算");
|
|
417
417
|
return h;
|
|
418
418
|
}
|
|
@@ -444,15 +444,15 @@ function Re(e = {}) {
|
|
|
444
444
|
if (!Object.values(t).every((n) => Number.isSafeInteger(n) && n > 0) || t.controlReserveBytes < 4096) throw new a("input", "任务容量应为正整数,控制状态预留至少4096字节");
|
|
445
445
|
return t;
|
|
446
446
|
}
|
|
447
|
-
function
|
|
447
|
+
function M(e) {
|
|
448
448
|
return new TextEncoder().encode(S(e)).byteLength;
|
|
449
449
|
}
|
|
450
450
|
function L(e, t) {
|
|
451
451
|
const n = { scope: e.scope, id: e.id, revision: 1, request: e.request, status: "queued", createdAt: e.createdAt, updatedAt: e.createdAt, attempt: 0 }, o = { ...e };
|
|
452
452
|
delete o.result;
|
|
453
|
-
const r = e.result === void 0 ? 0 :
|
|
453
|
+
const r = e.result === void 0 ? 0 : M(e.result);
|
|
454
454
|
if (r > t.maxResultBytes) throw new a("capacity", "任务结果超过独立预算,请保存文件引用");
|
|
455
|
-
return Math.max(
|
|
455
|
+
return Math.max(M(n) + t.controlReserveBytes, M(o)) + r;
|
|
456
456
|
}
|
|
457
457
|
function _(e) {
|
|
458
458
|
return e.status !== "queued" && e.status !== "running";
|
|
@@ -463,15 +463,15 @@ function Ee(e) {
|
|
|
463
463
|
if (![t.tombstoneRetentionMs, t.limit].every((n) => Number.isSafeInteger(n) && n > 0) || !Number.isSafeInteger(t.now + t.tombstoneRetentionMs)) throw new a("input", "幂等保留期与清理批量应为正整数");
|
|
464
464
|
return t;
|
|
465
465
|
}
|
|
466
|
-
async function
|
|
466
|
+
async function Me(e) {
|
|
467
467
|
const t = new TextEncoder().encode(S(e)), n = globalThis.crypto?.subtle;
|
|
468
|
-
if (!n) return
|
|
468
|
+
if (!n) return ke(t);
|
|
469
469
|
const o = await n.digest("SHA-256", t);
|
|
470
470
|
return Array.from(new Uint8Array(o), (r) => r.toString(16).padStart(2, "0")).join("");
|
|
471
471
|
}
|
|
472
|
-
async function
|
|
472
|
+
async function Oe(e, t) {
|
|
473
473
|
if (!_(e)) throw new a("input", "只能归档终态任务");
|
|
474
|
-
return { scope: e.scope, id: e.id, revision: e.revision, status: e.status, createdAt: e.createdAt, updatedAt: e.updatedAt, attempt: e.attempt, requestHash: await
|
|
474
|
+
return { scope: e.scope, id: e.id, revision: e.revision, status: e.status, createdAt: e.createdAt, updatedAt: e.updatedAt, attempt: e.attempt, requestHash: await Me(e.request), expiresAt: t };
|
|
475
475
|
}
|
|
476
476
|
function Ie(e) {
|
|
477
477
|
if (!e || !["completed", "failed", "cancelled"].includes(e.status) || !/^[a-f0-9]{64}$/.test(e.requestHash)) throw new a("input", "任务幂等摘要无效");
|
|
@@ -480,7 +480,7 @@ function Ie(e) {
|
|
|
480
480
|
function I(e) {
|
|
481
481
|
return e?.code;
|
|
482
482
|
}
|
|
483
|
-
function
|
|
483
|
+
function O(e, t) {
|
|
484
484
|
return W("sha256").update(JSON.stringify([e, t])).digest("hex") + ".json";
|
|
485
485
|
}
|
|
486
486
|
async function J(e) {
|
|
@@ -547,11 +547,11 @@ async function Je(e, t) {
|
|
|
547
547
|
function Be(e, t, n, o) {
|
|
548
548
|
if ("tombstone" in n) {
|
|
549
549
|
const r = n.tombstone;
|
|
550
|
-
if (Ie(r), T(r.scope, r.id),
|
|
551
|
-
const s =
|
|
550
|
+
if (Ie(r), T(r.scope, r.id), O(r.scope, r.id) !== t) throw new a("input", "持久任务摘要身份不匹配");
|
|
551
|
+
const s = M(r);
|
|
552
552
|
e.tombstoneBytes += s, e.tombstones.set(t, { value: r, bytes: s });
|
|
553
553
|
} else {
|
|
554
|
-
if (z(n, n.scope, n.id, n.revision - 1),
|
|
554
|
+
if (z(n, n.scope, n.id, n.revision - 1), O(n.scope, n.id) !== t) throw new a("input", "持久任务文件身份不匹配");
|
|
555
555
|
const r = L(n, o);
|
|
556
556
|
e.bytes += r, e.records.set(t, { record: n, bytes: r });
|
|
557
557
|
}
|
|
@@ -603,10 +603,10 @@ async function ze(e) {
|
|
|
603
603
|
throw await o.handle.close(), await l.unlink(o.file), p;
|
|
604
604
|
}
|
|
605
605
|
let s = !1, i = Promise.resolve();
|
|
606
|
-
const
|
|
606
|
+
const m = () => {
|
|
607
607
|
if (s) throw new a("closed", "持久任务存储已关闭");
|
|
608
608
|
}, h = (p) => {
|
|
609
|
-
|
|
609
|
+
m();
|
|
610
610
|
const f = i.then(async () => {
|
|
611
611
|
if (JSON.parse(await l.readFile(o.file, "utf8")).token !== o.token) throw new a("closed", "持久任务存储写入锁已失效");
|
|
612
612
|
return p();
|
|
@@ -624,26 +624,26 @@ async function ze(e) {
|
|
|
624
624
|
};
|
|
625
625
|
return {
|
|
626
626
|
read: async (p, f) => {
|
|
627
|
-
|
|
628
|
-
const c = r.records.get(
|
|
627
|
+
m(), T(p, f), await i;
|
|
628
|
+
const c = r.records.get(O(p, f));
|
|
629
629
|
return c ? j(c.record) : void 0;
|
|
630
630
|
},
|
|
631
631
|
readTombstone: async (p, f) => {
|
|
632
|
-
|
|
633
|
-
const c = r.tombstones.get(
|
|
632
|
+
m(), T(p, f), await i;
|
|
633
|
+
const c = r.tombstones.get(O(p, f));
|
|
634
634
|
return c ? j(c.value) : void 0;
|
|
635
635
|
},
|
|
636
|
-
candidates: async (p, f) => (
|
|
636
|
+
candidates: async (p, f) => (m(), await i, Array.from(r.records.values(), (c) => c.record).filter((c) => ve(c, p)).sort((c, d) => c.createdAt - d.createdAt).slice(0, f).map(j)),
|
|
637
637
|
compareAndSwap: async (p, f, c, d) => {
|
|
638
|
-
const
|
|
639
|
-
return z(
|
|
640
|
-
const A =
|
|
641
|
-
if ((
|
|
642
|
-
Se(
|
|
643
|
-
const
|
|
644
|
-
if ($ > n.maxBytes || !
|
|
645
|
-
return await u(A, S(
|
|
646
|
-
r.records.set(A, { record:
|
|
638
|
+
const g = JSON.parse(S(d));
|
|
639
|
+
return z(g, p, f, c), h(async () => {
|
|
640
|
+
const A = O(p, f), y = r.records.get(A);
|
|
641
|
+
if ((y?.record.revision ?? null) !== c || r.tombstones.has(A)) return !1;
|
|
642
|
+
Se(y?.record, g);
|
|
643
|
+
const w = L(g, n), $ = r.bytes - (y?.bytes ?? 0) + w;
|
|
644
|
+
if ($ > n.maxBytes || !y && r.records.size >= n.maxRecords) throw new a("capacity", "持久任务容量已满,请清理终态任务或扩大显式预算");
|
|
645
|
+
return await u(A, S(g), () => {
|
|
646
|
+
r.records.set(A, { record: g, bytes: w }), r.bytes = $;
|
|
647
647
|
}), !0;
|
|
648
648
|
});
|
|
649
649
|
},
|
|
@@ -651,14 +651,14 @@ async function ze(e) {
|
|
|
651
651
|
const f = Ee(p);
|
|
652
652
|
return h(async () => {
|
|
653
653
|
const c = { archived: 0, expired: 0 };
|
|
654
|
-
for (const [d,
|
|
655
|
-
|
|
656
|
-
for (const [d,
|
|
657
|
-
if (!_(
|
|
658
|
-
const A = await
|
|
659
|
-
if (r.tombstones.size >= n.maxTombstones || r.tombstoneBytes +
|
|
654
|
+
for (const [d, g] of r.tombstones)
|
|
655
|
+
g.value.expiresAt > f.now || c.expired >= f.limit || (await l.unlink(v.join(t, d)), r.tombstones.delete(d), r.tombstoneBytes -= g.bytes, c.expired++);
|
|
656
|
+
for (const [d, g] of r.records) {
|
|
657
|
+
if (!_(g.record) || g.record.updatedAt > f.terminalBefore || c.archived + c.expired >= f.limit) continue;
|
|
658
|
+
const A = await Oe(g.record, f.now + f.tombstoneRetentionMs), y = M(A);
|
|
659
|
+
if (r.tombstones.size >= n.maxTombstones || r.tombstoneBytes + y > n.maxTombstoneBytes) break;
|
|
660
660
|
await u(d, S({ tombstone: A }), () => {
|
|
661
|
-
r.tombstones.set(d, { value: A, bytes:
|
|
661
|
+
r.tombstones.set(d, { value: A, bytes: y }), r.tombstoneBytes += y, r.records.delete(d), r.bytes -= g.bytes;
|
|
662
662
|
}), c.archived++;
|
|
663
663
|
}
|
|
664
664
|
if (c.expired) {
|
package/dist/server.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var ue=Object.create;var H=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,me=Object.prototype.hasOwnProperty;var we=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of de(t))!me.call(e,n)&&n!==r&&H(e,n,{get:()=>t[n],enumerable:!(s=le(t,n))||s.enumerable});return e};var Q=(e,t,r)=>(r=e!=null?ue(fe(e)):{},we(t||!e||!e.__esModule?H(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("./template-review-D1RoNCPw.cjs"),F=require("./report-params-CjWrjPl6.cjs"),$=require("./param-validation-CiTxFeZ8.cjs"),ge=require("./validate-Bf6ccFr2.cjs"),pe=require("./dataset-BkRmwgeJ.cjs"),k=require("./task-events-DQ276fn2.cjs"),ye=require("./template-registry-CGWTLtIA.cjs");class v extends Error{constructor(t,r,s){super(r),this.code=t,this.path=s,this.name="ReportRuntimeError"}}function x(e){if(!e?.aborted)return;if(e.reason instanceof v)throw e.reason;const t=new Error("报表执行已取消");throw t.name="AbortError",Object.defineProperty(t,"cause",{value:e.reason}),t}function A(e,t,r){if(!Number.isFinite(r)||r<0)throw new v("budget",`${t} 的执行统计无效`,`$.budget.${t}`);const s=e[t];if(s!==void 0&&r>s)throw new v("budget",`${t} 超出预算 ${s}(实际 ${r})`,`$.budget.${t}`)}function he(e){for(const[t,r]of Object.entries(e)){if(r!==void 0&&(!Number.isFinite(r)||r<=0))throw new v("budget",`${t} 应为正有限数字`,`$.budget.${t}`);if(t!=="maxDurationMs"&&r!==void 0&&!Number.isSafeInteger(r))throw new v("budget",`${t} 应为正安全整数`,`$.budget.${t}`);if(t==="maxDurationMs"&&r!==void 0&&r>2147483647)throw new v("budget","maxDurationMs 不能超过 2147483647",`$.budget.${t}`)}}async function z(e,t,r){const s=new AbortController,n=()=>s.abort(e?.reason);e?.addEventListener("abort",n,{once:!0}),e?.aborted&&n();const o=Date.now(),c=t===void 0?void 0:setTimeout(()=>s.abort(new v("timeout",`报表执行超过 ${t}ms`)),t);let m;try{x(s.signal);const p=new Promise((u,i)=>{m=()=>{try{x(s.signal)}catch(d){i(d)}},s.signal.addEventListener("abort",m,{once:!0})}),a=await Promise.race([r(s.signal),p]);if(x(s.signal),t!==void 0&&Date.now()-o>t)throw new v("timeout",`报表执行超过 ${t}ms`);return a}finally{c!==void 0&&clearTimeout(c),m&&s.signal.removeEventListener("abort",m),e?.removeEventListener("abort",n)}}function ee(e,t){if(t.length===0)throw new P.ReportSourceError("config","缺少报表 ID");return t.map(r=>{if(!Object.prototype.hasOwnProperty.call(e,r))throw new P.ReportSourceError("config",`未注册报表 ${r}`);return e[r]})}function M(e){return e.grid?.cells.reduce((t,r)=>t+r.reduce((s,n)=>s+(n?1+(n.children?.reduce((o,c)=>o+M(c),0)??0):0),0),0)??0}function be(e,t,r){return e.pages.reduce((s,n)=>s+n.components.reduce((o,c)=>c.kind!=="list"?o+M(c):o+P.estimateListLayoutCells(c,t,r),0),0)}function ve(e,t=Object.keys(e)){return ee(e,t).map((r,s)=>{const n=t[s],o=F.getReportParamDefs(e,[n]);return{id:n,params:JSON.parse(JSON.stringify(o)),paramsSchema:$.reportParamsJsonSchema(o),datasetsSchema:Object.fromEntries(Object.entries(r.dataSchema??{}).map(([c,m])=>[c,pe.datasetJsonSchema(m)])),capabilities:{save:!!r.provider?.save,export:!!r.provider?.export,templates:!!r.provider?.templates}}})}function te(e,t){ee(e,t.reportIds);const r=$.validateReportParams(F.getReportParamDefs(e,t.reportIds),t.params),s=t.reportIds.flatMap(o=>$.validateReportParams(F.getReportParamDefs(e,[o]),t.params).issues),n=new Map(s.map(o=>[JSON.stringify(o),o]));return{...r,ok:n.size===0,issues:[...n.values()]}}function xe(e,t){const r=ge.validateRenderPlan(e.plan);if(!r.ok)throw new P.ReportSourceError("validate",`执行器返回无效计划:${r.errors[0]?.path}`);const s=e.plan.pages.length,n=e.plan.pages.reduce((o,c)=>o+c.components.reduce((m,p)=>m+M(p),0),0);return A(t,"maxRows",e.stats.rows),A(t,"maxPages",s),A(t,"maxCells",n),{...e,stats:{...e.stats,pages:s,cells:n}}}function W(e,t){const r=te(e.reports,t);if(!r.ok)throw new $.ReportParamValidationError(r.issues)}function X(e=[]){return e.map(({code:t,message:r,severity:s,pageIndex:n,componentIndex:o})=>({code:t,message:r,severity:s,path:`$.pages.${n}.components.${o}`}))}function re(e){const t={maxRows:1e5,maxPages:1e4,maxCells:2e6,maxOutputBytes:1e8,maxDurationMs:12e4,...e.budget};he(t);const r=async(n,o)=>{const c=Date.now();let m=0,p=0;const a=[],u={},i=Object.fromEntries(Object.entries(e.reports).map(([l,f])=>[l,{...f,pagination:{...e.pagination,...f.pagination,...o?{measurer:o}:{}},dataValidation:{...f.dataValidation,maxRows:Math.min(t.maxRows??1e5,f.dataValidation?.maxRows??1/0),maxCells:Math.min(t.maxCells??2e6,f.dataValidation?.maxCells??1/0)}}])),w=await P.createReportSource(i,{maxPages:t.maxPages,maxCells:t.maxCells,onDatasets:(l,f,h)=>{m+=Object.values(f).reduce((S,C)=>S+C.length,0),A(t,"maxRows",m),p+=be(h,f,i[l]?.pagination),A(t,"maxCells",p)}})({...n,params:n.params??{},onWarning:l=>a.push({code:"layout",message:l,severity:"warning"}),onQueryResult:(l,f)=>{Object.defineProperty(u,l,{value:{revision:f.revision,sourceToken:f.sourceToken},enumerable:!0,writable:!0}),a.push(...f.diagnostics??[])}}).catch(l=>{throw l instanceof P.ReportSourceError&&l.cause instanceof P.PaginatePageLimitError?new v("budget",l.cause.message,"$.budget.maxPages"):l instanceof P.ReportSourceError&&l.cause instanceof P.PaginateCellLimitError?new v("budget",l.cause.message,"$.budget.maxCells"):l});x(n.signal);const y=w.pages.reduce((l,f)=>l+f.components.reduce((h,S)=>h+M(S),0),0);return A(t,"maxPages",w.pages.length),A(t,"maxCells",y),{plan:w,diagnostics:a,revisions:u,stats:{rows:m,pages:w.pages.length,cells:y,durationMs:Date.now()-c}}},s=async n=>{const o=Date.now();if(n.format!=="pdf"&&n.format!=="xlsx")throw new P.ReportSourceError("config","不支持的报表导出格式");const c=n.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;x(n.signal);const m=n.pdf?.customFontFaces??(n.pdf?.customFontBytes?{regular:n.pdf.customFontBytes}:void 0),p=c&&m?c.createFontBytesMeasurer(m):void 0,a=await r(n,p);x(n.signal);const u=k.createReportTaskReporter(n),i=await u.run("encode",async()=>{let y;if(n.format==="pdf"){x(n.signal);const l=await c.renderPlanToPdf(a.plan,{...n.pdf,...p?{measurer:p}:{},fidelity:n.fidelity,signal:n.signal,onProgress:(f,h)=>u.progress("encode",f,h)});y=l.bytes,a.diagnostics.push(...X(l.diagnostics)),a.diagnostics.push(...l.fidelityWarnings.map(f=>({code:"pdf-fidelity",message:f,severity:"warning"})),...l.pageErrors.map(f=>({code:"pdf-page",message:f,severity:"error"}))),l.unsupportedTextCount&&a.diagnostics.push({code:"pdf-font",message:`${l.unsupportedTextCount} 段文本包含当前字体不支持的字符`,severity:"warning"})}else{const{renderPlanToXlsx:l}=await import("@agile-team/mach-report/xlsx");x(n.signal);const f=await l(a.plan,{...n.xlsx,fidelity:n.fidelity,signal:n.signal,onProgress:(h,S)=>u.progress("encode",h,S)});y=new Uint8Array(f.buffer),a.diagnostics.push(...X(f.diagnostics)),a.diagnostics.push(...f.warnings.map(h=>({code:"xlsx-fidelity",message:h,severity:"warning"})))}return x(n.signal),y});A(t,"maxOutputBytes",i.byteLength);const{plan:d,...w}=a;return{...w,bytes:i,format:n.format,contentType:n.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",stats:{...w.stats,durationMs:Date.now()-o,outputBytes:i.byteLength}}};return{describe:n=>ve(e.reports,n),validate:n=>te(e.reports,n),prepare:n=>z(n.signal,t.maxDurationMs,async o=>{const{signal:c,onEvent:m,...p}=n,a={...p,taskId:p.taskId??k.reportTaskId()},u=m?w=>k.notifyReportTaskEvent(m,w,o):void 0,i={...a,signal:o,onEvent:u};k.createReportTaskReporter(i).runSync("validate",()=>W(e,a));const d=e.executor?await e.executor.prepare(a,o,u):await r(i);return xe(d,t)}),export:n=>z(n.signal,t.maxDurationMs,async o=>{const{signal:c,onEvent:m,...p}=n,a={...p,taskId:p.taskId??k.reportTaskId()},u=m?w=>k.notifyReportTaskEvent(m,w,o):void 0,i={...a,signal:o,onEvent:u};if(k.createReportTaskReporter(i).runSync("validate",()=>W(e,a)),a.format!=="pdf"&&a.format!=="xlsx")throw new P.ReportSourceError("config","不支持的报表导出格式");const d=e.executor?await e.executor.export(a,o,u):await s(i);return A(t,"maxRows",d.stats.rows),A(t,"maxPages",d.stats.pages),A(t,"maxCells",d.stats.cells),A(t,"maxOutputBytes",d.bytes.byteLength),{...d,stats:{...d.stats,outputBytes:d.bytes.byteLength}}})}}function Re(e={}){const t=e.concurrency??1,r=e.maxQueued??20;if(!Number.isSafeInteger(t)||t<1||!Number.isSafeInteger(r)||r<0)throw new v("budget","队列并发应为正整数,排队上限应为非负整数");const s=[],n=new Set,o=new Set;let c=!1,m=0;const p=()=>{for(;!c&&n.size<t&&s.length;)s.shift().start()};return{get active(){return n.size},get pending(){return s.length},enqueue:(u,i={})=>{if(c)throw new v("closed","任务队列已关闭");if(x(i.signal),n.size>=t&&s.length>=r)throw new v("queue-full","报表任务队列已满");const d=i.id??`report-${++m}`;if(o.has(d))throw new v("queue-full","任务 ID 正在执行或排队");const w=new AbortController;let y="queued",l,f,h,S;const C=new Promise((b,E)=>{h=b,S=E}),U=()=>{i.signal?.removeEventListener("abort",_),o.delete(d)},B=b=>{if(y!=="queued"&&y!=="running")return;const E=y==="queued";y="cancelled",w.abort(b);try{x(w.signal)}catch(T){S(T)}if(E){const T=s.indexOf(j);T>=0&&s.splice(T,1),U(),p()}},_=()=>B(i.signal?.reason),V=(b,E)=>{y==="running"&&(!Number.isFinite(b)||b<0||E!==void 0&&(!Number.isFinite(E)||E<b)||(l={completed:b,...E===void 0?{}:{total:E}}))},ce=b=>{y!=="running"||w.signal.aborted||(f={...b,taskId:d},b.completed!==void 0&&V(b.completed,b.total),k.notifyReportTaskEvent(i.onEvent,f,w.signal))},j={cancel:B,start:()=>{y==="queued"&&(y="running",n.add(j),Promise.resolve().then(()=>(x(w.signal),u({taskId:d,signal:w.signal,reportProgress:V,onEvent:ce}))).then(b=>{y==="running"&&(y="completed",h(b))},b=>{y==="running"&&(y="failed",S(b))}).finally(()=>{n.delete(j),U(),p()}))}};return o.add(d),i.signal?.addEventListener("abort",_,{once:!0}),i.signal?.aborted?B(i.signal.reason):n.size<t?j.start():s.push(j),{id:d,get status(){return y},get progress(){return l},get event(){return f},result:C,cancel:B}},close:(u={})=>{c=!0;for(const i of[...s])i.cancel(new v("closed","任务队列已关闭"));if(u.cancelRunning)for(const i of n)i.cancel(new v("closed","任务队列已关闭"))}}}const Se=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),O=(e,t)=>e>>>t|e<<32-t;function Ae(e,t,r){const s=new DataView(e.buffer,e.byteOffset+t,64);for(let n=0;n<16;n++)r[n]=s.getUint32(n*4);for(let n=16;n<64;n++){const o=r[n-15],c=r[n-2],m=O(o,7)^O(o,18)^o>>>3,p=O(c,17)^O(c,19)^c>>>10;r[n]=r[n-16]+m+r[n-7]+p}}function Pe(e,t){let r=e[0],s=e[1],n=e[2],o=e[3],c=e[4],m=e[5],p=e[6],a=e[7];for(let u=0;u<64;u++){const i=O(c,6)^O(c,11)^O(c,25),d=c&m^~c&p,w=a+i+d+Se[u]+t[u]>>>0,y=O(r,2)^O(r,13)^O(r,22),l=r&s^r&n^s&n,f=y+l>>>0;a=p,p=m,m=c,c=o+w>>>0,o=n,n=s,s=r,r=w+f>>>0}e[0]=e[0]+r,e[1]=e[1]+s,e[2]=e[2]+n,e[3]=e[3]+o,e[4]=e[4]+c,e[5]=e[5]+m,e[6]=e[6]+p,e[7]=e[7]+a}function Oe(e){const t=new Uint8Array(Math.ceil((e.byteLength+9)/64)*64);t.set(e),t[e.byteLength]=128;const r=new DataView(t.buffer);return r.setUint32(t.length-8,Math.floor(e.byteLength/536870912)),r.setUint32(t.length-4,e.byteLength*8>>>0),t}const Ee=()=>new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),qe=e=>Array.from(e,t=>t.toString(16).padStart(8,"0")).join("");async function ke(e){const t=Oe(e),r=Ee(),s=new Uint32Array(64);for(let n=0;n<t.length;n+=64)n>0&&n%262144===0&&await new Promise(o=>setTimeout(o,0)),Ae(t,n,s),Pe(r,s);return qe(r)}function Ne(e={}){const t={maxRecords:e.maxRecords??1e4,maxBytes:e.maxBytes??67108864,maxResultBytes:e.maxResultBytes??262144,controlReserveBytes:e.controlReserveBytes??4096,maxTombstones:e.maxTombstones??1e4,maxTombstoneBytes:e.maxTombstoneBytes??16777216};if(!Object.values(t).every(r=>Number.isSafeInteger(r)&&r>0)||t.controlReserveBytes<4096)throw new g("input","任务容量应为正整数,控制状态预留至少4096字节");return t}function N(e){return new TextEncoder().encode(R(e)).byteLength}function L(e,t){const r={scope:e.scope,id:e.id,revision:1,request:e.request,status:"queued",createdAt:e.createdAt,updatedAt:e.createdAt,attempt:0},s={...e};delete s.result;const n=e.result===void 0?0:N(e.result);if(n>t.maxResultBytes)throw new g("capacity","任务结果超过独立预算,请保存文件引用");return Math.max(N(r)+t.controlReserveBytes,N(s))+n}function ne(e){return e.status!=="queued"&&e.status!=="running"}function je(e){const t={...e,tombstoneRetentionMs:e.tombstoneRetentionMs??6048e5,limit:e.limit??100};if(![t.now,t.terminalBefore].every(r=>Number.isSafeInteger(r)&&r>=0)||t.terminalBefore>t.now)throw new g("input","终态清理时间应为不超过当前时间的非负整数");if(![t.tombstoneRetentionMs,t.limit].every(r=>Number.isSafeInteger(r)&&r>0)||!Number.isSafeInteger(t.now+t.tombstoneRetentionMs))throw new g("input","幂等保留期与清理批量应为正整数");return t}async function se(e){const t=new TextEncoder().encode(R(e)),r=globalThis.crypto?.subtle;if(!r)return ke(t);const s=await r.digest("SHA-256",t);return Array.from(new Uint8Array(s),n=>n.toString(16).padStart(2,"0")).join("")}async function Ie(e,t){if(!ne(e))throw new g("input","只能归档终态任务");return{scope:e.scope,id:e.id,revision:e.revision,status:e.status,createdAt:e.createdAt,updatedAt:e.updatedAt,attempt:e.attempt,requestHash:await se(e.request),expiresAt:t}}class g extends Error{constructor(t,r){super(r),this.code=t,this.name="ReportJobError"}}function I(e,t){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 g("input","任务范围应非空,ID应为1–128位安全标识")}function Je(e){const t=Array.isArray(e),r=Object.getPrototypeOf(e),s=Object.keys(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t))throw new g("input","任务对象应为普通 JSON 对象");if(Object.getOwnPropertySymbols(e).length)throw new g("input","任务不能包含Symbol");if(Object.getOwnPropertyNames(e).filter(o=>!(t&&o==="length")).length!==s.length)throw new g("input","任务不能包含不可枚举属性");if(t&&(s.length!==e.length||s.some(o=>!/^(0|[1-9]\d*)$/.test(o)||Number(o)>=e.length)))throw new g("input","任务数组不能稀疏或包含额外属性");return s.sort()}function Be(e,t){const r=Object.getOwnPropertyDescriptor(e,t);if(["__proto__","prototype","constructor"].includes(t)||r.get||r.set)throw new g("input","任务不能包含危险键或访问器");return r.value}function R(e,t={}){const r=t.maxNodes??2e4,s=t.maxCharacters??1e6;if(!Number.isSafeInteger(r)||r<1||r>2e4||!Number.isSafeInteger(s)||s<1||s>1e6)throw new g("input","任务JSON预算无效");let n=0,o=0;const c=new Set;function m(a,u){if(++n>r||u>32)throw new g("input","任务数据超过节点或深度预算");if(typeof a=="string"){if(o+=a.length,o>s)throw new g("input","任务文本超过预算");return a}if(a===null||typeof a=="boolean"||typeof a=="number"&&Number.isFinite(a))return a;if(!a||typeof a!="object"||c.has(a))throw new g("input","任务只允许无循环的有限 JSON 值");const i=Array.isArray(a),d=Je(a);c.add(a);const w=Object.create(null);for(const y of d){if(o+=y.length,o>s)throw new g("input","任务文本超过预算");w[y]=m(Be(a,y),u+1)}return c.delete(a),i?Array.from({length:a.length},(y,l)=>w[String(l)]):w}const p=JSON.stringify(m(e,0));if(p.length>s)throw new g("input","任务序列化数据超过字符预算");return p}function q(e){return JSON.parse(JSON.stringify(e))}function ae(e,t,r,s){if(I(t,r),e.scope!==t||e.id!==r||e.revision!==(s??0)+1||!Number.isSafeInteger(e.revision))throw new g("input","任务身份或修订不匹配");if(![e.createdAt,e.updatedAt,e.attempt].every(n=>Number.isSafeInteger(n)&&n>=0)||!["queued","running","completed","failed","cancelled"].includes(e.status))throw new g("input","任务状态无效");if(e.lease&&(!e.lease.owner||!Number.isSafeInteger(e.lease.expiresAt)))throw new g("input","任务租约无效");if(!e.request||typeof e.request.kind!="string"||!e.request.kind.trim()||e.request.kind.length>128)throw new g("input","任务类型无效");R(e.request.payload,{maxNodes:19e3,maxCharacters:75e4}),R(e)}function oe(e,t){if(e&&(e.createdAt!==t.createdAt||R(e.request)!==R(t.request)))throw new g("input","任务创建时间与请求不可变更,请使用新任务ID")}function ie(e,t){return e.status==="queued"||e.status==="running"&&(e.lease?.expiresAt??0)<=t}function Te(e={}){const t=new Map,r=new Map,s=Ne(e);let n=0,o=0,c=Promise.resolve();const m=(a,u)=>JSON.stringify([a,u]),p=a=>{const u=c.then(a);return c=u.then(()=>{},()=>{}),u};return{read:async(a,u)=>{await c;const i=t.get(m(a,u));return i?q(i):void 0},readTombstone:async(a,u)=>{await c;const i=r.get(m(a,u));return i?q(i):void 0},candidates:async(a,u)=>(await c,Array.from(t.values()).filter(i=>ie(i,a)).sort((i,d)=>i.createdAt-d.createdAt).slice(0,u).map(q)),compareAndSwap:async(a,u,i,d)=>{ae(d,a,u,i);const w=q(d);return p(async()=>{const y=m(a,u),l=t.get(y);if((l?.revision??null)!==i||r.has(y))return!1;oe(l,w);const f=n-(l?L(l,s):0)+L(w,s);if(f>s.maxBytes||!l&&t.size>=s.maxRecords)throw new g("capacity","任务容量已满,请清理终态任务或扩大显式预算");return t.set(y,w),n=f,!0})},prune:async a=>{const u=je(a);return p(async()=>{const i={archived:0,expired:0};for(const[d,w]of r)w.expiresAt>u.now||i.expired>=u.limit||(r.delete(d),o-=N(w),i.expired++);for(const[d,w]of t){if(!ne(w)||w.updatedAt>u.terminalBefore||i.archived+i.expired>=u.limit)continue;const y=await Ie(w,u.now+u.tombstoneRetentionMs),l=N(y);if(r.size>=s.maxTombstones||o+l>s.maxTombstoneBytes)break;r.set(d,y),o+=l,t.delete(d),n-=L(w,s),i.archived++}return i})}}}function $e(e){let t,r;const s=new Promise((n,o)=>{t=n,r=o});return s.catch(()=>{}),{progress:e,promise:s,resolve:t,reject:r}}function Z(e){const t=Promise.reject(e);return t.catch(()=>{}),t}function De(e,t){let r,s,n=!0,o;function c(a){o??=a??new Error("任务心跳更新失败"),s?.reject(o),s=void 0,t(o)}function m(a){const u=Promise.resolve().then(()=>e(a?.progress)).then(()=>a?.resolve(),i=>{a?.reject(i),c(i)}).finally(()=>{r=void 0;const i=s;s=void 0,i&&o===void 0&&m(i)});r=u,u.catch(i=>{c(i)})}function p(a){if(!n)return Z(new g("closed","任务进度上报已结束"));if(o!==void 0)return Z(o);s?s.progress=a:s=$e(a);const u=s;return r||(s=void 0,m(u)),u.promise}return{progress:p,pulse(){n&&!r&&o===void 0&&m()},async finish(){for(n=!1;r;)await r;if(o!==void 0)throw o}}}class K extends g{constructor(){super("capacity","任务结果超过独立预算,请保存文件引用")}}function Me(e){const t=e.concurrency??1,r=e.leaseMs??3e4,s=e.heartbeatMs??1e4,n=e.maxResultBytes??256*1024;if(![t,r,s,n].every(c=>Number.isSafeInteger(c)&&c>0)||s*2>r)throw new g("input","并发、租约、心跳应为正整数,租约至少为心跳的两倍");if(s>2147483647)throw new g("input","心跳间隔超过平台定时器上限(2147483647毫秒)");return{concurrency:t,leaseMs:r,heartbeatMs:s,maxResultBytes:n,now:()=>{const c=(e.now??Date.now)();if(!Number.isSafeInteger(c)||c<0)throw new g("input","任务时钟应返回非负整数毫秒");return c}}}async function D(e,t,r){I(t,r);const s=await e.read(t,r);if(!s)throw new g("missing","报表任务不存在");return s}async function J(e,t,r,s=[]){const n={...t,...r,revision:t.revision+1};for(const o of s)delete n[o];if(!await e.compareAndSwap(t.scope,t.id,t.revision,n))throw new g("conflict","报表任务已被其他请求更新");return q(n)}async function Ce(e,t,r,s){if(!t.trim()||t.length>128)throw new g("input","workerId应为1–128位标识");for(const n of await e.store.candidates(s,100)){const o=n.cancelRequested?{...n,revision:n.revision+1,status:"cancelled",updatedAt:s}:{...n,revision:n.revision+1,status:"running",attempt:n.attempt+1,updatedAt:s,lease:{owner:t,expiresAt:s+r}};if(o.status==="cancelled"&&delete o.lease,await e.store.compareAndSwap(n.scope,n.id,n.revision,o))return o}}function G(e,t,r,s){return e.status==="running"&&e.attempt===s&&e.lease?.owner===t&&e.lease.expiresAt>r}async function Le(e,t,r,s){const{scope:n,id:o}=r,c=r.lease.owner;let m;const p=De(async f=>{const h=await D(e.store,n,o),S=t.now();if(!G(h,c,S,r.attempt))throw new g("lease","报表任务租约已失效");if(h.cancelRequested){s.abort(new g("closed","任务已请求取消"));return}await J(e.store,h,{updatedAt:S,lease:{owner:c,expiresAt:S+t.leaseMs},...f?{progress:f}:{}})},f=>{m=f,s.abort(f)}),a=(f,h)=>!Number.isFinite(f)||f<0||h!==void 0&&(!Number.isFinite(h)||h<f)?Promise.reject(new g("input","任务进度无效")):p.progress({completed:f,...h===void 0?{}:{total:h}}),u=setInterval(()=>{p.pulse()},t.heartbeatMs);let i,d;try{const f=Object.prototype.hasOwnProperty.call(e.handlers,r.request.kind)?e.handlers[r.request.kind]:void 0;if(!f)throw new g("input","报表任务处理器未注册");if(!s.signal.aborted){const h=await f(q(r.request.payload),{scope:n,taskId:o,signal:s.signal,reportProgress:a});if(i=JSON.parse(R(h)),N(i)>t.maxResultBytes)throw new K}}catch(f){d=f??new Error("报表任务执行失败")}finally{clearInterval(u),await p.finish().catch(()=>{})}const w=await D(e.store,n,o),y=t.now();if(!G(w,c,y,r.attempt))throw new g("lease","任务租约已失效,迟到结果不会写回");const l={...w,updatedAt:y};delete l.lease,d??=m,w.cancelRequested||s.signal.aborted&&m===void 0?l.status="cancelled":d!==void 0?(l.status="failed",l.error={code:d instanceof K?"result-budget":d instanceof g?d.code:"execution",message:d instanceof Error?d.message.slice(0,500):"报表任务执行失败"}):(l.status="completed",l.result=i);try{R(l)}catch{delete l.result,l.status="failed",l.error={code:"result-budget",message:"任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"}}return Fe(e.store,w,l)}async function Fe(e,t,r){try{return await J(e,t,r,["lease"])}catch(s){if(!(s instanceof g)||s.code!=="capacity"||r.status!=="completed")throw s;return delete r.result,r.status="failed",r.error={code:"result-budget",message:"任务结果超过存储剩余预算,请保存文件引用而非文件内容"},J(e,t,r,["lease","result"])}}async function Y(e,t,r,s){const n=await e.readTombstone?.(t,r);if(n){if(n.requestHash!==await se(s))throw new g("conflict","相同任务ID不能提交不同内容(幂等保留期内)");return{scope:t,id:r,revision:n.revision,request:q(s),status:n.status,createdAt:n.createdAt,updatedAt:n.updatedAt,attempt:n.attempt,archived:!0}}}function ze(e){e={...e,handlers:{...e.handlers}};const t=Me(e),r=new Set,s=new Set;let n=!1,o=0;const c=(a,u)=>(I(a,u),e.store.read(a,u));return{submit:async a=>{if(a={...a},I(a.scope,a.id),!Object.prototype.hasOwnProperty.call(e.handlers,a.kind)||typeof e.handlers[a.kind]!="function")throw new g("input","报表任务处理器未注册");const u={kind:a.kind,payload:JSON.parse(R(a.payload,{maxNodes:19e3,maxCharacters:75e4}))},i=await c(a.scope,a.id);if(i){if(R(i.request)!==R(u))throw new g("conflict","相同任务ID不能提交不同内容");return i}const d=await Y(e.store,a.scope,a.id,u);if(d)return d;const w=t.now(),y={scope:a.scope,id:a.id,revision:1,request:u,status:"queued",createdAt:w,updatedAt:w,attempt:0};if(!await e.store.compareAndSwap(a.scope,a.id,null,y)){const l=await c(a.scope,a.id);if(l&&R(l.request)===R(u))return l;const f=await Y(e.store,a.scope,a.id,u);if(f)return f;throw new g("conflict","报表任务提交发生冲突")}return q(y)},get:c,runNext:a=>{if(n)return Promise.reject(new g("closed","报表任务服务已关闭"));if(o>=t.concurrency)return Promise.reject(new g("capacity","报表任务执行槽位已满"));o++;const u=new AbortController;r.add(u);const i=(async()=>{try{const d=await Ce(e,a,t.leaseMs,t.now());return d?.status==="running"?await Le(e,t,d,u):d}finally{o--,r.delete(u)}})();return s.add(i),i.then(()=>s.delete(i),()=>s.delete(i)),i},get active(){return o},cancel:async(a,u)=>{const i=await D(e.store,a,u);return i.status!=="queued"&&i.status!=="running"?i:J(e.store,i,{updatedAt:t.now(),...i.status==="queued"?{status:"cancelled"}:{cancelRequested:!0}})},retry:async(a,u,i)=>{const d=await D(e.store,a,u);if(d.revision!==i||d.status!=="failed")throw new g("conflict","仅可重试当前修订的失败任务");const w={...d,status:"queued",updatedAt:t.now()};return delete w.error,delete w.progress,J(e.store,d,w,["error","progress"])},prune:async a=>{if(!e.store.prune||!e.store.readTombstone)throw new g("input","当前任务适配器未实现可选终态保留能力");return e.store.prune({...a,now:t.now()})},close:async()=>{n=!0;for(const a of r)a.abort(new g("closed","任务服务正在关闭"));await Promise.allSettled([...s])}}}async function Ue(e,t,r,s,n){const o=re({reports:{sample:{template:r,datasets:e.datasets}},budget:{maxRows:s.maxSampleRows??1e3,maxPages:s.maxPages??100,maxCells:s.maxCells??25e4,maxOutputBytes:s.maxOutputBytes??2e7,maxDurationMs:s.maxDurationMs??3e4}});try{const{result:c,digest:m}=await z(s.signal,s.maxDurationMs??3e4,async p=>{const a=await o.export({reportIds:["sample"],params:e.params,format:t,signal:p,fidelity:s.strictOutputs?"strict":"warn",pdf:s.pdf,xlsx:s.xlsx}),u=await s.digest?.(a.bytes);return x(p),await s.onArtifact?.(e.name,a),x(p),{result:a,digest:u}});n.artifacts.push({fixture:e.name,format:t,bytes:c.bytes.byteLength,pages:c.stats.pages,...m?{digest:m}:{}}),n.issues.push(...c.diagnostics.map(p=>({code:"output",severity:s.strictOutputs||p.severity==="error"?"error":"warning",path:"$.template",fixture:e.name,message:`${t}: ${p.message}`})))}catch(c){x(s.signal),n.issues.push({code:"output",severity:"error",path:"$.template",fixture:e.name,message:`${t}: ${c instanceof Error?c.message:String(c)}`})}}async function _e(e,t={}){x(t.signal);const r={...P.reviewReportTemplate(e,t),artifacts:[]};if(!r.ok)return r;const s=ye.parseReportTemplate(e).template,n=[...new Set(t.formats??["pdf","xlsx"])];if(!n.length||n.some(o=>o!=="pdf"&&o!=="xlsx"))return r.issues.push({code:"output",severity:"error",path:"$.formats",message:"真实文件验收应至少选择PDF/XLSX之一"}),r.ok=!1,r;for(const o of t.fixtures??[])for(const c of n)x(t.signal),!(c!=="pdf"&&c!=="xlsx")&&await Ue(o,c,s,t,r);return r.ok=r.issues.every(o=>o.severity!=="error"),r}exports.ReportJobError=g;exports.ReportRuntimeError=v;exports.checkJobIdentity=I;exports.cloneJob=q;exports.createMemoryReportJobStore=Te;exports.createReportJobService=ze;exports.createReportRuntime=re;exports.createReportTaskQueue=Re;exports.reviewReportPublication=_e;exports.runnableJob=ie;exports.serializeJobJson=R;exports.validateJobRecord=ae;exports.validateJobTransition=oe;
|
|
1
|
+
"use strict";var te=Object.create;var C=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var ae=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of se(t))!oe.call(e,r)&&r!==s&&C(e,r,{get:()=>t[r],enumerable:!(o=re(t,r))||o.enumerable});return e};var z=(e,t,s)=>(s=e!=null?te(ne(e)):{},ae(t||!e||!e.__esModule?C(s,"default",{value:e,enumerable:!0}):s,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("./template-review-BXp2oyqg.cjs"),M=require("./report-params-SJfhKgaX.cjs"),O=require("./param-validation-DCK039V1.cjs"),a=require("./batch-Bt3Fd27Z.cjs"),H=require("./validate-DsRiNw8h.cjs"),S=require("./task-events-DQ276fn2.cjs"),ie=require("./tree-BX380Rr7.cjs"),ce=require("./template-registry-ukBGlm8N.cjs");function X(e,t){if(t.length===0)throw new x.ReportSourceError("config","缺少报表 ID");return t.map(s=>{if(!Object.prototype.hasOwnProperty.call(e,s))throw new x.ReportSourceError("config",`未注册报表 ${s}`);return e[s]})}function B(e){return e.grid?.cells.reduce((t,s)=>t+s.reduce((o,r)=>o+(r?1+(r.children?.reduce((n,c)=>n+B(c),0)??0):0),0),0)??0}function le(e,t,s){return e.pages.reduce((o,r)=>o+r.components.reduce((n,c)=>c.kind!=="list"?n+B(c):n+x.estimateListLayoutCells(c,t,s),0),0)}function ue(e,t=Object.keys(e)){return X(e,t).map((s,o)=>{const r=t[o],n=M.getReportParamDefs(e,[r]);return{id:r,params:JSON.parse(JSON.stringify(n)),paramsSchema:O.reportParamsJsonSchema(n),datasetsSchema:Object.fromEntries(Object.entries(s.dataSchema??{}).map(([c,u])=>[c,x.templateDatasetJsonSchema(typeof s.template=="function"?void 0:s.template,c,u)])),capabilities:{save:!!s.provider?.save,export:!!s.provider?.export,templates:!!s.provider?.templates}}})}function G(e,t){X(e,t.reportIds);const s=O.validateReportParams(M.getReportParamDefs(e,t.reportIds),t.params),o=t.reportIds.flatMap(n=>O.validateReportParams(M.getReportParamDefs(e,[n]),t.params).issues),r=new Map(o.map(n=>[JSON.stringify(n),n]));return{...s,ok:r.size===0,issues:[...r.values()]}}function de(e,t){const s=H.validateRenderPlan(e.plan);if(!s.ok)throw new x.ReportSourceError("validate",`执行器返回无效计划:${s.errors[0]?.path}`);const o=e.plan.pages.length,r=e.plan.pages.reduce((n,c)=>n+c.components.reduce((u,f)=>u+B(f),0),0);return a.assertBudget(t,"maxRows",e.stats.rows),a.assertBudget(t,"maxPages",o),a.assertBudget(t,"maxCells",r),{...e,stats:{...e.stats,pages:o,cells:r}}}function $(e,t){const s=G(e.reports,t);if(!s.ok)throw new O.ReportParamValidationError(s.issues)}function L(e=[]){return e.map(({code:t,message:s,severity:o,pageIndex:r,componentIndex:n})=>({code:t,message:s,severity:o,path:`$.pages.${r}.components.${n}`}))}function K(e){const t={maxRows:1e5,maxPages:1e4,maxCells:2e6,maxOutputBytes:1e8,maxDurationMs:12e4,...e.budget};a.validateBudget(t);const s=async(r,n)=>{const c=Date.now();let u=0,f=0;const i=[],d={},l=Object.fromEntries(Object.entries(e.reports).map(([g,w])=>[g,{...w,pagination:{...e.pagination,...w.pagination,...n?{measurer:n}:{}},dataValidation:{...w.dataValidation,maxRows:Math.min(t.maxRows??1e5,w.dataValidation?.maxRows??1/0),maxCells:Math.min(t.maxCells??2e6,w.dataValidation?.maxCells??1/0)}}])),h=await x.createReportSource(l,{maxPages:t.maxPages,maxCells:t.maxCells,onDatasets:(g,w,b)=>{try{u+=x.templateDatasetRowCount(b,w,{maxRows:t.maxRows,signal:r.signal})}catch(R){throw R instanceof ie.TreeRowLimitError?new a.ReportRuntimeError("budget",R.message,"$.budget.maxRows"):R}a.assertBudget(t,"maxRows",u),f+=le(b,w,l[g]?.pagination),a.assertBudget(t,"maxCells",f)}})({...r,params:r.params??{},onWarning:g=>i.push({code:"layout",message:g,severity:"warning"}),onQueryResult:(g,w)=>{Object.defineProperty(d,g,{value:{revision:w.revision,sourceToken:w.sourceToken},enumerable:!0,writable:!0}),i.push(...w.diagnostics??[])}}).catch(g=>{throw g instanceof x.ReportSourceError&&g.cause instanceof x.PaginatePageLimitError?new a.ReportRuntimeError("budget",g.cause.message,"$.budget.maxPages"):g instanceof x.ReportSourceError&&g.cause instanceof x.PaginateCellLimitError?new a.ReportRuntimeError("budget",g.cause.message,"$.budget.maxCells"):g});a.throwIfAborted(r.signal);const y=h.pages.reduce((g,w)=>g+w.components.reduce((b,R)=>b+B(R),0),0);return a.assertBudget(t,"maxPages",h.pages.length),a.assertBudget(t,"maxCells",y),{plan:h,diagnostics:i,revisions:d,stats:{rows:u,pages:h.pages.length,cells:y,durationMs:Date.now()-c}}},o=async r=>{const n=Date.now();if(r.format!=="pdf"&&r.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const c=r.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;a.throwIfAborted(r.signal);const u=r.pdf?.customFontFaces??(r.pdf?.customFontBytes?{regular:r.pdf.customFontBytes}:void 0),f=c&&u?c.createFontBytesMeasurer(u):void 0,i=await s(r,f);a.throwIfAborted(r.signal);const d=S.createReportTaskReporter(r),l=await d.run("encode",async()=>{let y;if(r.format==="pdf"){a.throwIfAborted(r.signal);const g=await c.renderPlanToPdf(i.plan,{...r.pdf,...f?{measurer:f}:{},fidelity:r.fidelity,signal:r.signal,onProgress:(w,b)=>d.progress("encode",w,b)});y=g.bytes,i.diagnostics.push(...L(g.diagnostics)),i.diagnostics.push(...g.fidelityWarnings.map(w=>({code:"pdf-fidelity",message:w,severity:"warning"})),...g.pageErrors.map(w=>({code:"pdf-page",message:w,severity:"error"}))),g.unsupportedTextCount&&i.diagnostics.push({code:"pdf-font",message:`${g.unsupportedTextCount} 段文本包含当前字体不支持的字符`,severity:"warning"})}else{const{renderPlanToXlsx:g}=await import("@agile-team/mach-report/xlsx");a.throwIfAborted(r.signal);const w=await g(i.plan,{...r.xlsx,fidelity:r.fidelity,signal:r.signal,onProgress:(b,R)=>d.progress("encode",b,R)});y=new Uint8Array(w.buffer),i.diagnostics.push(...L(w.diagnostics)),i.diagnostics.push(...w.warnings.map(b=>({code:"xlsx-fidelity",message:b,severity:"warning"})))}return a.throwIfAborted(r.signal),y});a.assertBudget(t,"maxOutputBytes",l.byteLength);const{plan:p,...h}=i;return{...h,bytes:l,format:r.format,contentType:r.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",stats:{...h.stats,durationMs:Date.now()-n,outputBytes:l.byteLength}}};return{describe:r=>ue(e.reports,r),validate:r=>G(e.reports,r),prepare:r=>a.controlled(r.signal,t.maxDurationMs,async n=>{const{signal:c,onEvent:u,...f}=r,i={...f,taskId:f.taskId??S.reportTaskId()},d=u?h=>S.notifyReportTaskEvent(u,h,n):void 0,l={...i,signal:n,onEvent:d};S.createReportTaskReporter(l).runSync("validate",()=>$(e,i));const p=e.executor?await e.executor.prepare(i,n,d):await s(l);return de(p,t)}),export:r=>a.controlled(r.signal,t.maxDurationMs,async n=>{const{signal:c,onEvent:u,...f}=r,i={...f,taskId:f.taskId??S.reportTaskId()},d=u?h=>S.notifyReportTaskEvent(u,h,n):void 0,l={...i,signal:n,onEvent:d};if(S.createReportTaskReporter(l).runSync("validate",()=>$(e,i)),i.format!=="pdf"&&i.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const p=e.executor?await e.executor.export(i,n,d):await o(l);return a.assertBudget(t,"maxRows",p.stats.rows),a.assertBudget(t,"maxPages",p.stats.pages),a.assertBudget(t,"maxCells",p.stats.cells),a.assertBudget(t,"maxOutputBytes",p.bytes.byteLength),{...p,stats:{...p.stats,outputBytes:p.bytes.byteLength}}})}}function pe(e={}){const t=e.concurrency??1,s=e.maxQueued??20;if(!Number.isSafeInteger(t)||t<1||!Number.isSafeInteger(s)||s<0)throw new a.ReportRuntimeError("budget","队列并发应为正整数,排队上限应为非负整数");const o=[],r=new Set,n=new Set;let c=!1,u=0;const f=()=>{for(;!c&&r.size<t&&o.length;)o.shift().start()};return{get active(){return r.size},get pending(){return o.length},enqueue:(d,l={})=>{if(c)throw new a.ReportRuntimeError("closed","任务队列已关闭");if(a.throwIfAborted(l.signal),r.size>=t&&o.length>=s)throw new a.ReportRuntimeError("queue-full","报表任务队列已满");const p=l.id??`report-${++u}`;if(n.has(p))throw new a.ReportRuntimeError("queue-full","任务 ID 正在执行或排队");const h=new AbortController;let y="queued",g,w,b,R;const Y=new Promise((v,I)=>{b=v,R=I}),q=()=>{l.signal?.removeEventListener("abort",D),n.delete(p)},P=v=>{if(y!=="queued"&&y!=="running")return;const I=y==="queued";y="cancelled",h.abort(v);try{a.throwIfAborted(h.signal)}catch(k){R(k)}if(I){const k=o.indexOf(E);k>=0&&o.splice(k,1),q(),f()}},D=()=>P(l.signal?.reason),T=(v,I)=>{y==="running"&&(!Number.isFinite(v)||v<0||I!==void 0&&(!Number.isFinite(I)||I<v)||(g={completed:v,...I===void 0?{}:{total:I}}))},ee=v=>{y!=="running"||h.signal.aborted||(w={...v,taskId:p},v.completed!==void 0&&T(v.completed,v.total),S.notifyReportTaskEvent(l.onEvent,w,h.signal))},E={cancel:P,start:()=>{y==="queued"&&(y="running",r.add(E),Promise.resolve().then(()=>(a.throwIfAborted(h.signal),d({taskId:p,signal:h.signal,reportProgress:T,onEvent:ee}))).then(v=>{y==="running"&&(y="completed",b(v))},v=>{y==="running"&&(y="failed",R(v))}).finally(()=>{r.delete(E),q(),f()}))}};return n.add(p),l.signal?.addEventListener("abort",D,{once:!0}),l.signal?.aborted?P(l.signal.reason):r.size<t?E.start():o.push(E),{id:p,get status(){return y},get progress(){return g},get event(){return w},result:Y,cancel:P}},close:(d={})=>{c=!0;for(const l of[...o])l.cancel(new a.ReportRuntimeError("closed","任务队列已关闭"));if(d.cancelRunning)for(const l of r)l.cancel(new a.ReportRuntimeError("closed","任务队列已关闭"))}}}function fe(e){let t,s;const o=new Promise((r,n)=>{t=r,s=n});return o.catch(()=>{}),{progress:e,promise:o,resolve:t,reject:s}}function F(e){const t=Promise.reject(e);return t.catch(()=>{}),t}function we(e,t){let s,o,r=!0,n;function c(i){n??=i??new Error("任务心跳更新失败"),o?.reject(n),o=void 0,t(n)}function u(i){const d=Promise.resolve().then(()=>e(i?.progress)).then(()=>i?.resolve(),l=>{i?.reject(l),c(l)}).finally(()=>{s=void 0;const l=o;o=void 0,l&&n===void 0&&u(l)});s=d,d.catch(l=>{c(l)})}function f(i){if(!r)return F(new a.ReportJobError("closed","任务进度上报已结束"));if(n!==void 0)return F(n);o?o.progress=i:o=fe(i);const d=o;return s||(o=void 0,u(d)),d.promise}return{progress:f,pulse(){r&&!s&&n===void 0&&u()},async finish(){for(r=!1;s;)await s;if(n!==void 0)throw n}}}class _ extends a.ReportJobError{constructor(){super("capacity","任务结果超过独立预算,请保存文件引用")}}function ge(e){const t=e.concurrency??1,s=e.leaseMs??3e4,o=e.heartbeatMs??1e4,r=e.maxResultBytes??256*1024;if(![t,s,o,r].every(c=>Number.isSafeInteger(c)&&c>0)||o*2>s)throw new a.ReportJobError("input","并发、租约、心跳应为正整数,租约至少为心跳的两倍");if(o>2147483647)throw new a.ReportJobError("input","心跳间隔超过平台定时器上限(2147483647毫秒)");return{concurrency:t,leaseMs:s,heartbeatMs:o,maxResultBytes:r,now:()=>{const c=(e.now??Date.now)();if(!Number.isSafeInteger(c)||c<0)throw new a.ReportJobError("input","任务时钟应返回非负整数毫秒");return c}}}async function N(e,t,s){a.checkJobIdentity(t,s);const o=await e.read(t,s);if(!o)throw new a.ReportJobError("missing","报表任务不存在");return o}async function A(e,t,s,o=[]){const r={...t,...s,revision:t.revision+1};for(const n of o)delete r[n];if(!await e.compareAndSwap(t.scope,t.id,t.revision,r))throw new a.ReportJobError("conflict","报表任务已被其他请求更新");return a.cloneJob(r)}async function me(e,t,s,o){if(!t.trim()||t.length>128)throw new a.ReportJobError("input","workerId应为1–128位标识");for(const r of await e.store.candidates(o,100)){const n=r.cancelRequested?{...r,revision:r.revision+1,status:"cancelled",updatedAt:o}:{...r,revision:r.revision+1,status:"running",attempt:r.attempt+1,updatedAt:o,lease:{owner:t,expiresAt:o+s}};if(n.status==="cancelled"&&delete n.lease,await e.store.compareAndSwap(r.scope,r.id,r.revision,n))return n}}function V(e,t,s,o){return e.status==="running"&&e.attempt===o&&e.lease?.owner===t&&e.lease.expiresAt>s}async function he(e,t,s,o){const{scope:r,id:n}=s,c=s.lease.owner;let u;const f=we(async w=>{const b=await N(e.store,r,n),R=t.now();if(!V(b,c,R,s.attempt))throw new a.ReportJobError("lease","报表任务租约已失效");if(b.cancelRequested){o.abort(new a.ReportJobError("closed","任务已请求取消"));return}await A(e.store,b,{updatedAt:R,lease:{owner:c,expiresAt:R+t.leaseMs},...w?{progress:w}:{}})},w=>{u=w,o.abort(w)}),i=(w,b)=>!Number.isFinite(w)||w<0||b!==void 0&&(!Number.isFinite(b)||b<w)?Promise.reject(new a.ReportJobError("input","任务进度无效")):f.progress({completed:w,...b===void 0?{}:{total:b}}),d=setInterval(()=>{f.pulse()},t.heartbeatMs);let l,p;try{const w=Object.prototype.hasOwnProperty.call(e.handlers,s.request.kind)?e.handlers[s.request.kind]:void 0;if(!w)throw new a.ReportJobError("input","报表任务处理器未注册");if(!o.signal.aborted){const b=await w(a.cloneJob(s.request.payload),{scope:r,taskId:n,signal:o.signal,reportProgress:i});if(l=JSON.parse(a.serializeJobJson(b)),a.jobByteLength(l)>t.maxResultBytes)throw new _}}catch(w){p=w??new Error("报表任务执行失败")}finally{clearInterval(d),await f.finish().catch(()=>{})}const h=await N(e.store,r,n),y=t.now();if(!V(h,c,y,s.attempt))throw new a.ReportJobError("lease","任务租约已失效,迟到结果不会写回");const g={...h,updatedAt:y};delete g.lease,p??=u,h.cancelRequested||o.signal.aborted&&u===void 0?g.status="cancelled":p!==void 0?(g.status="failed",g.error={code:p instanceof _?"result-budget":p instanceof a.ReportJobError?p.code:"execution",message:p instanceof Error?p.message.slice(0,500):"报表任务执行失败"}):(g.status="completed",g.result=l);try{a.serializeJobJson(g)}catch{delete g.result,g.status="failed",g.error={code:"result-budget",message:"任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"}}return ye(e.store,h,g)}async function ye(e,t,s){try{return await A(e,t,s,["lease"])}catch(o){if(!(o instanceof a.ReportJobError)||o.code!=="capacity"||s.status!=="completed")throw o;return delete s.result,s.status="failed",s.error={code:"result-budget",message:"任务结果超过存储剩余预算,请保存文件引用而非文件内容"},A(e,t,s,["lease","result"])}}async function Q(e,t,s,o){const r=await e.readTombstone?.(t,s);if(r){if(r.requestHash!==await a.jobRequestHash(o))throw new a.ReportJobError("conflict","相同任务ID不能提交不同内容(幂等保留期内)");return{scope:t,id:s,revision:r.revision,request:a.cloneJob(o),status:r.status,createdAt:r.createdAt,updatedAt:r.updatedAt,attempt:r.attempt,archived:!0}}}function be(e){e={...e,handlers:{...e.handlers}};const t=ge(e),s=new Set,o=new Set;let r=!1,n=0;const c=(i,d)=>(a.checkJobIdentity(i,d),e.store.read(i,d));return{submit:async i=>{if(i={...i},a.checkJobIdentity(i.scope,i.id),!Object.prototype.hasOwnProperty.call(e.handlers,i.kind)||typeof e.handlers[i.kind]!="function")throw new a.ReportJobError("input","报表任务处理器未注册");const d={kind:i.kind,payload:JSON.parse(a.serializeJobJson(i.payload,{maxNodes:19e3,maxCharacters:75e4}))},l=await c(i.scope,i.id);if(l){if(a.serializeJobJson(l.request)!==a.serializeJobJson(d))throw new a.ReportJobError("conflict","相同任务ID不能提交不同内容");return l}const p=await Q(e.store,i.scope,i.id,d);if(p)return p;const h=t.now(),y={scope:i.scope,id:i.id,revision:1,request:d,status:"queued",createdAt:h,updatedAt:h,attempt:0};if(!await e.store.compareAndSwap(i.scope,i.id,null,y)){const g=await c(i.scope,i.id);if(g&&a.serializeJobJson(g.request)===a.serializeJobJson(d))return g;const w=await Q(e.store,i.scope,i.id,d);if(w)return w;throw new a.ReportJobError("conflict","报表任务提交发生冲突")}return a.cloneJob(y)},get:c,runNext:i=>{if(r)return Promise.reject(new a.ReportJobError("closed","报表任务服务已关闭"));if(n>=t.concurrency)return Promise.reject(new a.ReportJobError("capacity","报表任务执行槽位已满"));n++;const d=new AbortController;s.add(d);const l=(async()=>{try{const p=await me(e,i,t.leaseMs,t.now());return p?.status==="running"?await he(e,t,p,d):p}finally{n--,s.delete(d)}})();return o.add(l),l.then(()=>o.delete(l),()=>o.delete(l)),l},get active(){return n},cancel:async(i,d)=>{const l=await N(e.store,i,d);return l.status!=="queued"&&l.status!=="running"?l:A(e.store,l,{updatedAt:t.now(),...l.status==="queued"?{status:"cancelled"}:{cancelRequested:!0}})},retry:async(i,d,l)=>{const p=await N(e.store,i,d);if(p.revision!==l||p.status!=="failed")throw new a.ReportJobError("conflict","仅可重试当前修订的失败任务");const h={...p,status:"queued",updatedAt:t.now()};return delete h.error,delete h.progress,A(e.store,p,h,["error","progress"])},prune:async i=>{if(!e.store.prune||!e.store.readTombstone)throw new a.ReportJobError("input","当前任务适配器未实现可选终态保留能力");return e.store.prune({...i,now:t.now()})},close:async()=>{r=!0;for(const i of s)i.abort(new a.ReportJobError("closed","任务服务正在关闭"));await Promise.allSettled([...o])}}}async function ve(e,t,s,o,r){const n=K({reports:{sample:{template:s,datasets:e.datasets}},budget:{maxRows:o.maxSampleRows??1e3,maxPages:o.maxPages??100,maxCells:o.maxCells??25e4,maxOutputBytes:o.maxOutputBytes??2e7,maxDurationMs:o.maxDurationMs??3e4}});try{const{result:c,digest:u}=await a.controlled(o.signal,o.maxDurationMs??3e4,async f=>{const i=await n.export({reportIds:["sample"],params:e.params,format:t,signal:f,fidelity:o.strictOutputs?"strict":"warn",pdf:o.pdf,xlsx:o.xlsx}),d=await o.digest?.(i.bytes);return a.throwIfAborted(f),await o.onArtifact?.(e.name,i),a.throwIfAborted(f),{result:i,digest:d}});r.artifacts.push({fixture:e.name,format:t,bytes:c.bytes.byteLength,pages:c.stats.pages,...u?{digest:u}:{}}),r.issues.push(...c.diagnostics.map(f=>({code:"output",severity:o.strictOutputs||f.severity==="error"?"error":"warning",path:"$.template",fixture:e.name,message:`${t}: ${f.message}`})))}catch(c){a.throwIfAborted(o.signal),r.issues.push({code:"output",severity:"error",path:"$.template",fixture:e.name,message:`${t}: ${c instanceof Error?c.message:String(c)}`})}}async function Re(e,t={}){a.throwIfAborted(t.signal);const s={...x.reviewReportTemplate(e,t),artifacts:[]};if(!s.ok)return s;const o=ce.parseReportTemplate(e).template,r=[...new Set(t.formats??["pdf","xlsx"])];if(!r.length||r.some(n=>n!=="pdf"&&n!=="xlsx"))return s.issues.push({code:"output",severity:"error",path:"$.formats",message:"真实文件验收应至少选择PDF/XLSX之一"}),s.ok=!1,s;for(const n of t.fixtures??[])for(const c of r)a.throwIfAborted(t.signal),!(c!=="pdf"&&c!=="xlsx")&&await ve(n,c,o,t,s);return s.ok=s.issues.every(n=>n.severity!=="error"),s}class m extends Error{constructor(t,s){super(s),this.code=t,this.name="ReportInstanceError"}}function J(e,t){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 m("input","实例范围应非空,ID 应为安全标识")}function xe(e,t){const s=Object.getPrototypeOf(e);if(s!==(t?Array.prototype:Object.prototype)&&!(s===null&&!t)||Object.getOwnPropertySymbols(e).length)throw new m("input","实例应为普通 JSON 对象");if(t&&Object.keys(e).some(r=>r!==String(Number(r))||!Number.isSafeInteger(Number(r))||Number(r)<0||Number(r)>=e.length))throw new m("input","实例数组不能包含额外属性");if(Object.getOwnPropertyNames(e).filter(r=>!(t&&r==="length")).length!==Object.keys(e).length)throw new m("input","实例不能包含不可枚举属性")}function Ie(e){if(!Number.isSafeInteger(e.revision)||e.revision<1||typeof e.title!="string"||!e.title.trim()||e.title.length>512)throw new m("input","实例修订或标题无效");if(typeof e.generatedAt!="string"||!Number.isFinite(Date.parse(e.generatedAt))||new Date(e.generatedAt).toISOString()!==e.generatedAt)throw new m("input","实例生成时间应为 ISO UTC 字符串");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 m("input","实例报表 ID 应非空且唯一")}function Se(e){return e===null||typeof e=="boolean"||typeof e=="string"||typeof e=="number"&&Number.isFinite(e)}function U(e,t){if(!Number.isSafeInteger(t)||t<1)throw new m("input","实例快照字节预算应为正安全整数");let s=0,o=0;const r=new Set;function n(u,f){if(++s>1e6||f>64)throw new m("capacity","实例节点或嵌套深度超过预算");if(typeof u=="string"&&(o+=u.length,o>t))throw new m("capacity","实例文本超过预算");if(Se(u))return u;if(!u||typeof u!="object"||r.has(u))throw new m("input","实例只允许无循环的有限 JSON 值");const i=Array.isArray(u);xe(u,i),r.add(u);const d=Object.create(null);for(const l of Object.keys(u)){if(o+=l.length,o>t)throw new m("capacity","实例文本超过预算");const p=Object.getOwnPropertyDescriptor(u,l);if(p.get||p.set||["__proto__","constructor","prototype"].includes(l))throw new m("input","实例不能包含访问器或危险键");p.value!==void 0&&(d[l]=n(p.value,f+1))}if(r.delete(u),i){if(Object.keys(d).length!==u.length)throw new m("input","实例数组不能稀疏或包含额外属性");return Array.from({length:u.length},(l,p)=>d[String(p)])}return d}const c=JSON.stringify(n(e,0));if(new TextEncoder().encode(c).byteLength>t)throw new m("capacity","实例快照超过单条字节预算");return c}function j(e,t=8e6){const s=JSON.parse(U(e,t));J(s.scope,s.id);const o=new Set(["scope","id","revision","title","generatedAt","reportIds","params","templateRevisions","sourceRevisions","plan","artifacts"]);if(Object.keys(s).some(n=>!o.has(n)))throw new m("input","实例包含未知字段");Ie(s);for(const n of[s.params,s.templateRevisions,s.sourceRevisions])if(!n||typeof n!="object"||Array.isArray(n)||Object.values(n).some(c=>typeof c!="string"))throw new m("input","实例参数和修订应为字符串字典");if(s.reportIds.some(n=>!s.templateRevisions[n]))throw new m("input","每张报表都应记录生成时的模板修订");const r=H.validateRenderPlan(s.plan);if(!r.ok)throw new m("input",`实例渲染计划无效:${r.errors[0]?.path}`);return s.artifacts!==void 0&&Je(s.artifacts),s}function Je(e){if(!Array.isArray(e)||e.length>100)throw new m("input","实例文件列表无效");const t=new Set;for(const s of e){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 m("input","实例文件应包含唯一存储键、格式、大小和可选 SHA256");t.add(s.key)}}function W(e){const{scope:t,id:s,revision:o,title:r,generatedAt:n,reportIds:c,params:u,templateRevisions:f,sourceRevisions:i}=e;return JSON.parse(JSON.stringify({scope:t,id:s,revision:o,title:r,generatedAt:n,reportIds:c,params:u,templateRevisions:f,sourceRevisions:i}))}function Ee(e){const t={maxInstances:100,maxRevisions:20,maxBytes:64e6,maxSnapshotBytes:8e6,...e};if(Object.values(t).some(s=>!Number.isSafeInteger(s)||s<1))throw new m("input","实例存储预算应为正安全整数");return t}function Oe(e={}){const t=Ee(e),s=new Map;let o=0;return{read:async(r,n,c,u)=>{a.throwIfAborted(u),J(r,n);const f=s.get(JSON.stringify([r,n])),i=f?.get(c??f.size);return i?j(i,t.maxSnapshotBytes):void 0},list:async(r,n={})=>{a.throwIfAborted(n.signal),J(r,"list");const c=n.limit??25;if(!Number.isSafeInteger(c)||c<1||c>100)throw new m("input","实例每页数量应为 1–100");const u=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,i)=>f.id<i.id?-1:1).slice(0,c+1);return{items:u.slice(0,c).map(W),...u.length>c?{next:u[c-1].id}:{}}},compareAndSwap:async(r,n,c,u,f)=>{a.throwIfAborted(f),J(r,n);const i=j(u,t.maxSnapshotBytes);if(i.scope!==r||i.id!==n||i.revision!==(c??0)+1)throw new m("input","实例身份或修订不一致");const d=JSON.stringify([r,n]),l=s.get(d)??new Map;if((l.size||null)!==c)return!1;const p=new TextEncoder().encode(JSON.stringify(i)).byteLength;if(l.size>=t.maxRevisions||o+p>t.maxBytes||!l.size&&s.size>=t.maxInstances)throw new m("capacity","实例存储达到预算,请使用持久化归档策略或显式调整容量");return l.set(i.revision,i),s.set(d,l),o+=p,!0}}}function Z(e,t={}){const s=t.maxSnapshotBytes??8e6;if(!Number.isSafeInteger(s)||s<1)throw new m("input","实例快照字节预算应为正安全整数");return{read:e.read.bind(e),list:e.list.bind(e),save:async(o,r)=>{const n=r.expectedRevision;if(n!==null&&(!Number.isSafeInteger(n)||n<1||n>=Number.MAX_SAFE_INTEGER))throw new m("input","实例预期修订无效");const c=JSON.parse(U(o,s)),u=j({...c,revision:(n??0)+1},s);if(a.throwIfAborted(r.signal),!await e.compareAndSwap(u.scope,u.id,n,u,r.signal))throw new m("conflict","实例已存在或已变化,请显式确认修订后保存");return u}}}function Ae(e,t){return a.serializeJobJson({reportIds:e,params:t})}function Pe(e){if(!e||typeof e!="object"||Object.getOwnPropertySymbols(e).length)throw new m("input","生成请求应为普通对象");const t=Object.create(null);let s;const o=new Set(["scope","id","title","reportIds","params","expectedRevision","signal"]);for(const r of Object.getOwnPropertyNames(e)){const n=Object.getOwnPropertyDescriptor(e,r);if(!o.has(r)||!n.enumerable||n.get||n.set)throw new m("input","生成请求不能包含未知字段或访问器");r==="signal"?s=n.value:n.value!==void 0&&(t[r]=n.value)}return{signal:s,request:JSON.parse(a.serializeJobJson(t))}}function ke(e){const t=JSON.parse(a.serializeJobJson(e.templateRevisions)),s=Z(e.instances,{maxSnapshotBytes:e.maxSnapshotBytes});return{async generate(o){const{signal:r,request:n}=Pe(o);if(J(n.scope,n.id),n.expectedRevision!==null&&(!Number.isSafeInteger(n.expectedRevision)||n.expectedRevision<1))throw new m("input","实例预期修订无效");const c=e.runtime.validate(n);if(!c.ok)throw new O.ReportParamValidationError(c.issues);const u=Object.create(null);for(const l of n.reportIds){if(typeof t[l]!="string"||!t[l])throw new TypeError(`报表 ${l} 缺少生成时的模板修订`);u[l]=t[l]}if(a.throwIfAborted(r),((await e.instances.read(n.scope,n.id,void 0,r))?.revision??null)!==n.expectedRevision)throw new m("conflict","实例已存在或已变化,请显式确认修订后生成");const i=await e.runtime.prepare({reportIds:n.reportIds,params:c.values,signal:r});a.throwIfAborted(r);const d=Object.create(null);for(const[l,p]of Object.entries(i.revisions))p.revision!==void 0&&(d[l]=p.revision);return s.save({scope:n.scope,id:n.id,title:n.title,reportIds:n.reportIds,params:c.values,templateRevisions:u,sourceRevisions:d,generatedAt:(e.now?.()??new Date).toISOString(),plan:i.plan},{expectedRevision:n.expectedRevision,signal:r})},read:s.read,list:s.list,save:s.save}}exports.ReportJobError=a.ReportJobError;exports.ReportRuntimeError=a.ReportRuntimeError;exports.checkJobIdentity=a.checkJobIdentity;exports.cloneJob=a.cloneJob;exports.createMemoryReportJobStore=a.createMemoryReportJobStore;exports.runReportBatch=a.runReportBatch;exports.runnableJob=a.runnableJob;exports.serializeJobJson=a.serializeJobJson;exports.snapshotReportBatchCases=a.snapshotReportBatchCases;exports.validateJobRecord=a.validateJobRecord;exports.validateJobTransition=a.validateJobTransition;exports.ReportInstanceError=m;exports.checkInstanceIdentity=J;exports.createMemoryReportInstanceStore=Oe;exports.createReportGenerationService=ke;exports.createReportInstanceManager=Z;exports.createReportJobService=be;exports.createReportRuntime=K;exports.createReportTaskQueue=pe;exports.reportInstanceParameterKey=Ae;exports.reportInstanceSummary=W;exports.reviewReportPublication=Re;exports.snapshotReportInstance=j;
|