@agile-team/mach-report 2.12.0 → 2.13.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 +19 -3
- package/dist/{ReportBatchPanel-B5ClP9tm.js → ReportBatchPanel-CW2HV9I8.js} +1 -1
- package/dist/{ReportBatchPanel-Dc-SDkYA.cjs → ReportBatchPanel-Fp1ePFag.cjs} +1 -1
- package/dist/ReportPreview-BN6fk7Wz.cjs +6 -0
- package/dist/ReportPreview-D2Jkyh1U.js +4243 -0
- package/dist/config-Bb7RiIO5.cjs +1 -0
- package/dist/{config-B612mw0x.js → config-XVwG87IA.js} +4 -0
- package/dist/designer.cjs +2 -2
- package/dist/designer.d.cts +16 -0
- package/dist/designer.d.ts +16 -0
- package/dist/designer.js +2014 -1968
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +386 -367
- package/dist/{plugin-Cd5G2QQn.js → plugin-D4wizDXB.js} +1 -1
- package/dist/{plugin-BDTU4D94.cjs → plugin-DzS6pxTA.cjs} +1 -1
- package/dist/server.cjs +1 -1
- package/dist/server.js +22 -22
- package/dist/style.css +1 -1
- package/dist/template-review-DGwWOoCv.cjs +2 -0
- package/dist/{template-review-BzpcI-tR.js → template-review-PgEe_Wr9.js} +447 -427
- package/dist/vue/async.d.cts +4 -0
- package/dist/vue/async.d.ts +4 -0
- package/dist/vue/index.d.cts +7 -2
- package/dist/vue/index.d.ts +7 -2
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +5 -5
- package/package.json +1 -1
- package/dist/ReportPreview-DWXROHBP.cjs +0 -6
- package/dist/ReportPreview-DiNXhQI0.js +0 -4138
- package/dist/config-BRoLo2oj.cjs +0 -1
- package/dist/template-review-BfCC8Ng9.cjs +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineAsyncComponent as c, computed as m } from "vue";
|
|
2
2
|
import { b as i, c as l, a as d } from "./injection-keys-e85udZCp.js";
|
|
3
3
|
import { g as s } from "./report-params-B44imUd4.js";
|
|
4
|
-
const p = c(() => import("./ReportPreview-
|
|
4
|
+
const p = c(() => import("./ReportPreview-D2Jkyh1U.js").then((r) => r.o)), _ = {
|
|
5
5
|
install(r, e = {}) {
|
|
6
6
|
let t = e.fetcher;
|
|
7
7
|
if (!t && e.reports) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var R=Object.create;var f=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var m=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of P(e))!p.call(r,o)&&o!==t&&f(r,o,{get:()=>e[o],enumerable:!(n=u(e,o))||n.enumerable});return r};var E=(r,e,t)=>(t=r!=null?R(d(r)):{},m(e||!r||!r.__esModule?f(t,"default",{value:r,enumerable:!0}):t,r));const l=require("vue"),i=require("./injection-keys-Db_DyLkm.cjs"),h=require("./report-params-SJfhKgaX.cjs"),s=l.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-
|
|
1
|
+
"use strict";var R=Object.create;var f=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var m=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of P(e))!p.call(r,o)&&o!==t&&f(r,o,{get:()=>e[o],enumerable:!(n=u(e,o))||n.enumerable});return r};var E=(r,e,t)=>(t=r!=null?R(d(r)):{},m(e||!r||!r.__esModule?f(t,"default",{value:r,enumerable:!0}):t,r));const l=require("vue"),i=require("./injection-keys-Db_DyLkm.cjs"),h=require("./report-params-SJfhKgaX.cjs"),s=l.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-BN6fk7Wz.cjs")).then(r=>r.ReportPreview$1)),v={install(r,e={}){let t=e.fetcher;if(!t&&e.reports){const n=e.reports;let o;t=async c=>(o??=import("@agile-team/mach-report").then(({createReportSource:a})=>a(n)),(await o)(c)),t.getParamDefs=c=>h.getReportParamDefs(n,c)}t&&r.provide(i.MACH_REPORT_FETCHER_KEY,t),e.pdfExporter&&r.provide(i.MACH_REPORT_PDF_EXPORTER_KEY,e.pdfExporter),r.provide(i.MACH_REPORT_CONFIG_KEY,l.computed(()=>{if(e.pdfFontUrl===void 0)return e.config??null;const n=e.config??{defaults:{},presets:{}};return{...n,defaults:{...n.defaults,pdfFontUrl:e.pdfFontUrl}}})),e.globalComponent!==!1&&!r.component("MachReportPreview")&&r.component("MachReportPreview",s)}};exports.MachReportPreview=s;exports.machReportPlugin=v;
|
package/dist/server.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var se=Object.create;var $=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var ce=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ae(t))!ie.call(e,s)&&s!==r&&$(e,s,{get:()=>t[s],enumerable:!(a=ne(t,s))||a.enumerable});return e};var F=(e,t,r)=>(r=e!=null?se(oe(e)):{},ce(t||!e||!e.__esModule?$(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("./template-review-BfCC8Ng9.cjs"),T=require("./report-params-SJfhKgaX.cjs"),P=require("./param-validation-DCK039V1.cjs"),o=require("./batch-Bt3Fd27Z.cjs"),G=require("./validate-BJ5HIWY8.cjs"),S=require("./task-events-DQ276fn2.cjs"),le=require("./tree-BX380Rr7.cjs"),ue=require("./assets-C2U-e-Sz.cjs"),de=require("./template-registry-D3SjENi6.cjs");function K(e,t){if(t.length===0)throw new x.ReportSourceError("config","缺少报表 ID");return t.map(r=>{if(!Object.prototype.hasOwnProperty.call(e,r))throw new x.ReportSourceError("config",`未注册报表 ${r}`);return e[r]})}function q(e){return e.grid?.cells.reduce((t,r)=>t+r.reduce((a,s)=>a+(s?1+(s.children?.reduce((n,c)=>n+q(c),0)??0):0),0),0)??0}function fe(e,t,r){return e.pages.reduce((a,s)=>a+s.components.reduce((n,c)=>c.kind!=="list"?n+q(c):n+x.estimateListLayoutCells(c,t,r),0),0)}function pe(e,t=Object.keys(e)){return K(e,t).map((r,a)=>{const s=t[a],n=T.getReportParamDefs(e,[s]);return{id:s,params:JSON.parse(JSON.stringify(n)),paramsSchema:P.reportParamsJsonSchema(n),datasetsSchema:Object.fromEntries(Object.entries(r.dataSchema??{}).map(([c,u])=>[c,x.templateDatasetJsonSchema(typeof r.template=="function"?void 0:r.template,c,u)])),capabilities:{save:!!r.provider?.save,export:!!r.provider?.export,templates:!!r.provider?.templates}}})}function U(e,t){K(e,t.reportIds);const r=P.validateReportParams(T.getReportParamDefs(e,t.reportIds),t.params),a=t.reportIds.flatMap(n=>P.validateReportParams(T.getReportParamDefs(e,[n]),t.params).issues),s=new Map(a.map(n=>[JSON.stringify(n),n]));return{...r,ok:s.size===0,issues:[...s.values()]}}function ge(e,t){const r=G.validateRenderPlan(e.plan);if(!r.ok)throw new x.ReportSourceError("validate",`执行器返回无效计划:${r.errors[0]?.path}`);const a=e.plan.pages.length,s=e.plan.pages.reduce((n,c)=>n+c.components.reduce((u,p)=>u+q(p),0),0);return o.assertBudget(t,"maxRows",e.stats.rows),o.assertBudget(t,"maxPages",a),o.assertBudget(t,"maxCells",s),{...e,stats:{...e.stats,pages:a,cells:s}}}function L(e,t){const r=U(e.reports,t);if(!r.ok)throw new P.ReportParamValidationError(r.issues)}function M(e=[]){return e.map(({code:t,message:r,severity:a,pageIndex:s,componentIndex:n})=>({code:t,message:r,severity:a,path:`$.pages.${s}.components.${n}`}))}function W(e){const t={maxRows:1e5,maxPages:1e4,maxCells:2e6,maxOutputBytes:1e8,maxDurationMs:12e4,...e.budget};o.validateBudget(t);const r=async(s,n)=>{const c=Date.now();let u=0,p=0;const i=[],f={},l=Object.fromEntries(Object.entries(e.reports).map(([g,v])=>[g,{...v,pagination:{...e.pagination,...v.pagination,...n?{measurer:n}:{}},dataValidation:{...v.dataValidation,maxRows:Math.min(t.maxRows??1e5,v.dataValidation?.maxRows??1/0),maxCells:Math.min(t.maxCells??2e6,v.dataValidation?.maxCells??1/0)}}])),y=await x.createReportSource(l,{maxPages:t.maxPages,maxCells:t.maxCells,onDatasets:(g,v,E)=>{try{u+=x.templateDatasetRowCount(E,v,{maxRows:t.maxRows,signal:s.signal})}catch(J){throw J instanceof le.TreeRowLimitError?new o.ReportRuntimeError("budget",J.message,"$.budget.maxRows"):J}o.assertBudget(t,"maxRows",u),p+=fe(E,v,l[g]?.pagination),o.assertBudget(t,"maxCells",p)}})({...s,params:s.params??{},onWarning:g=>i.push({code:"layout",message:g,severity:"warning"}),onQueryResult:(g,v)=>{Object.defineProperty(f,g,{value:{revision:v.revision,sourceToken:v.sourceToken},enumerable:!0,writable:!0}),i.push(...v.diagnostics??[])}}).catch(g=>{throw g instanceof x.ReportSourceError&&g.cause instanceof x.PaginatePageLimitError?new o.ReportRuntimeError("budget",g.cause.message,"$.budget.maxPages"):g instanceof x.ReportSourceError&&g.cause instanceof x.PaginateCellLimitError?new o.ReportRuntimeError("budget",g.cause.message,"$.budget.maxCells"):g});o.throwIfAborted(s.signal);const b=e.assets?await S.createReportTaskReporter(s).run("assets",()=>ue.resolvePlanAssets(y,{...e.assets,signal:s.signal})):{plan:y,diagnostics:[]},h=b.plan;i.push(...M(b.diagnostics));const w=h.pages.reduce((g,v)=>g+v.components.reduce((E,J)=>E+q(J),0),0);return o.assertBudget(t,"maxPages",h.pages.length),o.assertBudget(t,"maxCells",w),{plan:h,diagnostics:i,revisions:f,stats:{rows:u,pages:h.pages.length,cells:w,durationMs:Date.now()-c}}},a=async s=>{const n=Date.now();if(s.format!=="pdf"&&s.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const c=s.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;o.throwIfAborted(s.signal);const u=s.pdf?.customFontFaces??(s.pdf?.customFontBytes?{regular:s.pdf.customFontBytes}:void 0),p=c&&u?c.createFontBytesMeasurer(u):void 0,i=await r(s,p);o.throwIfAborted(s.signal);const f=S.createReportTaskReporter(s),l=await f.run("encode",async()=>{let b;if(s.format==="pdf"){o.throwIfAborted(s.signal);const h=await c.renderPlanToPdf(i.plan,{...s.pdf,...p?{measurer:p}:{},fidelity:s.fidelity,signal:s.signal,onProgress:(w,g)=>f.progress("encode",w,g)});b=h.bytes,i.diagnostics.push(...M(h.diagnostics)),i.diagnostics.push(...h.fidelityWarnings.map(w=>({code:"pdf-fidelity",message:w,severity:"warning"})),...h.pageErrors.map(w=>({code:"pdf-page",message:w,severity:"error"}))),h.unsupportedTextCount&&i.diagnostics.push({code:"pdf-font",message:`${h.unsupportedTextCount} 段文本包含当前字体不支持的字符`,severity:"warning"})}else{const{renderPlanToXlsx:h}=await import("@agile-team/mach-report/xlsx");o.throwIfAborted(s.signal);const w=await h(i.plan,{...s.xlsx,fidelity:s.fidelity,signal:s.signal,onProgress:(g,v)=>f.progress("encode",g,v)});b=new Uint8Array(w.buffer),i.diagnostics.push(...M(w.diagnostics)),i.diagnostics.push(...w.warnings.map(g=>({code:"xlsx-fidelity",message:g,severity:"warning"})))}return o.throwIfAborted(s.signal),b});o.assertBudget(t,"maxOutputBytes",l.byteLength);const{plan:d,...y}=i;return{...y,bytes:l,format:s.format,contentType:s.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",stats:{...y.stats,durationMs:Date.now()-n,outputBytes:l.byteLength}}};return{describe:s=>pe(e.reports,s),validate:s=>U(e.reports,s),prepare:s=>o.controlled(s.signal,t.maxDurationMs,async n=>{const{signal:c,onEvent:u,...p}=s,i={...p,taskId:p.taskId??S.reportTaskId()},f=u?y=>S.notifyReportTaskEvent(u,y,n):void 0,l={...i,signal:n,onEvent:f};S.createReportTaskReporter(l).runSync("validate",()=>L(e,i));const d=e.executor?await e.executor.prepare(i,n,f):await r(l);return ge(d,t)}),export:s=>o.controlled(s.signal,t.maxDurationMs,async n=>{const{signal:c,onEvent:u,...p}=s,i={...p,taskId:p.taskId??S.reportTaskId()},f=u?y=>S.notifyReportTaskEvent(u,y,n):void 0,l={...i,signal:n,onEvent:f};if(S.createReportTaskReporter(l).runSync("validate",()=>L(e,i)),i.format!=="pdf"&&i.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const d=e.executor?await e.executor.export(i,n,f):await a(l);return o.assertBudget(t,"maxRows",d.stats.rows),o.assertBudget(t,"maxPages",d.stats.pages),o.assertBudget(t,"maxCells",d.stats.cells),o.assertBudget(t,"maxOutputBytes",d.bytes.byteLength),{...d,stats:{...d.stats,outputBytes:d.bytes.byteLength}}})}}function we(e={}){const t=e.concurrency??1,r=e.maxQueued??20;if(!Number.isSafeInteger(t)||t<1||!Number.isSafeInteger(r)||r<0)throw new o.ReportRuntimeError("budget","队列并发应为正整数,排队上限应为非负整数");const a=[],s=new Set,n=new Set;let c=!1,u=0;const p=()=>{for(;!c&&s.size<t&&a.length;)a.shift().start()};return{get active(){return s.size},get pending(){return a.length},enqueue:(f,l={})=>{if(c)throw new o.ReportRuntimeError("closed","任务队列已关闭");if(o.throwIfAborted(l.signal),s.size>=t&&a.length>=r)throw new o.ReportRuntimeError("queue-full","报表任务队列已满");const d=l.id??`report-${++u}`;if(n.has(d))throw new o.ReportRuntimeError("queue-full","任务 ID 正在执行或排队");const y=new AbortController;let b="queued",h,w,g,v;const E=new Promise((R,I)=>{g=R,v=I}),J=()=>{l.signal?.removeEventListener("abort",C),n.delete(d)},j=R=>{if(b!=="queued"&&b!=="running")return;const I=b==="queued";b="cancelled",y.abort(R);try{o.throwIfAborted(y.signal)}catch(N){v(N)}if(I){const N=a.indexOf(O);N>=0&&a.splice(N,1),J(),p()}},C=()=>j(l.signal?.reason),z=(R,I)=>{b==="running"&&(!Number.isFinite(R)||R<0||I!==void 0&&(!Number.isFinite(I)||I<R)||(h={completed:R,...I===void 0?{}:{total:I}}))},re=R=>{b!=="running"||y.signal.aborted||(w={...R,taskId:d},R.completed!==void 0&&z(R.completed,R.total),S.notifyReportTaskEvent(l.onEvent,w,y.signal))},O={cancel:j,start:()=>{b==="queued"&&(b="running",s.add(O),Promise.resolve().then(()=>(o.throwIfAborted(y.signal),f({taskId:d,signal:y.signal,reportProgress:z,onEvent:re}))).then(R=>{b==="running"&&(b="completed",g(R))},R=>{b==="running"&&(b="failed",v(R))}).finally(()=>{s.delete(O),J(),p()}))}};return n.add(d),l.signal?.addEventListener("abort",C,{once:!0}),l.signal?.aborted?j(l.signal.reason):s.size<t?O.start():a.push(O),{id:d,get status(){return b},get progress(){return h},get event(){return w},result:E,cancel:j}},close:(f={})=>{c=!0;for(const l of[...a])l.cancel(new o.ReportRuntimeError("closed","任务队列已关闭"));if(f.cancelRunning)for(const l of s)l.cancel(new o.ReportRuntimeError("closed","任务队列已关闭"))}}}function me(e){let t,r;const a=new Promise((s,n)=>{t=s,r=n});return a.catch(()=>{}),{progress:e,promise:a,resolve:t,reject:r}}function _(e){const t=Promise.reject(e);return t.catch(()=>{}),t}function he(e,t){let r,a,s=!0,n;function c(i){n??=i??new Error("任务心跳更新失败"),a?.reject(n),a=void 0,t(n)}function u(i){const f=Promise.resolve().then(()=>e(i?.progress)).then(()=>i?.resolve(),l=>{i?.reject(l),c(l)}).finally(()=>{r=void 0;const l=a;a=void 0,l&&n===void 0&&u(l)});r=f,f.catch(l=>{c(l)})}function p(i){if(!s)return _(new o.ReportJobError("closed","任务进度上报已结束"));if(n!==void 0)return _(n);a?a.progress=i:a=me(i);const f=a;return r||(a=void 0,u(f)),f.promise}return{progress:p,pulse(){s&&!r&&n===void 0&&u()},async finish(){for(s=!1;r;)await r;if(n!==void 0)throw n}}}class V extends o.ReportJobError{constructor(){super("capacity","任务结果超过独立预算,请保存文件引用")}}function ye(e){const t=e.concurrency??1,r=e.leaseMs??3e4,a=e.heartbeatMs??1e4,s=e.maxResultBytes??256*1024;if(![t,r,a,s].every(c=>Number.isSafeInteger(c)&&c>0)||a*2>r)throw new o.ReportJobError("input","并发、租约、心跳应为正整数,租约至少为心跳的两倍");if(a>2147483647)throw new o.ReportJobError("input","心跳间隔超过平台定时器上限(2147483647毫秒)");return{concurrency:t,leaseMs:r,heartbeatMs:a,maxResultBytes:s,now:()=>{const c=(e.now??Date.now)();if(!Number.isSafeInteger(c)||c<0)throw new o.ReportJobError("input","任务时钟应返回非负整数毫秒");return c}}}async function B(e,t,r){o.checkJobIdentity(t,r);const a=await e.read(t,r);if(!a)throw new o.ReportJobError("missing","报表任务不存在");return a}async function k(e,t,r,a=[]){const s={...t,...r,revision:t.revision+1};for(const n of a)delete s[n];if(!await e.compareAndSwap(t.scope,t.id,t.revision,s))throw new o.ReportJobError("conflict","报表任务已被其他请求更新");return o.cloneJob(s)}async function be(e,t,r,a){if(!t.trim()||t.length>128)throw new o.ReportJobError("input","workerId应为1–128位标识");for(const s of await e.store.candidates(a,100)){const n=s.cancelRequested?{...s,revision:s.revision+1,status:"cancelled",updatedAt:a}:{...s,revision:s.revision+1,status:"running",attempt:s.attempt+1,updatedAt:a,lease:{owner:t,expiresAt:a+r}};if(n.status==="cancelled"&&delete n.lease,await e.store.compareAndSwap(s.scope,s.id,s.revision,n))return n}}function Q(e,t,r,a){return e.status==="running"&&e.attempt===a&&e.lease?.owner===t&&e.lease.expiresAt>r}async function ve(e,t,r,a){const{scope:s,id:n}=r,c=r.lease.owner;let u;const p=he(async w=>{const g=await B(e.store,s,n),v=t.now();if(!Q(g,c,v,r.attempt))throw new o.ReportJobError("lease","报表任务租约已失效");if(g.cancelRequested){a.abort(new o.ReportJobError("closed","任务已请求取消"));return}await k(e.store,g,{updatedAt:v,lease:{owner:c,expiresAt:v+t.leaseMs},...w?{progress:w}:{}})},w=>{u=w,a.abort(w)}),i=(w,g)=>!Number.isFinite(w)||w<0||g!==void 0&&(!Number.isFinite(g)||g<w)?Promise.reject(new o.ReportJobError("input","任务进度无效")):p.progress({completed:w,...g===void 0?{}:{total:g}}),f=setInterval(()=>{p.pulse()},t.heartbeatMs);let l,d;try{const w=Object.prototype.hasOwnProperty.call(e.handlers,r.request.kind)?e.handlers[r.request.kind]:void 0;if(!w)throw new o.ReportJobError("input","报表任务处理器未注册");if(!a.signal.aborted){const g=await w(o.cloneJob(r.request.payload),{scope:s,taskId:n,signal:a.signal,reportProgress:i});if(l=JSON.parse(o.serializeJobJson(g)),o.jobByteLength(l)>t.maxResultBytes)throw new V}}catch(w){d=w??new Error("报表任务执行失败")}finally{clearInterval(f),await p.finish().catch(()=>{})}const y=await B(e.store,s,n),b=t.now();if(!Q(y,c,b,r.attempt))throw new o.ReportJobError("lease","任务租约已失效,迟到结果不会写回");const h={...y,updatedAt:b};delete h.lease,d??=u,y.cancelRequested||a.signal.aborted&&u===void 0?h.status="cancelled":d!==void 0?(h.status="failed",h.error={code:d instanceof V?"result-budget":d instanceof o.ReportJobError?d.code:"execution",message:d instanceof Error?d.message.slice(0,500):"报表任务执行失败"}):(h.status="completed",h.result=l);try{o.serializeJobJson(h)}catch{delete h.result,h.status="failed",h.error={code:"result-budget",message:"任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"}}return Re(e.store,y,h)}async function Re(e,t,r){try{return await k(e,t,r,["lease"])}catch(a){if(!(a instanceof o.ReportJobError)||a.code!=="capacity"||r.status!=="completed")throw a;return delete r.result,r.status="failed",r.error={code:"result-budget",message:"任务结果超过存储剩余预算,请保存文件引用而非文件内容"},k(e,t,r,["lease","result"])}}async function H(e,t,r,a){const s=await e.readTombstone?.(t,r);if(s){if(s.requestHash!==await o.jobRequestHash(a))throw new o.ReportJobError("conflict","相同任务ID不能提交不同内容(幂等保留期内)");return{scope:t,id:r,revision:s.revision,request:o.cloneJob(a),status:s.status,createdAt:s.createdAt,updatedAt:s.updatedAt,attempt:s.attempt,archived:!0}}}function xe(e){e={...e,handlers:{...e.handlers}};const t=ye(e),r=new Set,a=new Set;let s=!1,n=0;const c=(i,f)=>(o.checkJobIdentity(i,f),e.store.read(i,f));return{submit:async i=>{if(i={...i},o.checkJobIdentity(i.scope,i.id),!Object.prototype.hasOwnProperty.call(e.handlers,i.kind)||typeof e.handlers[i.kind]!="function")throw new o.ReportJobError("input","报表任务处理器未注册");const f={kind:i.kind,payload:JSON.parse(o.serializeJobJson(i.payload,{maxNodes:19e3,maxCharacters:75e4}))},l=await c(i.scope,i.id);if(l){if(o.serializeJobJson(l.request)!==o.serializeJobJson(f))throw new o.ReportJobError("conflict","相同任务ID不能提交不同内容");return l}const d=await H(e.store,i.scope,i.id,f);if(d)return d;const y=t.now(),b={scope:i.scope,id:i.id,revision:1,request:f,status:"queued",createdAt:y,updatedAt:y,attempt:0};if(!await e.store.compareAndSwap(i.scope,i.id,null,b)){const h=await c(i.scope,i.id);if(h&&o.serializeJobJson(h.request)===o.serializeJobJson(f))return h;const w=await H(e.store,i.scope,i.id,f);if(w)return w;throw new o.ReportJobError("conflict","报表任务提交发生冲突")}return o.cloneJob(b)},get:c,runNext:i=>{if(s)return Promise.reject(new o.ReportJobError("closed","报表任务服务已关闭"));if(n>=t.concurrency)return Promise.reject(new o.ReportJobError("capacity","报表任务执行槽位已满"));n++;const f=new AbortController;r.add(f);const l=(async()=>{try{const d=await be(e,i,t.leaseMs,t.now());return d?.status==="running"?await ve(e,t,d,f):d}finally{n--,r.delete(f)}})();return a.add(l),l.then(()=>a.delete(l),()=>a.delete(l)),l},get active(){return n},cancel:async(i,f)=>{const l=await B(e.store,i,f);return l.status!=="queued"&&l.status!=="running"?l:k(e.store,l,{updatedAt:t.now(),...l.status==="queued"?{status:"cancelled"}:{cancelRequested:!0}})},retry:async(i,f,l)=>{const d=await B(e.store,i,f);if(d.revision!==l||d.status!=="failed")throw new o.ReportJobError("conflict","仅可重试当前修订的失败任务");const y={...d,status:"queued",updatedAt:t.now()};return delete y.error,delete y.progress,k(e.store,d,y,["error","progress"])},prune:async i=>{if(!e.store.prune||!e.store.readTombstone)throw new o.ReportJobError("input","当前任务适配器未实现可选终态保留能力");return e.store.prune({...i,now:t.now()})},close:async()=>{s=!0;for(const i of r)i.abort(new o.ReportJobError("closed","任务服务正在关闭"));await Promise.allSettled([...a])}}}function Z(e,t){const r=e.assets,a=e[t];if(!(!r&&!a?.assetRenderers))return{...r,...a?.assetFailure===void 0?{}:{assetFailure:a.assetFailure},...a?.onDiagnostic===void 0?{}:{onDiagnostic:a.onDiagnostic},assetRenderers:{...r?.assetRenderers,...a?.assetRenderers},assetBudget:{...r?.assetBudget,...a?.assetBudget}}}function X(e,t){return!e||e.code!=="missing-image"||e.format!=="pdf"&&e.format!=="xlsx"?!1:typeof Z(t,e.format)?.assetRenderers?.[e.kind]=="function"}function Ie(e,t){const r=x.reviewReportTemplate(e,t),a=r.issues.filter(n=>!X(n.diagnostic,t)),s=r.samples.map(n=>({...n,diagnostics:n.diagnostics.filter(c=>!X(c,t))}));return{...r,issues:a,samples:s,ok:a.every(n=>n.severity!=="error"),artifacts:[]}}async function Se(e,t,r,a,s){const n=W({reports:{sample:{template:r,datasets:e.datasets}},assets:Z(a,t),budget:{maxRows:a.maxSampleRows??1e3,maxPages:a.maxPages??100,maxCells:a.maxCells??25e4,maxOutputBytes:a.maxOutputBytes??2e7,maxDurationMs:a.maxDurationMs??3e4}});try{const{result:c,digest:u}=await o.controlled(a.signal,a.maxDurationMs??3e4,async p=>{const i=await n.export({reportIds:["sample"],params:e.params,format:t,signal:p,fidelity:a.strictOutputs?"strict":"warn",pdf:a.pdf,xlsx:a.xlsx}),f=i.diagnostics.filter(d=>d.severity!=="info");if(a.strictOutputs&&f.length)throw new Error(`Strict ${t} encoding found fidelity issues: ${f.slice(0,3).map(d=>d.message).join("; ")}`);const l=await a.digest?.(i.bytes);return o.throwIfAborted(p),await a.onArtifact?.(e.name,i),o.throwIfAborted(p),{result:i,digest:l}});s.artifacts.push({fixture:e.name,format:t,bytes:c.bytes.byteLength,pages:c.stats.pages,...u?{digest:u}:{}}),s.issues.push(...c.diagnostics.map(p=>({code:"output",severity:a.strictOutputs||p.severity==="error"?"error":"warning",path:"$.template",fixture:e.name,message:`${t}: ${p.message}`})))}catch(c){o.throwIfAborted(a.signal),s.issues.push({code:"output",severity:"error",path:"$.template",fixture:e.name,message:`${t}: ${c instanceof Error?c.message:String(c)}`})}}async function Je(e,t={}){o.throwIfAborted(t.signal);const r=Ie(e,t);if(!r.ok)return r;const a=de.parseReportTemplate(e).template,s=[...new Set(t.formats??["pdf","xlsx"])];if(!s.length||s.some(n=>n!=="pdf"&&n!=="xlsx"))return r.issues.push({code:"output",severity:"error",path:"$.formats",message:"真实文件验收应至少选择PDF/XLSX之一"}),r.ok=!1,r;for(const n of t.fixtures??[])for(const c of s)o.throwIfAborted(t.signal),!(c!=="pdf"&&c!=="xlsx")&&await Se(n,c,a,t,r);return r.ok=r.issues.every(n=>n.severity!=="error"),r}class m extends Error{constructor(t,r){super(r),this.code=t,this.name="ReportInstanceError"}}function A(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 Ee(e,t){const r=Object.getPrototypeOf(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t)||Object.getOwnPropertySymbols(e).length)throw new m("input","实例应为普通 JSON 对象");if(t&&Object.keys(e).some(s=>s!==String(Number(s))||!Number.isSafeInteger(Number(s))||Number(s)<0||Number(s)>=e.length))throw new m("input","实例数组不能包含额外属性");if(Object.getOwnPropertyNames(e).filter(s=>!(t&&s==="length")).length!==Object.keys(e).length)throw new m("input","实例不能包含不可枚举属性")}function Ae(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 Oe(e){return e===null||typeof e=="boolean"||typeof e=="string"||typeof e=="number"&&Number.isFinite(e)}function Y(e,t){if(!Number.isSafeInteger(t)||t<1)throw new m("input","实例快照字节预算应为正安全整数");let r=0,a=0;const s=new Set;function n(u,p){if(++r>1e6||p>64)throw new m("capacity","实例节点或嵌套深度超过预算");if(typeof u=="string"&&(a+=u.length,a>t))throw new m("capacity","实例文本超过预算");if(Oe(u))return u;if(!u||typeof u!="object"||s.has(u))throw new m("input","实例只允许无循环的有限 JSON 值");const i=Array.isArray(u);Ee(u,i),s.add(u);const f=Object.create(null);for(const l of Object.keys(u)){if(a+=l.length,a>t)throw new m("capacity","实例文本超过预算");const d=Object.getOwnPropertyDescriptor(u,l);if(d.get||d.set||["__proto__","constructor","prototype"].includes(l))throw new m("input","实例不能包含访问器或危险键");d.value!==void 0&&(f[l]=n(d.value,p+1))}if(s.delete(u),i){if(Object.keys(f).length!==u.length)throw new m("input","实例数组不能稀疏或包含额外属性");return Array.from({length:u.length},(l,d)=>f[String(d)])}return f}const c=JSON.stringify(n(e,0));if(new TextEncoder().encode(c).byteLength>t)throw new m("capacity","实例快照超过单条字节预算");return c}function D(e,t=8e6){const r=JSON.parse(Y(e,t));A(r.scope,r.id);const a=new Set(["scope","id","revision","title","generatedAt","reportIds","params","templateRevisions","sourceRevisions","plan","artifacts"]);if(Object.keys(r).some(n=>!a.has(n)))throw new m("input","实例包含未知字段");Ae(r);for(const n of[r.params,r.templateRevisions,r.sourceRevisions])if(!n||typeof n!="object"||Array.isArray(n)||Object.values(n).some(c=>typeof c!="string"))throw new m("input","实例参数和修订应为字符串字典");if(r.reportIds.some(n=>!r.templateRevisions[n]))throw new m("input","每张报表都应记录生成时的模板修订");const s=G.validateRenderPlan(r.plan);if(!s.ok)throw new m("input",`实例渲染计划无效:${s.errors[0]?.path}`);return r.artifacts!==void 0&&Pe(r.artifacts),r}function Pe(e){if(!Array.isArray(e)||e.length>100)throw new m("input","实例文件列表无效");const t=new Set;for(const r of e){if(!r||typeof r.key!="string"||!r.key.trim()||r.key.length>1024||t.has(r.key)||!["pdf","xlsx"].includes(r.format)||!Number.isSafeInteger(r.bytes)||r.bytes<0||r.sha256!==void 0&&(typeof r.sha256!="string"||r.sha256.length!==64||!/^[a-f0-9]{64}$/i.test(r.sha256)))throw new m("input","实例文件应包含唯一存储键、格式、大小和可选 SHA256");t.add(r.key)}}function ee(e){const{scope:t,id:r,revision:a,title:s,generatedAt:n,reportIds:c,params:u,templateRevisions:p,sourceRevisions:i}=e;return JSON.parse(JSON.stringify({scope:t,id:r,revision:a,title:s,generatedAt:n,reportIds:c,params:u,templateRevisions:p,sourceRevisions:i}))}function ke(e){const t={maxInstances:100,maxRevisions:20,maxBytes:64e6,maxSnapshotBytes:8e6,...e};if(Object.values(t).some(r=>!Number.isSafeInteger(r)||r<1))throw new m("input","实例存储预算应为正安全整数");return t}function je(e={}){const t=ke(e),r=new Map;let a=0;return{read:async(s,n,c,u)=>{o.throwIfAborted(u),A(s,n);const p=r.get(JSON.stringify([s,n])),i=p?.get(c??p.size);return i?D(i,t.maxSnapshotBytes):void 0},list:async(s,n={})=>{o.throwIfAborted(n.signal),A(s,"list");const c=n.limit??25;if(!Number.isSafeInteger(c)||c<1||c>100)throw new m("input","实例每页数量应为 1–100");const u=Array.from(r.values(),p=>p.get(p.size)).filter(p=>p.scope===s&&(!n.after||p.id>n.after)&&(!n.reportId||p.reportIds.includes(n.reportId))).sort((p,i)=>p.id<i.id?-1:1).slice(0,c+1);return{items:u.slice(0,c).map(ee),...u.length>c?{next:u[c-1].id}:{}}},compareAndSwap:async(s,n,c,u,p)=>{o.throwIfAborted(p),A(s,n);const i=D(u,t.maxSnapshotBytes);if(i.scope!==s||i.id!==n||i.revision!==(c??0)+1)throw new m("input","实例身份或修订不一致");const f=JSON.stringify([s,n]),l=r.get(f)??new Map;if((l.size||null)!==c)return!1;const d=new TextEncoder().encode(JSON.stringify(i)).byteLength;if(l.size>=t.maxRevisions||a+d>t.maxBytes||!l.size&&r.size>=t.maxInstances)throw new m("capacity","实例存储达到预算,请使用持久化归档策略或显式调整容量");return l.set(i.revision,i),r.set(f,l),a+=d,!0}}}function te(e,t={}){const r=t.maxSnapshotBytes??8e6;if(!Number.isSafeInteger(r)||r<1)throw new m("input","实例快照字节预算应为正安全整数");return{read:e.read.bind(e),list:e.list.bind(e),save:async(a,s)=>{const n=s.expectedRevision;if(n!==null&&(!Number.isSafeInteger(n)||n<1||n>=Number.MAX_SAFE_INTEGER))throw new m("input","实例预期修订无效");const c=JSON.parse(Y(a,r)),u=D({...c,revision:(n??0)+1},r);if(o.throwIfAborted(s.signal),!await e.compareAndSwap(u.scope,u.id,n,u,s.signal))throw new m("conflict","实例已存在或已变化,请显式确认修订后保存");return u}}}function Ne(e,t){return o.serializeJobJson({reportIds:e,params:t})}function Be(e){if(!e||typeof e!="object"||Object.getOwnPropertySymbols(e).length)throw new m("input","生成请求应为普通对象");const t=Object.create(null);let r;const a=new Set(["scope","id","title","reportIds","params","expectedRevision","signal"]);for(const s of Object.getOwnPropertyNames(e)){const n=Object.getOwnPropertyDescriptor(e,s);if(!a.has(s)||!n.enumerable||n.get||n.set)throw new m("input","生成请求不能包含未知字段或访问器");s==="signal"?r=n.value:n.value!==void 0&&(t[s]=n.value)}return{signal:r,request:JSON.parse(o.serializeJobJson(t))}}function De(e){const t=JSON.parse(o.serializeJobJson(e.templateRevisions)),r=te(e.instances,{maxSnapshotBytes:e.maxSnapshotBytes});return{async generate(a){const{signal:s,request:n}=Be(a);if(A(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 P.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(o.throwIfAborted(s),((await e.instances.read(n.scope,n.id,void 0,s))?.revision??null)!==n.expectedRevision)throw new m("conflict","实例已存在或已变化,请显式确认修订后生成");const i=await e.runtime.prepare({reportIds:n.reportIds,params:c.values,signal:s});o.throwIfAborted(s);const f=Object.create(null);for(const[l,d]of Object.entries(i.revisions))d.revision!==void 0&&(f[l]=d.revision);return r.save({scope:n.scope,id:n.id,title:n.title,reportIds:n.reportIds,params:c.values,templateRevisions:u,sourceRevisions:f,generatedAt:(e.now?.()??new Date).toISOString(),plan:i.plan},{expectedRevision:n.expectedRevision,signal:s})},read:r.read,list:r.list,save:r.save}}exports.ReportJobError=o.ReportJobError;exports.ReportRuntimeError=o.ReportRuntimeError;exports.checkJobIdentity=o.checkJobIdentity;exports.cloneJob=o.cloneJob;exports.createMemoryReportJobStore=o.createMemoryReportJobStore;exports.runReportBatch=o.runReportBatch;exports.runnableJob=o.runnableJob;exports.serializeJobJson=o.serializeJobJson;exports.snapshotReportBatchCases=o.snapshotReportBatchCases;exports.validateJobRecord=o.validateJobRecord;exports.validateJobTransition=o.validateJobTransition;exports.ReportInstanceError=m;exports.checkInstanceIdentity=A;exports.createMemoryReportInstanceStore=je;exports.createReportGenerationService=De;exports.createReportInstanceManager=te;exports.createReportJobService=xe;exports.createReportRuntime=W;exports.createReportTaskQueue=we;exports.reportInstanceParameterKey=Ne;exports.reportInstanceSummary=ee;exports.reviewReportPublication=Je;exports.snapshotReportInstance=D;
|
|
1
|
+
"use strict";var se=Object.create;var $=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var ce=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ae(t))!ie.call(e,s)&&s!==r&&$(e,s,{get:()=>t[s],enumerable:!(a=ne(t,s))||a.enumerable});return e};var F=(e,t,r)=>(r=e!=null?se(oe(e)):{},ce(t||!e||!e.__esModule?$(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("./template-review-DGwWOoCv.cjs"),T=require("./report-params-SJfhKgaX.cjs"),P=require("./param-validation-DCK039V1.cjs"),o=require("./batch-Bt3Fd27Z.cjs"),G=require("./validate-BJ5HIWY8.cjs"),S=require("./task-events-DQ276fn2.cjs"),le=require("./tree-BX380Rr7.cjs"),ue=require("./assets-C2U-e-Sz.cjs"),de=require("./template-registry-D3SjENi6.cjs");function K(e,t){if(t.length===0)throw new x.ReportSourceError("config","缺少报表 ID");return t.map(r=>{if(!Object.prototype.hasOwnProperty.call(e,r))throw new x.ReportSourceError("config",`未注册报表 ${r}`);return e[r]})}function q(e){return e.grid?.cells.reduce((t,r)=>t+r.reduce((a,s)=>a+(s?1+(s.children?.reduce((n,c)=>n+q(c),0)??0):0),0),0)??0}function fe(e,t,r){return e.pages.reduce((a,s)=>a+s.components.reduce((n,c)=>c.kind!=="list"?n+q(c):n+x.estimateListLayoutCells(c,t,r),0),0)}function pe(e,t=Object.keys(e)){return K(e,t).map((r,a)=>{const s=t[a],n=T.getReportParamDefs(e,[s]);return{id:s,params:JSON.parse(JSON.stringify(n)),paramsSchema:P.reportParamsJsonSchema(n),datasetsSchema:Object.fromEntries(Object.entries(r.dataSchema??{}).map(([c,u])=>[c,x.templateDatasetJsonSchema(typeof r.template=="function"?void 0:r.template,c,u)])),capabilities:{save:!!r.provider?.save,export:!!r.provider?.export,templates:!!r.provider?.templates}}})}function U(e,t){K(e,t.reportIds);const r=P.validateReportParams(T.getReportParamDefs(e,t.reportIds),t.params),a=t.reportIds.flatMap(n=>P.validateReportParams(T.getReportParamDefs(e,[n]),t.params).issues),s=new Map(a.map(n=>[JSON.stringify(n),n]));return{...r,ok:s.size===0,issues:[...s.values()]}}function ge(e,t){const r=G.validateRenderPlan(e.plan);if(!r.ok)throw new x.ReportSourceError("validate",`执行器返回无效计划:${r.errors[0]?.path}`);const a=e.plan.pages.length,s=e.plan.pages.reduce((n,c)=>n+c.components.reduce((u,p)=>u+q(p),0),0);return o.assertBudget(t,"maxRows",e.stats.rows),o.assertBudget(t,"maxPages",a),o.assertBudget(t,"maxCells",s),{...e,stats:{...e.stats,pages:a,cells:s}}}function L(e,t){const r=U(e.reports,t);if(!r.ok)throw new P.ReportParamValidationError(r.issues)}function M(e=[]){return e.map(({code:t,message:r,severity:a,pageIndex:s,componentIndex:n})=>({code:t,message:r,severity:a,path:`$.pages.${s}.components.${n}`}))}function W(e){const t={maxRows:1e5,maxPages:1e4,maxCells:2e6,maxOutputBytes:1e8,maxDurationMs:12e4,...e.budget};o.validateBudget(t);const r=async(s,n)=>{const c=Date.now();let u=0,p=0;const i=[],f={},l=Object.fromEntries(Object.entries(e.reports).map(([g,v])=>[g,{...v,pagination:{...e.pagination,...v.pagination,...n?{measurer:n}:{}},dataValidation:{...v.dataValidation,maxRows:Math.min(t.maxRows??1e5,v.dataValidation?.maxRows??1/0),maxCells:Math.min(t.maxCells??2e6,v.dataValidation?.maxCells??1/0)}}])),y=await x.createReportSource(l,{maxPages:t.maxPages,maxCells:t.maxCells,onDatasets:(g,v,E)=>{try{u+=x.templateDatasetRowCount(E,v,{maxRows:t.maxRows,signal:s.signal})}catch(J){throw J instanceof le.TreeRowLimitError?new o.ReportRuntimeError("budget",J.message,"$.budget.maxRows"):J}o.assertBudget(t,"maxRows",u),p+=fe(E,v,l[g]?.pagination),o.assertBudget(t,"maxCells",p)}})({...s,params:s.params??{},onWarning:g=>i.push({code:"layout",message:g,severity:"warning"}),onQueryResult:(g,v)=>{Object.defineProperty(f,g,{value:{revision:v.revision,sourceToken:v.sourceToken},enumerable:!0,writable:!0}),i.push(...v.diagnostics??[])}}).catch(g=>{throw g instanceof x.ReportSourceError&&g.cause instanceof x.PaginatePageLimitError?new o.ReportRuntimeError("budget",g.cause.message,"$.budget.maxPages"):g instanceof x.ReportSourceError&&g.cause instanceof x.PaginateCellLimitError?new o.ReportRuntimeError("budget",g.cause.message,"$.budget.maxCells"):g});o.throwIfAborted(s.signal);const b=e.assets?await S.createReportTaskReporter(s).run("assets",()=>ue.resolvePlanAssets(y,{...e.assets,signal:s.signal})):{plan:y,diagnostics:[]},h=b.plan;i.push(...M(b.diagnostics));const w=h.pages.reduce((g,v)=>g+v.components.reduce((E,J)=>E+q(J),0),0);return o.assertBudget(t,"maxPages",h.pages.length),o.assertBudget(t,"maxCells",w),{plan:h,diagnostics:i,revisions:f,stats:{rows:u,pages:h.pages.length,cells:w,durationMs:Date.now()-c}}},a=async s=>{const n=Date.now();if(s.format!=="pdf"&&s.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const c=s.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;o.throwIfAborted(s.signal);const u=s.pdf?.customFontFaces??(s.pdf?.customFontBytes?{regular:s.pdf.customFontBytes}:void 0),p=c&&u?c.createFontBytesMeasurer(u):void 0,i=await r(s,p);o.throwIfAborted(s.signal);const f=S.createReportTaskReporter(s),l=await f.run("encode",async()=>{let b;if(s.format==="pdf"){o.throwIfAborted(s.signal);const h=await c.renderPlanToPdf(i.plan,{...s.pdf,...p?{measurer:p}:{},fidelity:s.fidelity,signal:s.signal,onProgress:(w,g)=>f.progress("encode",w,g)});b=h.bytes,i.diagnostics.push(...M(h.diagnostics)),i.diagnostics.push(...h.fidelityWarnings.map(w=>({code:"pdf-fidelity",message:w,severity:"warning"})),...h.pageErrors.map(w=>({code:"pdf-page",message:w,severity:"error"}))),h.unsupportedTextCount&&i.diagnostics.push({code:"pdf-font",message:`${h.unsupportedTextCount} 段文本包含当前字体不支持的字符`,severity:"warning"})}else{const{renderPlanToXlsx:h}=await import("@agile-team/mach-report/xlsx");o.throwIfAborted(s.signal);const w=await h(i.plan,{...s.xlsx,fidelity:s.fidelity,signal:s.signal,onProgress:(g,v)=>f.progress("encode",g,v)});b=new Uint8Array(w.buffer),i.diagnostics.push(...M(w.diagnostics)),i.diagnostics.push(...w.warnings.map(g=>({code:"xlsx-fidelity",message:g,severity:"warning"})))}return o.throwIfAborted(s.signal),b});o.assertBudget(t,"maxOutputBytes",l.byteLength);const{plan:d,...y}=i;return{...y,bytes:l,format:s.format,contentType:s.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",stats:{...y.stats,durationMs:Date.now()-n,outputBytes:l.byteLength}}};return{describe:s=>pe(e.reports,s),validate:s=>U(e.reports,s),prepare:s=>o.controlled(s.signal,t.maxDurationMs,async n=>{const{signal:c,onEvent:u,...p}=s,i={...p,taskId:p.taskId??S.reportTaskId()},f=u?y=>S.notifyReportTaskEvent(u,y,n):void 0,l={...i,signal:n,onEvent:f};S.createReportTaskReporter(l).runSync("validate",()=>L(e,i));const d=e.executor?await e.executor.prepare(i,n,f):await r(l);return ge(d,t)}),export:s=>o.controlled(s.signal,t.maxDurationMs,async n=>{const{signal:c,onEvent:u,...p}=s,i={...p,taskId:p.taskId??S.reportTaskId()},f=u?y=>S.notifyReportTaskEvent(u,y,n):void 0,l={...i,signal:n,onEvent:f};if(S.createReportTaskReporter(l).runSync("validate",()=>L(e,i)),i.format!=="pdf"&&i.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const d=e.executor?await e.executor.export(i,n,f):await a(l);return o.assertBudget(t,"maxRows",d.stats.rows),o.assertBudget(t,"maxPages",d.stats.pages),o.assertBudget(t,"maxCells",d.stats.cells),o.assertBudget(t,"maxOutputBytes",d.bytes.byteLength),{...d,stats:{...d.stats,outputBytes:d.bytes.byteLength}}})}}function we(e={}){const t=e.concurrency??1,r=e.maxQueued??20;if(!Number.isSafeInteger(t)||t<1||!Number.isSafeInteger(r)||r<0)throw new o.ReportRuntimeError("budget","队列并发应为正整数,排队上限应为非负整数");const a=[],s=new Set,n=new Set;let c=!1,u=0;const p=()=>{for(;!c&&s.size<t&&a.length;)a.shift().start()};return{get active(){return s.size},get pending(){return a.length},enqueue:(f,l={})=>{if(c)throw new o.ReportRuntimeError("closed","任务队列已关闭");if(o.throwIfAborted(l.signal),s.size>=t&&a.length>=r)throw new o.ReportRuntimeError("queue-full","报表任务队列已满");const d=l.id??`report-${++u}`;if(n.has(d))throw new o.ReportRuntimeError("queue-full","任务 ID 正在执行或排队");const y=new AbortController;let b="queued",h,w,g,v;const E=new Promise((R,I)=>{g=R,v=I}),J=()=>{l.signal?.removeEventListener("abort",C),n.delete(d)},j=R=>{if(b!=="queued"&&b!=="running")return;const I=b==="queued";b="cancelled",y.abort(R);try{o.throwIfAborted(y.signal)}catch(N){v(N)}if(I){const N=a.indexOf(O);N>=0&&a.splice(N,1),J(),p()}},C=()=>j(l.signal?.reason),z=(R,I)=>{b==="running"&&(!Number.isFinite(R)||R<0||I!==void 0&&(!Number.isFinite(I)||I<R)||(h={completed:R,...I===void 0?{}:{total:I}}))},re=R=>{b!=="running"||y.signal.aborted||(w={...R,taskId:d},R.completed!==void 0&&z(R.completed,R.total),S.notifyReportTaskEvent(l.onEvent,w,y.signal))},O={cancel:j,start:()=>{b==="queued"&&(b="running",s.add(O),Promise.resolve().then(()=>(o.throwIfAborted(y.signal),f({taskId:d,signal:y.signal,reportProgress:z,onEvent:re}))).then(R=>{b==="running"&&(b="completed",g(R))},R=>{b==="running"&&(b="failed",v(R))}).finally(()=>{s.delete(O),J(),p()}))}};return n.add(d),l.signal?.addEventListener("abort",C,{once:!0}),l.signal?.aborted?j(l.signal.reason):s.size<t?O.start():a.push(O),{id:d,get status(){return b},get progress(){return h},get event(){return w},result:E,cancel:j}},close:(f={})=>{c=!0;for(const l of[...a])l.cancel(new o.ReportRuntimeError("closed","任务队列已关闭"));if(f.cancelRunning)for(const l of s)l.cancel(new o.ReportRuntimeError("closed","任务队列已关闭"))}}}function me(e){let t,r;const a=new Promise((s,n)=>{t=s,r=n});return a.catch(()=>{}),{progress:e,promise:a,resolve:t,reject:r}}function _(e){const t=Promise.reject(e);return t.catch(()=>{}),t}function he(e,t){let r,a,s=!0,n;function c(i){n??=i??new Error("任务心跳更新失败"),a?.reject(n),a=void 0,t(n)}function u(i){const f=Promise.resolve().then(()=>e(i?.progress)).then(()=>i?.resolve(),l=>{i?.reject(l),c(l)}).finally(()=>{r=void 0;const l=a;a=void 0,l&&n===void 0&&u(l)});r=f,f.catch(l=>{c(l)})}function p(i){if(!s)return _(new o.ReportJobError("closed","任务进度上报已结束"));if(n!==void 0)return _(n);a?a.progress=i:a=me(i);const f=a;return r||(a=void 0,u(f)),f.promise}return{progress:p,pulse(){s&&!r&&n===void 0&&u()},async finish(){for(s=!1;r;)await r;if(n!==void 0)throw n}}}class V extends o.ReportJobError{constructor(){super("capacity","任务结果超过独立预算,请保存文件引用")}}function ye(e){const t=e.concurrency??1,r=e.leaseMs??3e4,a=e.heartbeatMs??1e4,s=e.maxResultBytes??256*1024;if(![t,r,a,s].every(c=>Number.isSafeInteger(c)&&c>0)||a*2>r)throw new o.ReportJobError("input","并发、租约、心跳应为正整数,租约至少为心跳的两倍");if(a>2147483647)throw new o.ReportJobError("input","心跳间隔超过平台定时器上限(2147483647毫秒)");return{concurrency:t,leaseMs:r,heartbeatMs:a,maxResultBytes:s,now:()=>{const c=(e.now??Date.now)();if(!Number.isSafeInteger(c)||c<0)throw new o.ReportJobError("input","任务时钟应返回非负整数毫秒");return c}}}async function B(e,t,r){o.checkJobIdentity(t,r);const a=await e.read(t,r);if(!a)throw new o.ReportJobError("missing","报表任务不存在");return a}async function k(e,t,r,a=[]){const s={...t,...r,revision:t.revision+1};for(const n of a)delete s[n];if(!await e.compareAndSwap(t.scope,t.id,t.revision,s))throw new o.ReportJobError("conflict","报表任务已被其他请求更新");return o.cloneJob(s)}async function be(e,t,r,a){if(!t.trim()||t.length>128)throw new o.ReportJobError("input","workerId应为1–128位标识");for(const s of await e.store.candidates(a,100)){const n=s.cancelRequested?{...s,revision:s.revision+1,status:"cancelled",updatedAt:a}:{...s,revision:s.revision+1,status:"running",attempt:s.attempt+1,updatedAt:a,lease:{owner:t,expiresAt:a+r}};if(n.status==="cancelled"&&delete n.lease,await e.store.compareAndSwap(s.scope,s.id,s.revision,n))return n}}function Q(e,t,r,a){return e.status==="running"&&e.attempt===a&&e.lease?.owner===t&&e.lease.expiresAt>r}async function ve(e,t,r,a){const{scope:s,id:n}=r,c=r.lease.owner;let u;const p=he(async w=>{const g=await B(e.store,s,n),v=t.now();if(!Q(g,c,v,r.attempt))throw new o.ReportJobError("lease","报表任务租约已失效");if(g.cancelRequested){a.abort(new o.ReportJobError("closed","任务已请求取消"));return}await k(e.store,g,{updatedAt:v,lease:{owner:c,expiresAt:v+t.leaseMs},...w?{progress:w}:{}})},w=>{u=w,a.abort(w)}),i=(w,g)=>!Number.isFinite(w)||w<0||g!==void 0&&(!Number.isFinite(g)||g<w)?Promise.reject(new o.ReportJobError("input","任务进度无效")):p.progress({completed:w,...g===void 0?{}:{total:g}}),f=setInterval(()=>{p.pulse()},t.heartbeatMs);let l,d;try{const w=Object.prototype.hasOwnProperty.call(e.handlers,r.request.kind)?e.handlers[r.request.kind]:void 0;if(!w)throw new o.ReportJobError("input","报表任务处理器未注册");if(!a.signal.aborted){const g=await w(o.cloneJob(r.request.payload),{scope:s,taskId:n,signal:a.signal,reportProgress:i});if(l=JSON.parse(o.serializeJobJson(g)),o.jobByteLength(l)>t.maxResultBytes)throw new V}}catch(w){d=w??new Error("报表任务执行失败")}finally{clearInterval(f),await p.finish().catch(()=>{})}const y=await B(e.store,s,n),b=t.now();if(!Q(y,c,b,r.attempt))throw new o.ReportJobError("lease","任务租约已失效,迟到结果不会写回");const h={...y,updatedAt:b};delete h.lease,d??=u,y.cancelRequested||a.signal.aborted&&u===void 0?h.status="cancelled":d!==void 0?(h.status="failed",h.error={code:d instanceof V?"result-budget":d instanceof o.ReportJobError?d.code:"execution",message:d instanceof Error?d.message.slice(0,500):"报表任务执行失败"}):(h.status="completed",h.result=l);try{o.serializeJobJson(h)}catch{delete h.result,h.status="failed",h.error={code:"result-budget",message:"任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"}}return Re(e.store,y,h)}async function Re(e,t,r){try{return await k(e,t,r,["lease"])}catch(a){if(!(a instanceof o.ReportJobError)||a.code!=="capacity"||r.status!=="completed")throw a;return delete r.result,r.status="failed",r.error={code:"result-budget",message:"任务结果超过存储剩余预算,请保存文件引用而非文件内容"},k(e,t,r,["lease","result"])}}async function H(e,t,r,a){const s=await e.readTombstone?.(t,r);if(s){if(s.requestHash!==await o.jobRequestHash(a))throw new o.ReportJobError("conflict","相同任务ID不能提交不同内容(幂等保留期内)");return{scope:t,id:r,revision:s.revision,request:o.cloneJob(a),status:s.status,createdAt:s.createdAt,updatedAt:s.updatedAt,attempt:s.attempt,archived:!0}}}function xe(e){e={...e,handlers:{...e.handlers}};const t=ye(e),r=new Set,a=new Set;let s=!1,n=0;const c=(i,f)=>(o.checkJobIdentity(i,f),e.store.read(i,f));return{submit:async i=>{if(i={...i},o.checkJobIdentity(i.scope,i.id),!Object.prototype.hasOwnProperty.call(e.handlers,i.kind)||typeof e.handlers[i.kind]!="function")throw new o.ReportJobError("input","报表任务处理器未注册");const f={kind:i.kind,payload:JSON.parse(o.serializeJobJson(i.payload,{maxNodes:19e3,maxCharacters:75e4}))},l=await c(i.scope,i.id);if(l){if(o.serializeJobJson(l.request)!==o.serializeJobJson(f))throw new o.ReportJobError("conflict","相同任务ID不能提交不同内容");return l}const d=await H(e.store,i.scope,i.id,f);if(d)return d;const y=t.now(),b={scope:i.scope,id:i.id,revision:1,request:f,status:"queued",createdAt:y,updatedAt:y,attempt:0};if(!await e.store.compareAndSwap(i.scope,i.id,null,b)){const h=await c(i.scope,i.id);if(h&&o.serializeJobJson(h.request)===o.serializeJobJson(f))return h;const w=await H(e.store,i.scope,i.id,f);if(w)return w;throw new o.ReportJobError("conflict","报表任务提交发生冲突")}return o.cloneJob(b)},get:c,runNext:i=>{if(s)return Promise.reject(new o.ReportJobError("closed","报表任务服务已关闭"));if(n>=t.concurrency)return Promise.reject(new o.ReportJobError("capacity","报表任务执行槽位已满"));n++;const f=new AbortController;r.add(f);const l=(async()=>{try{const d=await be(e,i,t.leaseMs,t.now());return d?.status==="running"?await ve(e,t,d,f):d}finally{n--,r.delete(f)}})();return a.add(l),l.then(()=>a.delete(l),()=>a.delete(l)),l},get active(){return n},cancel:async(i,f)=>{const l=await B(e.store,i,f);return l.status!=="queued"&&l.status!=="running"?l:k(e.store,l,{updatedAt:t.now(),...l.status==="queued"?{status:"cancelled"}:{cancelRequested:!0}})},retry:async(i,f,l)=>{const d=await B(e.store,i,f);if(d.revision!==l||d.status!=="failed")throw new o.ReportJobError("conflict","仅可重试当前修订的失败任务");const y={...d,status:"queued",updatedAt:t.now()};return delete y.error,delete y.progress,k(e.store,d,y,["error","progress"])},prune:async i=>{if(!e.store.prune||!e.store.readTombstone)throw new o.ReportJobError("input","当前任务适配器未实现可选终态保留能力");return e.store.prune({...i,now:t.now()})},close:async()=>{s=!0;for(const i of r)i.abort(new o.ReportJobError("closed","任务服务正在关闭"));await Promise.allSettled([...a])}}}function Z(e,t){const r=e.assets,a=e[t];if(!(!r&&!a?.assetRenderers))return{...r,...a?.assetFailure===void 0?{}:{assetFailure:a.assetFailure},...a?.onDiagnostic===void 0?{}:{onDiagnostic:a.onDiagnostic},assetRenderers:{...r?.assetRenderers,...a?.assetRenderers},assetBudget:{...r?.assetBudget,...a?.assetBudget}}}function X(e,t){return!e||e.code!=="missing-image"||e.format!=="pdf"&&e.format!=="xlsx"?!1:typeof Z(t,e.format)?.assetRenderers?.[e.kind]=="function"}function Ie(e,t){const r=x.reviewReportTemplate(e,t),a=r.issues.filter(n=>!X(n.diagnostic,t)),s=r.samples.map(n=>({...n,diagnostics:n.diagnostics.filter(c=>!X(c,t))}));return{...r,issues:a,samples:s,ok:a.every(n=>n.severity!=="error"),artifacts:[]}}async function Se(e,t,r,a,s){const n=W({reports:{sample:{template:r,datasets:e.datasets}},assets:Z(a,t),budget:{maxRows:a.maxSampleRows??1e3,maxPages:a.maxPages??100,maxCells:a.maxCells??25e4,maxOutputBytes:a.maxOutputBytes??2e7,maxDurationMs:a.maxDurationMs??3e4}});try{const{result:c,digest:u}=await o.controlled(a.signal,a.maxDurationMs??3e4,async p=>{const i=await n.export({reportIds:["sample"],params:e.params,format:t,signal:p,fidelity:a.strictOutputs?"strict":"warn",pdf:a.pdf,xlsx:a.xlsx}),f=i.diagnostics.filter(d=>d.severity!=="info");if(a.strictOutputs&&f.length)throw new Error(`Strict ${t} encoding found fidelity issues: ${f.slice(0,3).map(d=>d.message).join("; ")}`);const l=await a.digest?.(i.bytes);return o.throwIfAborted(p),await a.onArtifact?.(e.name,i),o.throwIfAborted(p),{result:i,digest:l}});s.artifacts.push({fixture:e.name,format:t,bytes:c.bytes.byteLength,pages:c.stats.pages,...u?{digest:u}:{}}),s.issues.push(...c.diagnostics.map(p=>({code:"output",severity:a.strictOutputs||p.severity==="error"?"error":"warning",path:"$.template",fixture:e.name,message:`${t}: ${p.message}`})))}catch(c){o.throwIfAborted(a.signal),s.issues.push({code:"output",severity:"error",path:"$.template",fixture:e.name,message:`${t}: ${c instanceof Error?c.message:String(c)}`})}}async function Je(e,t={}){o.throwIfAborted(t.signal);const r=Ie(e,t);if(!r.ok)return r;const a=de.parseReportTemplate(e).template,s=[...new Set(t.formats??["pdf","xlsx"])];if(!s.length||s.some(n=>n!=="pdf"&&n!=="xlsx"))return r.issues.push({code:"output",severity:"error",path:"$.formats",message:"真实文件验收应至少选择PDF/XLSX之一"}),r.ok=!1,r;for(const n of t.fixtures??[])for(const c of s)o.throwIfAborted(t.signal),!(c!=="pdf"&&c!=="xlsx")&&await Se(n,c,a,t,r);return r.ok=r.issues.every(n=>n.severity!=="error"),r}class m extends Error{constructor(t,r){super(r),this.code=t,this.name="ReportInstanceError"}}function A(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 Ee(e,t){const r=Object.getPrototypeOf(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t)||Object.getOwnPropertySymbols(e).length)throw new m("input","实例应为普通 JSON 对象");if(t&&Object.keys(e).some(s=>s!==String(Number(s))||!Number.isSafeInteger(Number(s))||Number(s)<0||Number(s)>=e.length))throw new m("input","实例数组不能包含额外属性");if(Object.getOwnPropertyNames(e).filter(s=>!(t&&s==="length")).length!==Object.keys(e).length)throw new m("input","实例不能包含不可枚举属性")}function Ae(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 Oe(e){return e===null||typeof e=="boolean"||typeof e=="string"||typeof e=="number"&&Number.isFinite(e)}function Y(e,t){if(!Number.isSafeInteger(t)||t<1)throw new m("input","实例快照字节预算应为正安全整数");let r=0,a=0;const s=new Set;function n(u,p){if(++r>1e6||p>64)throw new m("capacity","实例节点或嵌套深度超过预算");if(typeof u=="string"&&(a+=u.length,a>t))throw new m("capacity","实例文本超过预算");if(Oe(u))return u;if(!u||typeof u!="object"||s.has(u))throw new m("input","实例只允许无循环的有限 JSON 值");const i=Array.isArray(u);Ee(u,i),s.add(u);const f=Object.create(null);for(const l of Object.keys(u)){if(a+=l.length,a>t)throw new m("capacity","实例文本超过预算");const d=Object.getOwnPropertyDescriptor(u,l);if(d.get||d.set||["__proto__","constructor","prototype"].includes(l))throw new m("input","实例不能包含访问器或危险键");d.value!==void 0&&(f[l]=n(d.value,p+1))}if(s.delete(u),i){if(Object.keys(f).length!==u.length)throw new m("input","实例数组不能稀疏或包含额外属性");return Array.from({length:u.length},(l,d)=>f[String(d)])}return f}const c=JSON.stringify(n(e,0));if(new TextEncoder().encode(c).byteLength>t)throw new m("capacity","实例快照超过单条字节预算");return c}function D(e,t=8e6){const r=JSON.parse(Y(e,t));A(r.scope,r.id);const a=new Set(["scope","id","revision","title","generatedAt","reportIds","params","templateRevisions","sourceRevisions","plan","artifacts"]);if(Object.keys(r).some(n=>!a.has(n)))throw new m("input","实例包含未知字段");Ae(r);for(const n of[r.params,r.templateRevisions,r.sourceRevisions])if(!n||typeof n!="object"||Array.isArray(n)||Object.values(n).some(c=>typeof c!="string"))throw new m("input","实例参数和修订应为字符串字典");if(r.reportIds.some(n=>!r.templateRevisions[n]))throw new m("input","每张报表都应记录生成时的模板修订");const s=G.validateRenderPlan(r.plan);if(!s.ok)throw new m("input",`实例渲染计划无效:${s.errors[0]?.path}`);return r.artifacts!==void 0&&Pe(r.artifacts),r}function Pe(e){if(!Array.isArray(e)||e.length>100)throw new m("input","实例文件列表无效");const t=new Set;for(const r of e){if(!r||typeof r.key!="string"||!r.key.trim()||r.key.length>1024||t.has(r.key)||!["pdf","xlsx"].includes(r.format)||!Number.isSafeInteger(r.bytes)||r.bytes<0||r.sha256!==void 0&&(typeof r.sha256!="string"||r.sha256.length!==64||!/^[a-f0-9]{64}$/i.test(r.sha256)))throw new m("input","实例文件应包含唯一存储键、格式、大小和可选 SHA256");t.add(r.key)}}function ee(e){const{scope:t,id:r,revision:a,title:s,generatedAt:n,reportIds:c,params:u,templateRevisions:p,sourceRevisions:i}=e;return JSON.parse(JSON.stringify({scope:t,id:r,revision:a,title:s,generatedAt:n,reportIds:c,params:u,templateRevisions:p,sourceRevisions:i}))}function ke(e){const t={maxInstances:100,maxRevisions:20,maxBytes:64e6,maxSnapshotBytes:8e6,...e};if(Object.values(t).some(r=>!Number.isSafeInteger(r)||r<1))throw new m("input","实例存储预算应为正安全整数");return t}function je(e={}){const t=ke(e),r=new Map;let a=0;return{read:async(s,n,c,u)=>{o.throwIfAborted(u),A(s,n);const p=r.get(JSON.stringify([s,n])),i=p?.get(c??p.size);return i?D(i,t.maxSnapshotBytes):void 0},list:async(s,n={})=>{o.throwIfAborted(n.signal),A(s,"list");const c=n.limit??25;if(!Number.isSafeInteger(c)||c<1||c>100)throw new m("input","实例每页数量应为 1–100");const u=Array.from(r.values(),p=>p.get(p.size)).filter(p=>p.scope===s&&(!n.after||p.id>n.after)&&(!n.reportId||p.reportIds.includes(n.reportId))).sort((p,i)=>p.id<i.id?-1:1).slice(0,c+1);return{items:u.slice(0,c).map(ee),...u.length>c?{next:u[c-1].id}:{}}},compareAndSwap:async(s,n,c,u,p)=>{o.throwIfAborted(p),A(s,n);const i=D(u,t.maxSnapshotBytes);if(i.scope!==s||i.id!==n||i.revision!==(c??0)+1)throw new m("input","实例身份或修订不一致");const f=JSON.stringify([s,n]),l=r.get(f)??new Map;if((l.size||null)!==c)return!1;const d=new TextEncoder().encode(JSON.stringify(i)).byteLength;if(l.size>=t.maxRevisions||a+d>t.maxBytes||!l.size&&r.size>=t.maxInstances)throw new m("capacity","实例存储达到预算,请使用持久化归档策略或显式调整容量");return l.set(i.revision,i),r.set(f,l),a+=d,!0}}}function te(e,t={}){const r=t.maxSnapshotBytes??8e6;if(!Number.isSafeInteger(r)||r<1)throw new m("input","实例快照字节预算应为正安全整数");return{read:e.read.bind(e),list:e.list.bind(e),save:async(a,s)=>{const n=s.expectedRevision;if(n!==null&&(!Number.isSafeInteger(n)||n<1||n>=Number.MAX_SAFE_INTEGER))throw new m("input","实例预期修订无效");const c=JSON.parse(Y(a,r)),u=D({...c,revision:(n??0)+1},r);if(o.throwIfAborted(s.signal),!await e.compareAndSwap(u.scope,u.id,n,u,s.signal))throw new m("conflict","实例已存在或已变化,请显式确认修订后保存");return u}}}function Ne(e,t){return o.serializeJobJson({reportIds:e,params:t})}function Be(e){if(!e||typeof e!="object"||Object.getOwnPropertySymbols(e).length)throw new m("input","生成请求应为普通对象");const t=Object.create(null);let r;const a=new Set(["scope","id","title","reportIds","params","expectedRevision","signal"]);for(const s of Object.getOwnPropertyNames(e)){const n=Object.getOwnPropertyDescriptor(e,s);if(!a.has(s)||!n.enumerable||n.get||n.set)throw new m("input","生成请求不能包含未知字段或访问器");s==="signal"?r=n.value:n.value!==void 0&&(t[s]=n.value)}return{signal:r,request:JSON.parse(o.serializeJobJson(t))}}function De(e){const t=JSON.parse(o.serializeJobJson(e.templateRevisions)),r=te(e.instances,{maxSnapshotBytes:e.maxSnapshotBytes});return{async generate(a){const{signal:s,request:n}=Be(a);if(A(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 P.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(o.throwIfAborted(s),((await e.instances.read(n.scope,n.id,void 0,s))?.revision??null)!==n.expectedRevision)throw new m("conflict","实例已存在或已变化,请显式确认修订后生成");const i=await e.runtime.prepare({reportIds:n.reportIds,params:c.values,signal:s});o.throwIfAborted(s);const f=Object.create(null);for(const[l,d]of Object.entries(i.revisions))d.revision!==void 0&&(f[l]=d.revision);return r.save({scope:n.scope,id:n.id,title:n.title,reportIds:n.reportIds,params:c.values,templateRevisions:u,sourceRevisions:f,generatedAt:(e.now?.()??new Date).toISOString(),plan:i.plan},{expectedRevision:n.expectedRevision,signal:s})},read:r.read,list:r.list,save:r.save}}exports.ReportJobError=o.ReportJobError;exports.ReportRuntimeError=o.ReportRuntimeError;exports.checkJobIdentity=o.checkJobIdentity;exports.cloneJob=o.cloneJob;exports.createMemoryReportJobStore=o.createMemoryReportJobStore;exports.runReportBatch=o.runReportBatch;exports.runnableJob=o.runnableJob;exports.serializeJobJson=o.serializeJobJson;exports.snapshotReportBatchCases=o.snapshotReportBatchCases;exports.validateJobRecord=o.validateJobRecord;exports.validateJobTransition=o.validateJobTransition;exports.ReportInstanceError=m;exports.checkInstanceIdentity=A;exports.createMemoryReportInstanceStore=je;exports.createReportGenerationService=De;exports.createReportInstanceManager=te;exports.createReportJobService=xe;exports.createReportRuntime=W;exports.createReportTaskQueue=we;exports.reportInstanceParameterKey=Ne;exports.reportInstanceSummary=ee;exports.reviewReportPublication=Je;exports.snapshotReportInstance=D;
|
package/dist/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as ce,
|
|
1
|
+
import { A as ce, R as k, l as le, B as ue, b as de, P as fe, n as pe, y as ge } from "./template-review-PgEe_Wr9.js";
|
|
2
2
|
import { g as F } from "./report-params-B44imUd4.js";
|
|
3
3
|
import { d as X, r as we, R as te } from "./param-validation-BlHHXs6u.js";
|
|
4
|
-
import { v as me, c as z, a as
|
|
4
|
+
import { v as me, c as z, a as S, t as x, R as A, b, d as L, s as I, e as T, j as ye, f as he } from "./batch-mRqhhhjt.js";
|
|
5
5
|
import { g as at, r as ot, h as it, i as ct, k as lt, l as ut } from "./batch-mRqhhhjt.js";
|
|
6
6
|
import { c as re } from "./validate-DbgEM1Hh.js";
|
|
7
7
|
import { r as G, c as C, n as _ } from "./task-events-Dpsvf_t2.js";
|
|
@@ -18,10 +18,10 @@ function se(e, t) {
|
|
|
18
18
|
function $(e) {
|
|
19
19
|
return e.grid?.cells.reduce((t, r) => t + r.reduce((a, s) => a + (s ? 1 + (s.children?.reduce((n, i) => n + $(i), 0) ?? 0) : 0), 0), 0) ?? 0;
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function Re(e, t, r) {
|
|
22
22
|
return e.pages.reduce((a, s) => a + s.components.reduce((n, i) => i.kind !== "list" ? n + $(i) : n + pe(i, t, r), 0), 0);
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function Se(e, t = Object.keys(e)) {
|
|
25
25
|
return se(e, t).map((r, a) => {
|
|
26
26
|
const s = t[a], n = F(e, [s]);
|
|
27
27
|
return {
|
|
@@ -46,7 +46,7 @@ function Ie(e, t) {
|
|
|
46
46
|
const r = re(e.plan);
|
|
47
47
|
if (!r.ok) throw new k("validate", `执行器返回无效计划:${r.errors[0]?.path}`);
|
|
48
48
|
const a = e.plan.pages.length, s = e.plan.pages.reduce((n, i) => n + i.components.reduce((l, f) => l + $(f), 0), 0);
|
|
49
|
-
return
|
|
49
|
+
return S(t, "maxRows", e.stats.rows), S(t, "maxPages", a), S(t, "maxCells", s), { ...e, stats: { ...e.stats, pages: a, cells: s } };
|
|
50
50
|
}
|
|
51
51
|
function U(e, t) {
|
|
52
52
|
const r = ne(e.reports, t);
|
|
@@ -75,7 +75,7 @@ function Oe(e) {
|
|
|
75
75
|
} catch (P) {
|
|
76
76
|
throw P instanceof ve ? new A("budget", P.message, "$.budget.maxRows") : P;
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
S(t, "maxRows", l), f += Re(j, v, c[p]?.pagination), S(t, "maxCells", f);
|
|
79
79
|
} })({ ...s, params: s.params ?? {}, onWarning: (p) => o.push({ code: "layout", message: p, severity: "warning" }), onQueryResult: (p, v) => {
|
|
80
80
|
Object.defineProperty(d, p, { value: { revision: v.revision, sourceToken: v.sourceToken }, enumerable: !0, writable: !0 }), o.push(...v.diagnostics ?? []);
|
|
81
81
|
} }).catch((p) => {
|
|
@@ -85,7 +85,7 @@ function Oe(e) {
|
|
|
85
85
|
const h = e.assets ? await C(s).run("assets", () => be(y, { ...e.assets, signal: s.signal })) : { plan: y, diagnostics: [] }, w = h.plan;
|
|
86
86
|
o.push(...q(h.diagnostics));
|
|
87
87
|
const g = w.pages.reduce((p, v) => p + v.components.reduce((j, P) => j + $(P), 0), 0);
|
|
88
|
-
return
|
|
88
|
+
return S(t, "maxPages", w.pages.length), S(t, "maxCells", g), { plan: w, diagnostics: o, revisions: d, stats: { rows: l, pages: w.pages.length, cells: g, durationMs: Date.now() - i } };
|
|
89
89
|
}, a = async (s) => {
|
|
90
90
|
const n = Date.now();
|
|
91
91
|
if (s.format !== "pdf" && s.format !== "xlsx") throw new k("config", "不支持的报表导出格式");
|
|
@@ -107,12 +107,12 @@ function Oe(e) {
|
|
|
107
107
|
}
|
|
108
108
|
return x(s.signal), h;
|
|
109
109
|
});
|
|
110
|
-
|
|
110
|
+
S(t, "maxOutputBytes", c.byteLength);
|
|
111
111
|
const { plan: u, ...y } = o;
|
|
112
112
|
return { ...y, bytes: c, format: s.format, contentType: s.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", stats: { ...y.stats, durationMs: Date.now() - n, outputBytes: c.byteLength } };
|
|
113
113
|
};
|
|
114
114
|
return {
|
|
115
|
-
describe: (s) =>
|
|
115
|
+
describe: (s) => Se(e.reports, s),
|
|
116
116
|
validate: (s) => ne(e.reports, s),
|
|
117
117
|
prepare: (s) => z(s.signal, t.maxDurationMs, async (n) => {
|
|
118
118
|
const { signal: i, onEvent: l, ...f } = s, o = { ...f, taskId: f.taskId ?? G() }, d = l ? (y) => _(l, y, n) : void 0, c = { ...o, signal: n, onEvent: d };
|
|
@@ -124,7 +124,7 @@ function Oe(e) {
|
|
|
124
124
|
const { signal: i, onEvent: l, ...f } = s, o = { ...f, taskId: f.taskId ?? G() }, d = l ? (y) => _(l, y, n) : void 0, c = { ...o, signal: n, onEvent: d };
|
|
125
125
|
if (C(c).runSync("validate", () => U(e, o)), o.format !== "pdf" && o.format !== "xlsx") throw new k("config", "不支持的报表导出格式");
|
|
126
126
|
const u = e.executor ? await e.executor.export(o, n, d) : await a(c);
|
|
127
|
-
return
|
|
127
|
+
return S(t, "maxRows", u.stats.rows), S(t, "maxPages", u.stats.pages), S(t, "maxCells", u.stats.cells), S(t, "maxOutputBytes", u.bytes.byteLength), { ...u, stats: { ...u.stats, outputBytes: u.bytes.byteLength } };
|
|
128
128
|
})
|
|
129
129
|
};
|
|
130
130
|
}
|
|
@@ -150,14 +150,14 @@ function Ze(e = {}) {
|
|
|
150
150
|
if (n.has(u)) throw new A("queue-full", "任务 ID 正在执行或排队");
|
|
151
151
|
const y = new AbortController();
|
|
152
152
|
let h = "queued", w, g, p, v;
|
|
153
|
-
const j = new Promise((
|
|
154
|
-
p =
|
|
153
|
+
const j = new Promise((R, O) => {
|
|
154
|
+
p = R, v = O;
|
|
155
155
|
}), P = () => {
|
|
156
156
|
c.signal?.removeEventListener("abort", H), n.delete(u);
|
|
157
|
-
}, J = (
|
|
157
|
+
}, J = (R) => {
|
|
158
158
|
if (h !== "queued" && h !== "running") return;
|
|
159
159
|
const O = h === "queued";
|
|
160
|
-
h = "cancelled", y.abort(
|
|
160
|
+
h = "cancelled", y.abort(R);
|
|
161
161
|
try {
|
|
162
162
|
x(y.signal);
|
|
163
163
|
} catch (D) {
|
|
@@ -167,19 +167,19 @@ function Ze(e = {}) {
|
|
|
167
167
|
const D = a.indexOf(N);
|
|
168
168
|
D >= 0 && a.splice(D, 1), P(), f();
|
|
169
169
|
}
|
|
170
|
-
}, H = () => J(c.signal?.reason), Q = (
|
|
171
|
-
h === "running" && (!Number.isFinite(
|
|
172
|
-
}, ie = (
|
|
173
|
-
h !== "running" || y.signal.aborted || (g = { ...
|
|
170
|
+
}, H = () => J(c.signal?.reason), Q = (R, O) => {
|
|
171
|
+
h === "running" && (!Number.isFinite(R) || R < 0 || O !== void 0 && (!Number.isFinite(O) || O < R) || (w = { completed: R, ...O === void 0 ? {} : { total: O } }));
|
|
172
|
+
}, ie = (R) => {
|
|
173
|
+
h !== "running" || y.signal.aborted || (g = { ...R, taskId: u }, R.completed !== void 0 && Q(R.completed, R.total), _(c.onEvent, g, y.signal));
|
|
174
174
|
}, N = {
|
|
175
175
|
cancel: J,
|
|
176
176
|
start: () => {
|
|
177
177
|
h === "queued" && (h = "running", s.add(N), Promise.resolve().then(() => (x(y.signal), d({ taskId: u, signal: y.signal, reportProgress: Q, onEvent: ie }))).then(
|
|
178
|
-
(
|
|
179
|
-
h === "running" && (h = "completed", p(
|
|
178
|
+
(R) => {
|
|
179
|
+
h === "running" && (h = "completed", p(R));
|
|
180
180
|
},
|
|
181
|
-
(
|
|
182
|
-
h === "running" && (h = "failed", v(
|
|
181
|
+
(R) => {
|
|
182
|
+
h === "running" && (h = "failed", v(R));
|
|
183
183
|
}
|
|
184
184
|
).finally(() => {
|
|
185
185
|
s.delete(N), P(), f();
|