@agile-team/mach-report 2.15.0 → 2.17.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 +21 -12
- package/dist/{ExcelBindingWizard-Bs43BGNp.cjs → ExcelBindingWizard-Bq6FYME6.cjs} +1 -1
- package/dist/{ExcelBindingWizard-BKH1nGNS.js → ExcelBindingWizard-Co1svTsw.js} +3 -3
- package/dist/{ParamEditor-Da4akw6V.cjs → ParamEditor-B5UZRgxv.cjs} +1 -1
- package/dist/{ParamEditor-DoAhzJsm.js → ParamEditor-DNNARyeB.js} +1 -1
- package/dist/{ReportBatchPanel-wP9m9Pj1.cjs → ReportBatchPanel-Ctvs2t_9.cjs} +1 -1
- package/dist/{ReportBatchPanel-BMf6boMA.js → ReportBatchPanel-uQh06usx.js} +3 -3
- package/dist/ReportPreview-BdQawRh0.js +4879 -0
- package/dist/ReportPreview-CJC_-j2I.cjs +6 -0
- package/dist/{ReportTemplateLibrary-Sxr3eD0J.cjs → ReportTemplateLibrary-CnP7_1pH.cjs} +1 -1
- package/dist/{ReportTemplateLibrary-C9wutIiT.js → ReportTemplateLibrary-TIL_Oj2l.js} +1 -1
- package/dist/RuleEditor-DkRjOLlr.js +2141 -0
- package/dist/RuleEditor-h5anGsDB.cjs +1 -0
- package/dist/{TemplateOutlinePanel-JTSR53vJ.cjs → TemplateOutlinePanel-BlLxRrfu.cjs} +1 -1
- package/dist/{TemplateOutlinePanel-D6Bkny59.js → TemplateOutlinePanel-BouxsuqQ.js} +1 -1
- package/dist/{TemplateReusePanel-rVuK1kTz.js → TemplateReusePanel-BEACLPaN.js} +2 -2
- package/dist/{TemplateReusePanel-Kx35S0Ql.cjs → TemplateReusePanel-yxsHSO40.cjs} +1 -1
- package/dist/{TemplateReviewPanel-B0ar9_zf.js → TemplateReviewPanel-B1OGRY2i.js} +1 -1
- package/dist/{TemplateReviewPanel-Dn6X9UmY.cjs → TemplateReviewPanel-D9Cx0m2N.cjs} +1 -1
- package/dist/analytics.cjs +1 -1
- package/dist/analytics.d.cts +65 -1
- package/dist/analytics.d.ts +65 -1
- package/dist/analytics.js +4 -4
- package/dist/artifact-integrity.json +105 -101
- package/dist/assets-BIMVwjQe.js +231 -0
- package/dist/assets-Dfs2ElxI.cjs +1 -0
- package/dist/auto-BIOmtVhk.js +240 -0
- package/dist/auto-DDHflI9v.cjs +1 -0
- package/dist/{batch-BfZHN1do.js → batch-WzDIXJAt.js} +1 -1
- package/dist/{batch-CLpELXBl.cjs → batch-z6Aw5GEY.cjs} +1 -1
- package/dist/codes.d.cts +2 -0
- package/dist/codes.d.ts +2 -0
- package/dist/component-tree-Ca6YYfHq.js +61 -0
- package/dist/component-tree-DkGLEfZC.cjs +1 -0
- package/dist/computed-BW5a8QFk.js +612 -0
- package/dist/computed-C2GD3XcE.cjs +1 -0
- package/dist/config-Dg_o8e7m.cjs +1 -0
- package/dist/{config-BVsJXSqS.js → config-XQ4qrQ7Q.js} +66 -64
- package/dist/dataset-DL83majE.js +161 -0
- package/dist/dataset-IrlXbUvh.cjs +1 -0
- package/dist/designer-D9XAxqSc.js +5178 -0
- package/dist/designer-uCDo5XSK.cjs +2 -0
- package/dist/designer.cjs +1 -1
- package/dist/designer.d.cts +178 -3
- package/dist/designer.d.ts +178 -3
- package/dist/designer.js +1 -1
- package/dist/drill-ByN8COs_.cjs +1 -0
- package/dist/{drill-ByJviLXS.js → drill-CKW3Xtfa.js} +5 -5
- package/dist/encoding-BFMFIc4r.cjs +1 -0
- package/dist/encoding-DP_Eaf0A.js +21 -0
- package/dist/{font-loader-B_UkxpzC.cjs → font-loader-7FWVlykp.cjs} +1 -1
- package/dist/{font-loader-Q3bQjmrI.js → font-loader-CQZowp0I.js} +1 -1
- package/dist/index.cjs +8 -9
- package/dist/index.d.cts +175 -1
- package/dist/index.d.ts +175 -1
- package/dist/index.js +1343 -915
- package/dist/json-snapshot-D7PE1NsU.cjs +2 -0
- package/dist/json-snapshot-DYmEe3sO.js +1779 -0
- package/dist/matrix-JLAXlux-.js +302 -0
- package/dist/matrix-gTHpDTGm.cjs +1 -0
- package/dist/{pdf-CvvrjPQg.cjs → pdf-B8JouyYv.cjs} +48 -50
- package/dist/{pdf-BwNyeGpt.js → pdf-l3ea86di.js} +2734 -2748
- package/dist/pdf.cjs +1 -1
- package/dist/pdf.d.cts +14 -0
- package/dist/pdf.d.ts +14 -0
- package/dist/pdf.js +2 -2
- package/dist/{plugin-Ca_XZG3l.js → plugin-BBp74CQZ.js} +1 -1
- package/dist/{plugin-DHO7X8z2.cjs → plugin-CtFX9PFG.cjs} +1 -1
- package/dist/prepared-CARicKYh.js +87 -0
- package/dist/prepared-Ch1x_Gog.cjs +1 -0
- package/dist/progress-BXzlVbIp.js +29 -0
- package/dist/progress-DJBd9Rb9.cjs +1 -0
- package/dist/{progress-D-OTpEav.js → progress-Hc2vxoCs.js} +2 -2
- package/dist/protocol-B5A2uom4.cjs +1 -0
- package/dist/protocol-BaiWjq5w.js +90 -0
- package/dist/record-bindings-B86Sur_y.cjs +1 -0
- package/dist/{record-bindings-Do_b3h4V.js → record-bindings-D4TuMzHs.js} +10 -11
- package/dist/{region-binding-workflow-BMhK_TjP.js → region-binding-workflow-BNasF5kz.js} +2 -2
- package/dist/{region-binding-workflow-DIYJdCUr.cjs → region-binding-workflow-O2Cni3mF.cjs} +1 -1
- package/dist/report-encoding-worker.cjs +1 -0
- package/dist/report-encoding-worker.d.ts +1 -0
- package/dist/report-encoding-worker.js +2 -0
- package/dist/rich-text-layout-ALlMoYOG.cjs +3 -0
- package/dist/rich-text-layout-Ct5WrY1g.js +102 -0
- package/dist/runtime-DakRXui3.js +170 -0
- package/dist/runtime-dL5ygIfa.cjs +1 -0
- package/dist/sbom.cdx.json +2 -2
- package/dist/server/node.d.cts +132 -1
- package/dist/server/node.d.ts +132 -1
- package/dist/server-node.cjs +5 -1
- package/dist/server-node.js +5177 -463
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +182 -2
- package/dist/server.d.ts +182 -2
- package/dist/server.js +918 -833
- package/dist/sha256-BshdOkCC.cjs +1 -0
- package/dist/sha256-DTG-Gq8i.js +157 -0
- package/dist/style-67OqfNed.js +73 -0
- package/dist/style-C22Pbv3T.cjs +1 -0
- package/dist/style.css +1 -1
- package/dist/template-catalog-Dua8h9ZA.cjs +1 -0
- package/dist/{template-catalog-j2B1MJlL.js → template-catalog-wT1fNeAP.js} +10 -10
- package/dist/{template-fragments-DcKeiylI.cjs → template-fragments-BajTajb4.cjs} +1 -1
- package/dist/{template-fragments-BGbQLGlV.js → template-fragments-DmX5XK4N.js} +2 -2
- package/dist/template-registry-CpysHAxy.cjs +1 -0
- package/dist/{template-registry-BtaKPELV.js → template-registry-u11fPd8D.js} +389 -321
- package/dist/{textwrap-DE1kgcJB.js → textwrap-BEIg2w8y.js} +1 -1
- package/dist/textwrap-BI-yJ6Wt.cjs +4 -0
- package/dist/{tree-BX380Rr7.cjs → tree-CLpxYbKa.cjs} +1 -1
- package/dist/{tree-CjVZLRw7.js → tree-DNJorJUf.js} +1 -1
- package/dist/vue/async.d.cts +174 -2
- package/dist/vue/async.d.ts +174 -2
- package/dist/vue/index.d.cts +218 -3
- package/dist/vue/index.d.ts +218 -3
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +7 -7
- package/dist/{workbook-session-BvToI-Fd.js → workbook-session-B8pNW24X.js} +153 -140
- package/dist/{workbook-session-Bjv1YCRK.cjs → workbook-session-DN5LSA5C.cjs} +12 -12
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.cts +84 -1
- package/dist/worker.d.ts +84 -1
- package/dist/worker.js +12 -157
- package/dist/xlsx-node.cjs +33 -33
- package/dist/xlsx-node.js +1282 -1289
- package/dist/xlsx.cjs +4 -3
- package/dist/xlsx.d.cts +90 -2
- package/dist/xlsx.d.ts +90 -2
- package/dist/xlsx.js +279 -259
- package/package.json +6 -3
- package/dist/ReportPreview-ChV19HBp.js +0 -4619
- package/dist/ReportPreview-DbLvvOUT.cjs +0 -6
- package/dist/RuleEditor-C_Clasvd.js +0 -2037
- package/dist/RuleEditor-XhGHK8DE.cjs +0 -1
- package/dist/assets-B9ImAi6_.cjs +0 -1
- package/dist/assets-DEaz4qsp.js +0 -124
- package/dist/batch-BaP6pWDE.cjs +0 -1
- package/dist/batch-CGyt-b2W.js +0 -273
- package/dist/capabilities-CAh2Nrue.cjs +0 -1
- package/dist/capabilities-DskCHs3V.js +0 -69
- package/dist/computed-C-4C2S5h.js +0 -521
- package/dist/computed-CGV2a809.cjs +0 -1
- package/dist/config-D10us76d.cjs +0 -1
- package/dist/data-explanation-B8MZRYVS.js +0 -16
- package/dist/data-explanation-DE55G30w.cjs +0 -1
- package/dist/dataset-BkRmwgeJ.cjs +0 -1
- package/dist/dataset-H5pFuQGU.js +0 -121
- package/dist/defaults-DXhiM1ZD.js +0 -10
- package/dist/defaults-xhmcLLrf.cjs +0 -1
- package/dist/designer-2bDlcNXQ.js +0 -5136
- package/dist/designer-BT7XCdbW.cjs +0 -2
- package/dist/drill-DYTxuL3A.cjs +0 -1
- package/dist/grid-strokes-Cr7DwUux.cjs +0 -1
- package/dist/grid-strokes-DyyG1q_o.js +0 -53
- package/dist/json-snapshot-DFb2eWkf.js +0 -1416
- package/dist/json-snapshot-WWSGlaHG.cjs +0 -2
- package/dist/matrix-CGRGkn5s.js +0 -112
- package/dist/matrix-gEO7ZM_u.cjs +0 -1
- package/dist/prepared-CFy9B75C.cjs +0 -1
- package/dist/prepared-ajM-H-9B.js +0 -69
- package/dist/record-bindings-By_UKZ2g.cjs +0 -1
- package/dist/render-plan-7xpGrCEl.cjs +0 -1
- package/dist/render-plan-Ck6koX9L.js +0 -13
- package/dist/sha256-ArEYjaTI.cjs +0 -1
- package/dist/sha256-DPEuJ3nh.js +0 -155
- package/dist/style-CQ1PK8ZB.js +0 -67
- package/dist/style-UgIJSA1F.cjs +0 -1
- package/dist/template-catalog-FJE_c9Qe.cjs +0 -1
- package/dist/template-registry-Co1zPq5e.cjs +0 -1
- package/dist/textwrap-CWHyzkBH.cjs +0 -4
package/dist/server.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Ae=Object.create;var G=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Te=Object.getPrototypeOf,Je=Object.prototype.hasOwnProperty;var Be=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Pe(t))!Je.call(e,n)&&n!==r&&G(e,n,{get:()=>t[n],enumerable:!(s=Oe(t,n))||s.enumerable});return e};var C=(e,t,r)=>(r=e!=null?Ae(Te(e)):{},Be(t||!e||!e.__esModule?G(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("./json-snapshot-WWSGlaHG.cjs"),U=require("./report-params-WDGrA4oP.cjs"),$=require("./param-validation-C3HlcLLO.cjs"),p=require("./sha256-ArEYjaTI.cjs"),B=require("./template-registry-Co1zPq5e.cjs"),je=require("./tree-BX380Rr7.cjs"),Q=require("./assets-B9ImAi6_.cjs"),T=require("./prepared-CFy9B75C.cjs"),w=require("./batch-CLpELXBl.cjs"),le=require("./template-catalog-FJE_c9Qe.cjs"),fe=require("./record-bindings-By_UKZ2g.cjs"),ue=require("./dataset-BkRmwgeJ.cjs"),pe=require("./media-B7vnpD8k.cjs");function z(e=[]){return e.map(({code:t,message:r,severity:s,pageIndex:n,componentIndex:o})=>({code:t,message:r,severity:s,path:o<0?`$.pages.${n}`:`$.pages.${n}.components.${o}`}))}async function W(e,t,r=Date.now()){const s=e.prepared,n=e.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;p.throwIfAborted(e.signal);const o=e.pdf?.customFontFaces??(e.pdf?.customFontBytes?{regular:e.pdf.customFontBytes}:void 0),a=n&&o?n.createFontBytesMeasurer(o):void 0,d=x.createReportTaskReporter(e),c=await d.run("encode",async()=>{let l;if(e.format==="pdf"){p.throwIfAborted(e.signal);const u=await n.renderPlanToPdf(s.plan,{...e.pdf,...a?{measurer:a}:{},fidelity:e.fidelity,signal:e.signal,onProgress:(m,g)=>d.progress("encode",m,g)});l=u.bytes,s.diagnostics.push(...z(u.diagnostics)),s.diagnostics.push(...u.fidelityWarnings.map(m=>({code:"pdf-fidelity",message:m,severity:"warning"})),...u.pageErrors.map(m=>({code:"pdf-page",message:m,severity:"error"}))),u.unsupportedTextCount&&s.diagnostics.push({code:"pdf-font",message:`${u.unsupportedTextCount} 段文本包含当前字体不支持的字符`,severity:"warning"})}else{const{renderPlanToXlsx:u}=await import("@agile-team/mach-report/xlsx");p.throwIfAborted(e.signal);const m=await u(s.plan,{...e.xlsx,fidelity:e.fidelity,signal:e.signal,onProgress:(g,v)=>d.progress("encode",g,v)});l=new Uint8Array(m.buffer),s.diagnostics.push(...z(m.diagnostics)),s.diagnostics.push(...m.warnings.map(g=>({code:"xlsx-fidelity",message:g,severity:"warning"})))}return p.throwIfAborted(e.signal),l});p.assertBudget(t,"maxOutputBytes",c.byteLength);const{plan:i,...f}=s;return{...f,bytes:c,format:e.format,contentType:e.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",stats:{...f.stats,durationMs:Date.now()-r,outputBytes:c.byteLength}}}function Z(e){return{...e,reportIds:[...e.reportIds],...e.params?{params:{...e.params}}:{}}}function we(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 V(e){return e.grid?.cells.reduce((t,r)=>t+r.reduce((s,n)=>s+(n?1+(n.children?.reduce((o,a)=>o+V(a),0)??0):0),0),0)??0}function Ne(e,t,r){return e.pages.reduce((s,n)=>s+n.components.reduce((o,a)=>a.kind!=="list"?o+V(a):o+x.estimateListLayoutCells(a,t,r),0),0)}function $e(e,t=Object.keys(e)){return we(e,t).map((r,s)=>{const n=t[s],o=U.getReportParamDefs(e,[n]);return{id:n,params:JSON.parse(JSON.stringify(o)),paramsSchema:$.reportParamsJsonSchema(o),datasetsSchema:Object.fromEntries(Object.entries(r.dataSchema??{}).map(([a,d])=>[a,x.templateDatasetJsonSchema(typeof r.template=="function"?void 0:r.template,a,d)])),capabilities:{save:!!r.provider?.save,export:!!r.provider?.export,templates:!!r.provider?.templates}}})}function ge(e,t){we(e,t.reportIds);const r=$.validateReportParams(U.getReportParamDefs(e,t.reportIds),t.params),s=t.reportIds.flatMap(o=>$.validateReportParams(U.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 Y(e,t){const r=B.validateRenderPlan(e.plan);if(!r.ok)throw new x.ReportSourceError("validate",`执行器返回无效计划:${r.errors[0]?.path}`);const s=e.plan.pages.length,n=e.plan.pages.reduce((o,a)=>o+a.components.reduce((d,c)=>d+V(c),0),0);return p.assertBudget(t,"maxRows",e.stats.rows),p.assertBudget(t,"maxPages",s),p.assertBudget(t,"maxCells",n),{...e,stats:{...e.stats,pages:s,cells:n}}}function ee(e,t){const r=ge(e.reports,t);if(!r.ok)throw new $.ReportParamValidationError(r.issues)}function _(e){const t={maxRows:1e5,maxPages:1e4,maxCells:2e6,maxOutputBytes:1e8,maxPreparedBytes:64e6,maxDurationMs:12e4,...e.budget};p.validateBudget(t);const r=async(n,o)=>{const a=Date.now();let d=0,c=0;const i=[],f={},l=[],u=Object.fromEntries(Object.entries(e.reports).map(([I,R])=>[I,{...R,pagination:{...e.pagination,...R.pagination,...o?{measurer:o}:{}},dataValidation:{...R.dataValidation,maxRows:Math.min(t.maxRows??1e5,R.dataValidation?.maxRows??1/0),maxCells:Math.min(t.maxCells??2e6,R.dataValidation?.maxCells??1/0)}}])),g=await x.createReportSource(u,{maxPages:t.maxPages,maxCells:t.maxCells,onDatasets:(I,R,A)=>{try{d+=x.templateDatasetRowCount(A,R,{maxRows:t.maxRows,signal:n.signal})}catch(P){throw P instanceof je.TreeRowLimitError?new p.ReportRuntimeError("budget",P.message,"$.budget.maxRows"):P}p.assertBudget(t,"maxRows",d),c+=Ne(A,R,u[I]?.pagination),p.assertBudget(t,"maxCells",c)}})({...n,params:n.params??{},onWarning:I=>i.push({code:"layout",message:I,severity:"warning"}),onQueryResult:(I,R,A=0)=>{const P=x.reportOccurrenceScope(A,I);Object.defineProperty(f,I,{value:{revision:R.revision,sourceToken:R.sourceToken},enumerable:!0,writable:!0}),l.push({reportId:I,reportIndex:A,reportScope:P,...R.revision===void 0?{}:{revision:R.revision},...R.sourceToken===void 0?{}:{sourceToken:R.sourceToken}}),i.push(...(R.diagnostics??[]).map(O=>({...O,...O.target?{target:{...O.target,reportScope:P,...O.target.tableId?{tableId:JSON.stringify([A,I,O.target.tableId])}:{}}}:{}})))}}).catch(I=>{throw I instanceof x.ReportSourceError&&I.cause instanceof x.PaginatePageLimitError?new p.ReportRuntimeError("budget",I.cause.message,"$.budget.maxPages"):I instanceof x.ReportSourceError&&I.cause instanceof x.PaginateCellLimitError?new p.ReportRuntimeError("budget",I.cause.message,"$.budget.maxCells"):I});p.throwIfAborted(n.signal);const v=e.assets?await x.createReportTaskReporter(n).run("assets",()=>Q.resolvePlanAssets(g,{...e.assets,signal:n.signal})):{plan:g,diagnostics:[]},b=v.plan;i.push(...z(v.diagnostics));const h=b.pages.reduce((I,R)=>I+R.components.reduce((A,P)=>A+V(P),0),0);p.assertBudget(t,"maxPages",b.pages.length),p.assertBudget(t,"maxCells",h);const S=T.reportFontFingerprint(n.pdf),N=e.pagination?.measurer||Object.values(e.reports).some(I=>I.pagination?.measurer);return{plan:b,diagnostics:i,revisions:f,sources:l,layout:{textMetrics:S?"font-bytes":N?"provided":"heuristic",...S?{fontFingerprint:S}:{}},stats:{rows:d,pages:b.pages.length,cells:h,durationMs:Date.now()-a}}},s=async n=>{const o=Date.now();if(n.format!=="pdf"&&n.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const a=n.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;p.throwIfAborted(n.signal);const d=n.pdf?.customFontFaces??(n.pdf?.customFontBytes?{regular:n.pdf.customFontBytes}:void 0),c=a&&d?a.createFontBytesMeasurer(d):void 0,i=await r(n,c);return p.throwIfAborted(n.signal),W({...n,prepared:i},t,o)};return{describe:n=>$e(e.reports,n),validate:n=>ge(e.reports,n),prepare:n=>p.controlled(n.signal,t.maxDurationMs,async o=>{const{signal:a,onEvent:d,...c}=Z(n),i={...c,...c.pdf?{pdf:T.snapshotPdfFonts(c.pdf)}:{},taskId:c.taskId??x.reportTaskId()},f=d?v=>x.notifyReportTaskEvent(d,v,o):void 0,l={...i,signal:o,onEvent:f};x.createReportTaskReporter(l).runSync("validate",()=>ee(e,i));let u;const m=i.pdf?.customFontFaces??(i.pdf?.customFontBytes?{regular:i.pdf.customFontBytes}:void 0);if(!e.executor&&m){const v=await import("@agile-team/mach-report/pdf");p.throwIfAborted(o),u=v.createFontBytesMeasurer(m)}const g=e.executor?await e.executor.prepare(i,o,f):await r(l,u);return Y(g,t)}),exportPrepared:n=>p.controlled(n.signal,t.maxDurationMs,async o=>{const a=Date.now(),{signal:d,onEvent:c,...i}=n,f=Y(T.snapshotPreparedReport(n.prepared,t.maxPreparedBytes??64e6,o),t),l={...i,xlsx:T.snapshotXlsxOptions(i.xlsx),prepared:f,...i.pdf?{pdf:T.snapshotPdfFonts(i.pdf)}:{},taskId:i.taskId??x.reportTaskId()};if(l.format!=="pdf"&&l.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const u=c?g=>x.notifyReportTaskEvent(c,g,o):void 0;if(e.executor){if(!e.executor.exportPrepared)throw new x.ReportSourceError("config","执行器未实现 exportPrepared;请升级执行器或显式使用本地运行时");const g=await e.executor.exportPrepared(l,o,u);return p.assertBudget(t,"maxRows",g.stats.rows),p.assertBudget(t,"maxPages",g.stats.pages),p.assertBudget(t,"maxCells",g.stats.cells),p.assertBudget(t,"maxOutputBytes",g.bytes.byteLength),{...g,stats:{...g.stats,outputBytes:g.bytes.byteLength}}}const m={...l,signal:o,onEvent:u};if(x.createReportTaskReporter(m).runSync("validate",()=>T.checkPreparedFont(m)),e.assets){const g=await x.createReportTaskReporter(m).run("assets",()=>Q.resolvePlanAssets(f.plan,{...e.assets,signal:o}));f.plan=g.plan,f.diagnostics.push(...z(g.diagnostics))}return W(m,t,a)}),export:n=>p.controlled(n.signal,t.maxDurationMs,async o=>{const{signal:a,onEvent:d,...c}=Z(n),i={...c,xlsx:T.snapshotXlsxOptions(c.xlsx),...c.pdf?{pdf:T.snapshotPdfFonts(c.pdf)}:{},taskId:c.taskId??x.reportTaskId()},f=d?m=>x.notifyReportTaskEvent(d,m,o):void 0,l={...i,signal:o,onEvent:f};if(x.createReportTaskReporter(l).runSync("validate",()=>ee(e,i)),i.format!=="pdf"&&i.format!=="xlsx")throw new x.ReportSourceError("config","不支持的报表导出格式");const u=e.executor?await e.executor.export(i,o,f):await s(l);return p.assertBudget(t,"maxRows",u.stats.rows),p.assertBudget(t,"maxPages",u.stats.pages),p.assertBudget(t,"maxCells",u.stats.cells),p.assertBudget(t,"maxOutputBytes",u.bytes.byteLength),{...u,stats:{...u.stats,outputBytes:u.bytes.byteLength}}})}}function Me(e={}){const t=e.concurrency??1,r=e.maxQueued??20;if(!Number.isSafeInteger(t)||t<1||!Number.isSafeInteger(r)||r<0)throw new p.ReportRuntimeError("budget","队列并发应为正整数,排队上限应为非负整数");const s=[],n=new Set,o=new Set;let a=!1,d=0;const c=()=>{for(;!a&&n.size<t&&s.length;)s.shift().start()};return{get active(){return n.size},get pending(){return s.length},enqueue:(f,l={})=>{if(a)throw new p.ReportRuntimeError("closed","任务队列已关闭");if(p.throwIfAborted(l.signal),n.size>=t&&s.length>=r)throw new p.ReportRuntimeError("queue-full","报表任务队列已满");const u=l.id??`report-${++d}`;if(o.has(u))throw new p.ReportRuntimeError("queue-full","任务 ID 正在执行或排队");const m=new AbortController;let g="queued",v,b,h,S;const N=new Promise((E,J)=>{h=E,S=J}),I=()=>{l.signal?.removeEventListener("abort",A),o.delete(u)},R=E=>{if(g!=="queued"&&g!=="running")return;const J=g==="queued";g="cancelled",m.abort(E);try{p.throwIfAborted(m.signal)}catch(D){S(D)}if(J){const D=s.indexOf(k);D>=0&&s.splice(D,1),I(),c()}},A=()=>R(l.signal?.reason),P=(E,J)=>{g==="running"&&(!Number.isFinite(E)||E<0||J!==void 0&&(!Number.isFinite(J)||J<E)||(v={completed:E,...J===void 0?{}:{total:J}}))},O=E=>{g!=="running"||m.signal.aborted||(b={...E,taskId:u},E.completed!==void 0&&P(E.completed,E.total),x.notifyReportTaskEvent(l.onEvent,b,m.signal))},k={cancel:R,start:()=>{g==="queued"&&(g="running",n.add(k),Promise.resolve().then(()=>(p.throwIfAborted(m.signal),f({taskId:u,signal:m.signal,reportProgress:P,onEvent:O}))).then(E=>{g==="running"&&(g="completed",h(E))},E=>{g==="running"&&(g="failed",S(E))}).finally(()=>{n.delete(k),I(),c()}))}};return o.add(u),l.signal?.addEventListener("abort",A,{once:!0}),l.signal?.aborted?R(l.signal.reason):n.size<t?k.start():s.push(k),{id:u,get status(){return g},get progress(){return v},get event(){return b},result:N,cancel:R}},close:(f={})=>{a=!0;for(const l of[...s])l.cancel(new p.ReportRuntimeError("closed","任务队列已关闭"));if(f.cancelRunning)for(const l of n)l.cancel(new p.ReportRuntimeError("closed","任务队列已关闭"))}}}function De(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 te(e){const t=Promise.reject(e);return t.catch(()=>{}),t}function Ce(e,t){let r,s,n=!0,o;function a(i){o??=i??new Error("任务心跳更新失败"),s?.reject(o),s=void 0,t(o)}function d(i){const f=Promise.resolve().then(()=>e(i?.progress)).then(()=>i?.resolve(),l=>{i?.reject(l),a(l)}).finally(()=>{r=void 0;const l=s;s=void 0,l&&o===void 0&&d(l)});r=f,f.catch(l=>{a(l)})}function c(i){if(!n)return te(new w.ReportJobError("closed","任务进度上报已结束"));if(o!==void 0)return te(o);s?s.progress=i:s=De(i);const f=s;return r||(s=void 0,d(f)),f.promise}return{progress:c,pulse(){n&&!r&&o===void 0&&d()},async finish(){for(n=!1;r;)await r;if(o!==void 0)throw o}}}class re extends w.ReportJobError{constructor(){super("capacity","任务结果超过独立预算,请保存文件引用")}}function Fe(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(a=>Number.isSafeInteger(a)&&a>0)||s*2>r)throw new w.ReportJobError("input","并发、租约、心跳应为正整数,租约至少为心跳的两倍");if(s>2147483647)throw new w.ReportJobError("input","心跳间隔超过平台定时器上限(2147483647毫秒)");return{concurrency:t,leaseMs:r,heartbeatMs:s,maxResultBytes:n,now:()=>{const a=(e.now??Date.now)();if(!Number.isSafeInteger(a)||a<0)throw new w.ReportJobError("input","任务时钟应返回非负整数毫秒");return a}}}async function q(e,t,r){w.checkJobIdentity(t,r);const s=await e.read(t,r);if(!s)throw new w.ReportJobError("missing","报表任务不存在");return s}async function M(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 w.ReportJobError("conflict","报表任务已被其他请求更新");return w.cloneJob(n)}async function ze(e,t,r,s){if(!t.trim()||t.length>128)throw new w.ReportJobError("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 se(e,t,r,s){return e.status==="running"&&e.attempt===s&&e.lease?.owner===t&&e.lease.expiresAt>r}async function qe(e,t,r,s){const{scope:n,id:o}=r,a=r.lease.owner;let d;const c=Ce(async b=>{const h=await q(e.store,n,o),S=t.now();if(!se(h,a,S,r.attempt))throw new w.ReportJobError("lease","报表任务租约已失效");if(h.cancelRequested){s.abort(new w.ReportJobError("closed","任务已请求取消"));return}await M(e.store,h,{updatedAt:S,lease:{owner:a,expiresAt:S+t.leaseMs},...b?{progress:b}:{}})},b=>{d=b,s.abort(b)}),i=(b,h)=>!Number.isFinite(b)||b<0||h!==void 0&&(!Number.isFinite(h)||h<b)?Promise.reject(new w.ReportJobError("input","任务进度无效")):c.progress({completed:b,...h===void 0?{}:{total:h}}),f=setInterval(()=>{c.pulse()},t.heartbeatMs);let l,u;try{const b=Object.prototype.hasOwnProperty.call(e.handlers,r.request.kind)?e.handlers[r.request.kind]:void 0;if(!b)throw new w.ReportJobError("input","报表任务处理器未注册");if(!s.signal.aborted){const h=await b(w.cloneJob(r.request.payload),{scope:n,taskId:o,attempt:r.attempt,executionToken:JSON.stringify([n,o,r.attempt]),signal:s.signal,reportProgress:i});if(l=JSON.parse(w.serializeJobJson(h)),w.jobByteLength(l)>t.maxResultBytes)throw new re}}catch(b){u=b??new Error("报表任务执行失败")}finally{clearInterval(f),await c.finish().catch(()=>{})}const m=await q(e.store,n,o),g=t.now();if(!se(m,a,g,r.attempt))throw new w.ReportJobError("lease","任务租约已失效,迟到结果不会写回");const v={...m,updatedAt:g};delete v.lease,u??=d,m.cancelRequested||s.signal.aborted&&d===void 0?v.status="cancelled":u!==void 0?(v.status="failed",v.error={code:u instanceof re?"result-budget":u instanceof w.ReportJobError?u.code:"execution",message:u instanceof Error?u.message.slice(0,500):"报表任务执行失败"}):(v.status="completed",v.result=l);try{w.serializeJobJson(v)}catch{delete v.result,v.status="failed",v.error={code:"result-budget",message:"任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"}}return Le(e.store,m,v)}async function Le(e,t,r){try{return await M(e,t,r,["lease"])}catch(s){if(!(s instanceof w.ReportJobError)||s.code!=="capacity"||r.status!=="completed")throw s;return delete r.result,r.status="failed",r.error={code:"result-budget",message:"任务结果超过存储剩余预算,请保存文件引用而非文件内容"},M(e,t,r,["lease","result"])}}async function ne(e,t,r,s){const n=await e.readTombstone?.(t,r);if(n){if(n.requestHash!==await w.jobRequestHash(s))throw new w.ReportJobError("conflict","相同任务ID不能提交不同内容(幂等保留期内)");return{scope:t,id:r,revision:n.revision,request:w.cloneJob(s),status:n.status,createdAt:n.createdAt,updatedAt:n.updatedAt,attempt:n.attempt,archived:!0}}}function Ve(e){e={...e,handlers:{...e.handlers}};const t=Fe(e),r=new Set,s=new Set;let n=!1,o=0;const a=(i,f)=>(w.checkJobIdentity(i,f),e.store.read(i,f));return{submit:async i=>{if(i={...i},w.checkJobIdentity(i.scope,i.id),!Object.prototype.hasOwnProperty.call(e.handlers,i.kind)||typeof e.handlers[i.kind]!="function")throw new w.ReportJobError("input","报表任务处理器未注册");const f={kind:i.kind,payload:JSON.parse(w.serializeJobJson(i.payload,{maxNodes:19e3,maxCharacters:75e4}))},l=await a(i.scope,i.id);if(l){if(w.serializeJobJson(l.request)!==w.serializeJobJson(f))throw new w.ReportJobError("conflict","相同任务ID不能提交不同内容");return l}const u=await ne(e.store,i.scope,i.id,f);if(u)return u;const m=t.now(),g={scope:i.scope,id:i.id,revision:1,request:f,status:"queued",createdAt:m,updatedAt:m,attempt:0};if(!await e.store.compareAndSwap(i.scope,i.id,null,g)){const v=await a(i.scope,i.id);if(v&&w.serializeJobJson(v.request)===w.serializeJobJson(f))return v;const b=await ne(e.store,i.scope,i.id,f);if(b)return b;throw new w.ReportJobError("conflict","报表任务提交发生冲突")}return w.cloneJob(g)},get:a,runNext:i=>{if(n)return Promise.reject(new w.ReportJobError("closed","报表任务服务已关闭"));if(o>=t.concurrency)return Promise.reject(new w.ReportJobError("capacity","报表任务执行槽位已满"));o++;const f=new AbortController;r.add(f);const l=(async()=>{try{const u=await ze(e,i,t.leaseMs,t.now());return u?.status==="running"?await qe(e,t,u,f):u}finally{o--,r.delete(f)}})();return s.add(l),l.then(()=>s.delete(l),()=>s.delete(l)),l},get active(){return o},cancel:async(i,f)=>{const l=await q(e.store,i,f);return l.status!=="queued"&&l.status!=="running"?l:M(e.store,l,{updatedAt:t.now(),...l.status==="queued"?{status:"cancelled"}:{cancelRequested:!0}})},retry:async(i,f,l)=>{const u=await q(e.store,i,f);if(u.revision!==l||u.status!=="failed")throw new w.ReportJobError("conflict","仅可重试当前修订的失败任务");const m={...u,status:"queued",updatedAt:t.now()};return delete m.error,delete m.progress,M(e.store,u,m,["error","progress"])},prune:async i=>{if(!e.store.prune||!e.store.readTombstone)throw new w.ReportJobError("input","当前任务适配器未实现可选终态保留能力");return e.store.prune({...i,now:t.now()})},close:async()=>{n=!0;for(const i of r)i.abort(new w.ReportJobError("closed","任务服务正在关闭"));await Promise.allSettled([...s])}}}function me(e,t){const r=e.assets,s=e[t];if(!(!r&&!s?.assetRenderers))return{...r,...s?.assetFailure===void 0?{}:{assetFailure:s.assetFailure},...s?.onDiagnostic===void 0?{}:{onDiagnostic:s.onDiagnostic},assetRenderers:{...r?.assetRenderers,...s?.assetRenderers},assetBudget:{...r?.assetBudget,...s?.assetBudget}}}function oe(e,t){return!e||e.code!=="missing-image"||e.format!=="pdf"&&e.format!=="xlsx"?!1:typeof me(t,e.format)?.assetRenderers?.[e.kind]=="function"}function _e(e,t){const r=le.reviewReportTemplate(e,t),s=r.issues.filter(o=>!oe(o.diagnostic,t)),n=r.samples.map(o=>({...o,diagnostics:o.diagnostics.filter(a=>!oe(a,t))}));return{...r,issues:s,samples:n,ok:s.every(o=>o.severity!=="error"),artifacts:[]}}async function He(e,t,r,s,n){const o=_({reports:{sample:{template:r,datasets:e.datasets}},assets:me(s,t),budget:{maxRows:s.maxSampleRows??1e3,maxPages:s.maxPages??100,maxCells:s.maxCells??25e4,maxOutputBytes:s.maxOutputBytes??2e7,maxDurationMs:s.maxDurationMs??3e4}});try{const{result:a,digest:d}=await p.controlled(s.signal,s.maxDurationMs??3e4,async c=>{const i=await o.export({reportIds:["sample"],params:e.params,format:t,signal:c,fidelity:s.strictOutputs?"strict":"warn",pdf:s.pdf,xlsx:s.xlsx}),f=i.diagnostics.filter(u=>u.severity!=="info");if(s.strictOutputs&&f.length)throw new Error(`Strict ${t} encoding found fidelity issues: ${f.slice(0,3).map(u=>u.message).join("; ")}`);const l=await s.digest?.(i.bytes);return p.throwIfAborted(c),await s.onArtifact?.(e.name,i),p.throwIfAborted(c),{result:i,digest:l}});n.artifacts.push({fixture:e.name,format:t,bytes:a.bytes.byteLength,pages:a.stats.pages,...d?{digest:d}:{}}),n.issues.push(...a.diagnostics.map(c=>({code:"output",severity:s.strictOutputs||c.severity==="error"?"error":"warning",path:"$.template",fixture:e.name,message:`${t}: ${c.message}`})))}catch(a){p.throwIfAborted(s.signal),n.issues.push({code:"output",severity:"error",path:"$.template",fixture:e.name,message:`${t}: ${a instanceof Error?a.message:String(a)}`})}}async function Ue(e,t={}){p.throwIfAborted(t.signal);const r=_e(e,t);if(!r.ok)return r;const s=B.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 a of n)p.throwIfAborted(t.signal),!(a!=="pdf"&&a!=="xlsx")&&await He(o,a,s,t,r);return r.ok=r.issues.every(o=>o.severity!=="error"),r}class y extends Error{constructor(t,r){super(r),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 y("input","实例范围应非空,ID 应为安全标识")}function Ke(e,t){const r=Object.getPrototypeOf(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t)||Object.getOwnPropertySymbols(e).length)throw new y("input","实例应为普通 JSON 对象");if(t&&Object.keys(e).some(n=>n!==String(Number(n))||!Number.isSafeInteger(Number(n))||Number(n)<0||Number(n)>=e.length))throw new y("input","实例数组不能包含额外属性");if(Object.getOwnPropertyNames(e).filter(n=>!(t&&n==="length")).length!==Object.keys(e).length)throw new y("input","实例不能包含不可枚举属性")}function Xe(e){if(!Number.isSafeInteger(e.revision)||e.revision<1||typeof e.title!="string"||!e.title.trim()||e.title.length>512)throw new y("input","实例修订或标题无效");if(typeof e.generatedAt!="string"||!Number.isFinite(Date.parse(e.generatedAt))||new Date(e.generatedAt).toISOString()!==e.generatedAt)throw new y("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 y("input","实例报表 ID 应非空且唯一")}function Ge(e){return e===null||typeof e=="boolean"||typeof e=="string"||typeof e=="number"&&Number.isFinite(e)}function he(e,t){if(!Number.isSafeInteger(t)||t<1)throw new y("input","实例快照字节预算应为正安全整数");let r=0,s=0;const n=new Set;function o(d,c){if(++r>1e6||c>64)throw new y("capacity","实例节点或嵌套深度超过预算");if(typeof d=="string"&&(s+=d.length,s>t))throw new y("capacity","实例文本超过预算");if(Ge(d))return d;if(!d||typeof d!="object"||n.has(d))throw new y("input","实例只允许无循环的有限 JSON 值");const i=Array.isArray(d);Ke(d,i),n.add(d);const f=Object.create(null);for(const l of Object.keys(d)){if(s+=l.length,s>t)throw new y("capacity","实例文本超过预算");const u=Object.getOwnPropertyDescriptor(d,l);if(u.get||u.set||["__proto__","constructor","prototype"].includes(l))throw new y("input","实例不能包含访问器或危险键");u.value!==void 0&&(f[l]=o(u.value,c+1))}if(n.delete(d),i){if(Object.keys(f).length!==d.length)throw new y("input","实例数组不能稀疏或包含额外属性");return Array.from({length:d.length},(l,u)=>f[String(u)])}return f}const a=JSON.stringify(o(e,0));if(new TextEncoder().encode(a).byteLength>t)throw new y("capacity","实例快照超过单条字节预算");return a}function L(e,t=8e6){const r=JSON.parse(he(e,t));j(r.scope,r.id);const s=new Set(["scope","id","revision","title","generatedAt","reportIds","params","templateRevisions","sourceRevisions","plan","artifacts","output"]);if(Object.keys(r).some(o=>!s.has(o)))throw new y("input","实例包含未知字段");Xe(r);for(const o of[r.params,r.templateRevisions,r.sourceRevisions])if(!o||typeof o!="object"||Array.isArray(o)||Object.values(o).some(a=>typeof a!="string"))throw new y("input","实例参数和修订应为字符串字典");if(r.reportIds.some(o=>!r.templateRevisions[o]))throw new y("input","每张报表都应记录生成时的模板修订");const n=B.validateRenderPlan(r.plan);if(!n.ok)throw new y("input",`实例渲染计划无效:${n.errors[0]?.path}`);if(r.output!==void 0){if(!r.output||Object.keys(r.output).some(o=>!["stats","diagnostics","layout","sources"].includes(o)))throw new y("input","实例输出元数据只允许统计、诊断和字体度量;不保存来源令牌");if(T.validatePreparedMetadata({...r.output,plan:r.plan,revisions:{}}),r.output.sources?.some(o=>"sourceToken"in o))throw new y("input","实例来源清单不保存来源令牌")}return r.artifacts!==void 0&&Qe(r.artifacts),r}function Qe(e){if(!Array.isArray(e)||e.length>100)throw new y("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 y("input","实例文件应包含唯一存储键、格式、大小和可选 SHA256");t.add(r.key)}}function ye(e){const{scope:t,id:r,revision:s,title:n,generatedAt:o,reportIds:a,params:d,templateRevisions:c,sourceRevisions:i}=e;return JSON.parse(JSON.stringify({scope:t,id:r,revision:s,title:n,generatedAt:o,reportIds:a,params:d,templateRevisions:c,sourceRevisions:i}))}function We(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 y("input","实例存储预算应为正安全整数");return t}function Ze(e={}){const t=We(e),r=new Map;let s=0;return{read:async(n,o,a,d)=>{p.throwIfAborted(d),j(n,o);const c=r.get(JSON.stringify([n,o])),i=c?.get(a??c.size);return i?L(i,t.maxSnapshotBytes):void 0},list:async(n,o={})=>{p.throwIfAborted(o.signal),j(n,"list");const a=o.limit??25;if(!Number.isSafeInteger(a)||a<1||a>100)throw new y("input","实例每页数量应为 1–100");const d=Array.from(r.values(),c=>c.get(c.size)).filter(c=>c.scope===n&&(!o.after||c.id>o.after)&&(!o.reportId||c.reportIds.includes(o.reportId))).sort((c,i)=>c.id<i.id?-1:1).slice(0,a+1);return{items:d.slice(0,a).map(ye),...d.length>a?{next:d[a-1].id}:{}}},compareAndSwap:async(n,o,a,d,c)=>{p.throwIfAborted(c),j(n,o);const i=L(d,t.maxSnapshotBytes);if(i.scope!==n||i.id!==o||i.revision!==(a??0)+1)throw new y("input","实例身份或修订不一致");const f=JSON.stringify([n,o]),l=r.get(f)??new Map;if((l.size||null)!==a)return!1;const u=new TextEncoder().encode(JSON.stringify(i)).byteLength;if(l.size>=t.maxRevisions||s+u>t.maxBytes||!l.size&&r.size>=t.maxInstances)throw new y("capacity","实例存储达到预算,请使用持久化归档策略或显式调整容量");return l.set(i.revision,i),r.set(f,l),s+=u,!0}}}function be(e,t={}){const r=t.maxSnapshotBytes??8e6;if(!Number.isSafeInteger(r)||r<1)throw new y("input","实例快照字节预算应为正安全整数");return{read:e.read.bind(e),list:e.list.bind(e),save:async(s,n)=>{const o=n.expectedRevision;if(o!==null&&(!Number.isSafeInteger(o)||o<1||o>=Number.MAX_SAFE_INTEGER))throw new y("input","实例预期修订无效");const a=JSON.parse(he(s,r)),d=L({...a,revision:(o??0)+1},r);if(p.throwIfAborted(n.signal),!await e.compareAndSwap(d.scope,d.id,o,d,n.signal))throw new y("conflict","实例已存在或已变化,请显式确认修订后保存");return d}}}function Ye(e,t){return w.serializeJobJson({reportIds:e,params:t})}function et(e){if(!e||typeof e!="object"||Object.getOwnPropertySymbols(e).length)throw new y("input","生成请求应为普通对象");const t=Object.create(null);let r;const s=new Set(["scope","id","title","reportIds","params","expectedRevision","signal"]);for(const n of Object.getOwnPropertyNames(e)){const o=Object.getOwnPropertyDescriptor(e,n);if(!s.has(n)||!o.enumerable||o.get||o.set)throw new y("input","生成请求不能包含未知字段或访问器");n==="signal"?r=o.value:o.value!==void 0&&(t[n]=o.value)}return{signal:r,request:JSON.parse(w.serializeJobJson(t))}}function ve(e){const t=JSON.parse(w.serializeJobJson(e.templateRevisions)),r=T.snapshotPdfFonts(e.pdf),s=be(e.instances,{maxSnapshotBytes:e.maxSnapshotBytes});return{async generate(n){const{signal:o,request:a}=et(n);if(j(a.scope,a.id),a.expectedRevision!==null&&(!Number.isSafeInteger(a.expectedRevision)||a.expectedRevision<1))throw new y("input","实例预期修订无效");const d=e.runtime.validate(a);if(!d.ok)throw new $.ReportParamValidationError(d.issues);const c=Object.create(null);for(const h of a.reportIds){if(typeof t[h]!="string"||!t[h])throw new TypeError(`报表 ${h} 缺少生成时的模板修订`);c[h]=t[h]}if(p.throwIfAborted(o),((await e.instances.read(a.scope,a.id,void 0,o))?.revision??null)!==a.expectedRevision)throw new y("conflict","实例已存在或已变化,请显式确认修订后生成");const f=await e.runtime.prepare({reportIds:a.reportIds,params:d.values,pdf:r,signal:o});p.throwIfAborted(o);const l=Object.create(null);for(const[h,S]of Object.entries(f.revisions))S.revision!==void 0&&(l[h]=S.revision);const{plan:u,revisions:m,sources:g,...v}=f,b={...v,...g?{sources:g.map(({sourceToken:h,...S})=>S)}:{}};return s.save({scope:a.scope,id:a.id,title:a.title,reportIds:a.reportIds,params:d.values,templateRevisions:c,sourceRevisions:l,generatedAt:(e.now?.()??new Date).toISOString(),plan:u,output:b},{expectedRevision:a.expectedRevision,signal:o})},read:s.read,list:s.list,async exportInstance(n){const{scope:o,id:a,revision:d,signal:c,format:i,fidelity:f,taskId:l,correlationId:u,onEvent:m}=n,g=T.snapshotPdfFonts(n.pdf??r),v=T.snapshotXlsxOptions(n.xlsx);j(o,a),p.throwIfAborted(c);const b=await s.read(o,a,d,c);if(!b)throw new y("input","报表实例不存在");const h={plan:b.plan,revisions:Object.fromEntries(b.reportIds.map(S=>[S,{revision:b.sourceRevisions[S]}])),diagnostics:[{code:"instance-row-count",severity:"info",message:"历史实例未保存原始取数行数;本次 rows 统计为 0,页面及单元格数由已保存计划校验。"}],stats:{rows:0,pages:b.plan.pages.length,cells:0,durationMs:0},...b.output};return e.runtime.exportPrepared({prepared:h,format:i,fidelity:f,pdf:g,xlsx:v,signal:c,taskId:l,correlationId:u,onEvent:m})},save:s.save}}function F(e,t,r){if(!Number.isSafeInteger(e)||e<1||e>t)throw new RangeError(`${r} 应为 1–${t} 的安全整数`);return e}function ae(e){if(!e||typeof e.key!="string"||!e.key.trim()||e.key.length>1024||!["pdf","xlsx"].includes(e.format)||!Number.isSafeInteger(e.bytes)||e.bytes<0||e.sha256!==void 0&&!/^[a-f0-9]{64}$/i.test(e.sha256))throw new TypeError("分批归档回执应包含存储键、格式、大小和可选 SHA256");return{key:e.key,format:e.format,bytes:e.bytes,...e.sha256?{sha256:e.sha256}:{}}}function tt(e){if(!B.validateReportTemplate(e).ok||!e.repeat)throw new TypeError("分批生成仅支持有效的逐记录固定标签模板");return JSON.parse(JSON.stringify(e))}function rt(e){const t=new Set,r=e.repeat;r.rowKey&&t.add(r.rowKey),typeof r.copies=="object"&&t.add(r.copies.field);const s=n=>{n.binding&&t.add(n.binding.field);for(const o of n.grid?.cells??[])for(const a of o)a?.children?.forEach(s)};return e.pages.forEach(n=>n.components.forEach(o=>s(o))),[...t]}function st(e,t,r,s){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError(`标签记录 ${s} 应为对象`);const n=Object.create(null);for(const o of t){const a=fe.readRecordScalar(e,o,{dataset:r,rowIndex:s});if(typeof a=="string"&&a.length>1e6)throw new p.ReportRuntimeError("budget","标签字段超过 1 MB 字符预算",`$.datasets.${r}[${s}].${o}`);a!==void 0&&(n[o]=a)}return n}function nt(e,t,r,s){const n=t.repeat;if(!n.rowKey)return;const o=fe.readRecordScalar(e,n.rowKey,{rowIndex:s,dataset:n.dataset});if(!(typeof o=="string"&&o.trim()||typeof o=="number"&&Number.isFinite(o)))throw new TypeError(`标签记录 ${s} 的业务主键无效`);const a=JSON.stringify([typeof o,o]);if(r.keys.has(a))throw new TypeError(`标签记录 ${s} 的业务主键重复(包含先前批次)`);r.bytes+=a.length*2+64,r.keys.add(a)}function ot(e){return Object.entries(e).reduce((t,[r,s])=>t+64+r.length*2+(typeof s=="string"?s.length*2:8),0)}function at(e,t){if(!t)return e;for(const r of e.plan.pages){const s=r.meta?.record;s&&typeof s=="object"&&"rowIndex"in s&&typeof s.rowIndex=="number"&&(s.rowIndex+=t)}return e}async function it(e,t){if(!e.return)return;const r=Promise.resolve(e.return());if(t.aborted){r.catch(()=>{});return}await p.controlled(t,void 0,()=>r)}async function ie(e,t,r){const s=Promise.resolve().then(()=>e.onReceipt?.(t,r));s.catch(()=>{}),await p.controlled(r.signal,void 0,()=>s)}function ct(e,t,r){return new Promise((s,n)=>{let o=!1,a=!1,d;const c=()=>{clearTimeout(d),t.removeEventListener("abort",i)},i=()=>{o||d!==void 0||(d=setTimeout(()=>{if(!o){o=!0,a=!0,c();try{p.throwIfAborted(t)}catch(f){n(f)}}},0))};e.then(f=>{if(a){Promise.resolve().then(()=>r(f)).catch(()=>{});return}o||(o=!0,c(),s(f))},f=>{o||(o=!0,c(),n(f))}),t.addEventListener("abort",i,{once:!0}),t.aborted&&i()})}async function dt(e,t){const r=F(t.batchSize??100,1e3,"batchSize"),s=F(t.maxRows??1e5,1e6,"maxRows"),n=F(t.maxChunks??1e3,1e4,"maxChunks"),o=F(t.maxRetainedBytes??16e6,64e6,"maxRetainedBytes"),a=tt(t.template),d=rt(a);if(!e||typeof e[Symbol.asyncIterator]!="function")throw new TypeError("标签来源应为 AsyncIterable");return p.controlled(t.signal,t.runtime?.budget?.maxDurationMs??12e4,async c=>{const i={rows:0,chunks:[]},f={keys:new Set,bytes:0},l=e[Symbol.asyncIterator]();let u=!1,m=!1,g;const v=()=>g??=it(l,c),b=()=>{u||v().catch(()=>{})};c.addEventListener("abort",b,{once:!0});try{for(;!u;){p.throwIfAborted(c);const h=[];let S=0;for(;h.length<r;){const k=await p.controlled(c,void 0,()=>Promise.resolve(l.next()));if(k.done){u=!0;break}if(i.rows+h.length>=s)throw new p.ReportRuntimeError("budget","标签来源行数超过预算","$.maxRows");if(i.chunks.length>=n)throw new p.ReportRuntimeError("budget","标签分块数量超过预算","$.maxChunks");const E=st(k.value,d,a.repeat.dataset,i.rows+h.length);if(nt(E,a,f,i.rows+h.length),S+=ot(E),f.bytes+S>o)throw new p.ReportRuntimeError("budget","标签当前块字段与全局主键索引超过内存预算","$.maxRetainedBytes");h.push(E)}if(!h.length)break;const N=_({...t.runtime,reports:{labels:{template:a,datasets:{[a.repeat.dataset]:h}}}});let I;const R={index:i.chunks.length,rowOffset:i.rows,rowCount:h.length,signal:c,export:k=>N.exportPrepared({pdf:t.pdf,...k,prepared:I,signal:c})};let A;const O=(await w.runReportBatch([{id:`labels-${R.index}`,params:{}}],async()=>{try{I=at(await N.prepare({reportIds:["labels"],pdf:t.pdf,signal:c}),R.rowOffset),p.throwIfAborted(c);const k=Promise.resolve(t.execute(I,R)),E=await ct(k,c,J=>ie(t,ae(J),R));return ae(E)}catch(k){throw A=k,k}},{concurrency:1,signal:c,failure:"stop"}))[0];if(O.status==="cancelled")throw p.throwIfAborted(c),new Error("标签分批任务已取消");if(O.status==="failed")throw A??new Error(O.error.message);i.chunks.push({...O.value,index:R.index,rowOffset:R.rowOffset,rowCount:R.rowCount}),i.rows+=h.length,await ie(t,O.value,R)}return i}catch(h){throw m=!0,h}finally{c.removeEventListener("abort",b),u||await v().catch(h=>{if(!m)throw h})}})}async function Re(e,t){const r=t.document().id,s=()=>t.editor.saving||t.editor.blocked;if(s())throw new Error("草稿尚未保存,请处理设计器提示后再发布");if(t.editor.pendingLocalChanges){const o=t.successfulSaves();if(await t.editor.save(),await t.afterSave(),t.successfulSaves()===o||t.editor.pendingLocalChanges||s())throw new Error("草稿尚未保存,请处理设计器提示后再发布")}const n=t.document();if(n.id!==r)throw new y("conflict","当前模板已切换,请重新确认后发布");return e.publish(n.id,{expectedRevision:n.revision??null})}function xe(e,t){return{async search(r){p.throwIfAborted(r.signal);const s=await e.list(r.signal);if(s.length>1e3)throw new RangeError("本地模板连接目录最多 1000 项;更大目录请使用宿主分页查询适配器");const n=[];for(const o of s){p.throwIfAborted(r.signal);const[a,d]=await Promise.all([e.get(o.id,{draft:!0,signal:r.signal}),e.get(o.id,{signal:r.signal})]),c=a??d;c&&n.push({document:c,published:d,draftRevision:a?.revision,publishedRevision:d?.revision,...t?.(B.parseReportTemplate(c))})}return le.createLocalTemplateCatalog(n).search(r)},async get(r,s){return s.mode==="published"?e.get(r,{signal:s.signal}):await e.get(r,{draft:!0,signal:s.signal})??e.get(r,{signal:s.signal})}}}function Ie(e=1e3){if(!Number.isSafeInteger(e)||e<1||e>1e3)throw new RangeError("本地生成意图上限应为 1–1000");const t=new Map,r=globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;return{forCase(s,n){if(![s,n].every(c=>typeof c=="string"&&c.length>0&&c.length<=256))throw new TypeError("模板与参数组标识无效");const o=JSON.stringify([s,n]),a=t.get(o);if(a)return a;if(t.size>=e)throw new RangeError("本地生成意图已达上限,请使用持久化任务服务");const d=`instance-${r}-${(t.size+1).toString(36)}`;return t.set(o,d),d}}}function lt(e,t,r){const s=Object.keys(r);return e.reportIds.length===1&&e.reportIds[0]===t.id&&Object.keys(e.templateRevisions).length===1&&e.templateRevisions[t.id]===t.revision&&Object.keys(e.params).length===s.length&&s.every(n=>r[n]===e.params[n])}function ce(e){return{instanceId:e.id,label:e.title}}function ft(e,t,r){const s=B.parseReportTemplate(e);if(!s.revision)throw new Error("请先发布该模板");const n=typeof t.data=="function"?t.data(B.parseReportTemplate(s)):t.data,o=_({...t.runtime,reports:{[s.id]:{...n,template:s.template}}}),a=ve({runtime:o,instances:t.instances,templateRevisions:{[s.id]:s.revision},pdf:t.pdf});async function d(c,i,f){p.throwIfAborted(f);const l=await t.instances.read(t.scope,c,void 0,f);if(p.throwIfAborted(f),!!l){if(!lt(l,s,i))throw new y("conflict","此参数组已用于其他参数或发布修订,请复制为新任务生成");return ce(l)}}return{document:B.parseReportTemplate(s),async execute(c,{signal:i}){p.throwIfAborted(i);const f=o.validate({reportIds:[s.id],params:c.params});if(!f.ok)throw new Error(f.issues[0]?.message??"生成参数无效");const l=r(s.id,c.id),u=await d(l,f.values,i);if(u)return u;try{return ce(await a.generate({scope:t.scope,id:l,title:(t.title?.(B.parseReportTemplate(s),c,f.values)??`${s.name} · ${c.id}`).slice(0,512),reportIds:[s.id],params:f.values,expectedRevision:null,signal:i}))}catch(m){if(m instanceof y&&m.code==="conflict"){const g=await d(l,f.values,i);if(g)return g}throw m}}}}function ut(e){e={...e};const t=Ie(),r=e.instanceId??t.forCase;return{catalog:e.catalog??xe(e.templates,e.catalogMetadata),publish:s=>Re(e.templates,s),async batch(s,n={}){const{expectedRevision:o,signal:a}=n,d=await e.templates.get(s,{signal:a});if(p.throwIfAborted(a),!d?.revision)throw new Error("请先发布该模板");if(o!==void 0&&d.revision!==o)throw new y("conflict","模板发布版本已变化,请重新打开后生成");return ft(d,e,r)}}}const Ee="2.15.0";function H(e,t){const r=t?.componentPath;if(!Number.isSafeInteger(t?.pageIndex)||t.pageIndex<0||!Array.isArray(r)||r.length<1||r.length>31||r.length%3!==1||r.some(n=>!Number.isSafeInteger(n)||n<0))throw new TypeError("模板包图片位置无效");let s=e.template.pages[t.pageIndex]?.components[r[0]];for(let n=1;s&&n<r.length;n+=3)s=s.grid?.cells[r[n]]?.[r[n+1]]?.children?.[r[n+2]];if(!s||s.kind!=="image"||s.binding)throw new TypeError("模板包图片位置应指向静态图片组件");return s}function pt(e){const t=["id","kind","mediaType","bytes","sha256","license","font","targets"];if(!e||Object.keys(e).some(r=>!t.includes(r)))throw new TypeError("模板资源包含未知字段");if(typeof e.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(e.id))throw new TypeError("模板资源ID应为安全标识");if(!Number.isSafeInteger(e.bytes)||e.bytes<1||e.bytes>32e6||!/^[a-f0-9]{64}$/.test(e.sha256))throw new TypeError("模板资源大小或SHA256无效");if(e.license!==void 0&&(typeof e.license!="string"||e.license.length>512))throw new TypeError("模板资源许可说明无效")}function wt(e,t){if(pt(e),e.kind==="font"){if(!["font/ttf","font/otf"].includes(e.mediaType)||e.targets!==void 0)throw new TypeError("字体资源类型无效");const r=e.font;if(!r||typeof r.family!="string"||!r.family.trim()||r.family.length>128||!["regular","bold","italic","boldItalic"].includes(r.face)||Object.keys(r).some(s=>!["family","face"].includes(s)))throw new TypeError("字体资源需要family和face");return}if(e.kind!=="image"||!["image/png","image/jpeg"].includes(e.mediaType)||e.font!==void 0)throw new TypeError("模板图片仅支持PNG/JPEG");if(!Array.isArray(e.targets)||!e.targets.length||e.targets.length>1e3)throw new TypeError("模板图片需要1–1000个位置");for(const r of e.targets){if(Object.keys(r).some(s=>!["pageIndex","componentPath"].includes(s)))throw new TypeError("模板图片位置包含未知字段");H(t,r)}}function gt(e,t){const r=s=>s.every((n,o)=>e[o]===n);return t==="image/png"?r([137,80,78,71,13,10,26,10]):t==="image/jpeg"?r([255,216,255]):t==="font/otf"?r([79,84,84,79]):r([0,1,0,0])||r([116,114,117,101])}function Se(e){if(!(e instanceof Uint8Array)||!e.byteLength||e.byteLength>32e6)throw new RangeError("资源摘要只接受1–32MB字节");return p.portableSha256Hex(e)}function ke(e,t,r=pe.createImageMediaInspector()){const s=new Set(t.flatMap(a=>(a.targets??[]).map(d=>H(e,d)))),n=new Map,o=a=>{if(a.imageData&&!s.has(a)){const d=r(a.imageData);n.set(d.dataUrl,d.bytes.byteLength)}for(const d of a.grid?.cells??[])for(const c of d)for(const i of c?.children??[])o(i)};for(const a of e.template.pages)for(const d of a.components)o(d);return[...n.values()].reduce((a,d)=>a+d,0)}function mt(e,t){let r="";for(let s=0;s<e.length;s+=16384)r+=String.fromCharCode(...e.subarray(s,s+16384));return`data:${t};base64,${btoa(r)}`}async function ht(e,t,r,s,n=3e4){if(!Number.isFinite(n)||n<1||n>2147483647)throw new RangeError("模板资源加载超时应为1–2147483647毫秒");return p.controlled(s,n,async o=>{const a=[],d=pe.createImageMediaInspector();ke(e,t,d);for(const c of t){p.throwIfAborted(o);const i=await p.controlled(o,void 0,()=>Promise.resolve(r(JSON.parse(JSON.stringify(c)),{signal:o})));if(p.throwIfAborted(o),!i||!(i.bytes instanceof Uint8Array)||i.mediaType!==c.mediaType||i.bytes.byteLength!==c.bytes)throw new TypeError(`资源 ${c.id} 的类型或大小与清单不一致`);const f=new Uint8Array(i.bytes);if(!gt(f,c.mediaType)||Se(f)!==c.sha256)throw new TypeError(`资源 ${c.id} 的文件标识或SHA256与清单不一致`);if(c.kind==="font")a.push({id:c.id,family:c.font.family,face:c.font.face,bytes:f});else{const l=d(mt(f,c.mediaType)).dataUrl;for(const u of c.targets)H(e,u).imageData=l}}return a})}function de(e){if(typeof e!="string"||!/^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})$/.test(e))throw new TypeError("模板包最低版本与运行版本应为正式版本x.y.z");return e.split(".").map(Number)}function yt(e,t){const r=de(e),s=de(t);for(let n=0;n<3;n++){if(s[n]>r[n])return;if(s[n]<r[n])throw new Error(`模板包需要MachReport ${e}或更新版本`)}}function K(e,t,r){const s=e??t;if(!Number.isSafeInteger(s)||s<1||s>r)throw new RangeError("模板包字节预算无效");return s}function bt(e){if(e.contracts!==void 0){if(!e.contracts||typeof e.contracts!="object"||Array.isArray(e.contracts)||Object.keys(e.contracts).length>100)throw new TypeError("模板包字段契约应为最多100个数据集");for(const[t,r]of Object.entries(e.contracts)){if(!t.trim()||t.length>256)throw new TypeError("模板包数据集名称无效");ue.validateDatasetRows([],r)}}}function vt(e,t){if(!e||e.deidentified!==!0||typeof e.name!="string"||!e.name.trim()||e.name.length>128)throw new TypeError("样例需要名称和明确的deidentified:true确认");if(Object.keys(e).some(s=>!["name","deidentified","datasets","params"].includes(s)))throw new TypeError("模板包样例包含未知字段");if(!e.datasets||typeof e.datasets!="object"||Array.isArray(e.datasets))throw new TypeError("模板包样例数据集无效");if(Rt(e,t),!$.validateReportParams(t.document.template.params??[],e.params).ok)throw new TypeError(`样例 ${e.name} 的参数不符合模板定义`)}function Rt(e,t){let r=0;for(const n of Object.values(e.datasets))if(!Array.isArray(n)||n.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new TypeError("模板包样例应为对象行数组");const s=x.templateValidationDatasets(t.document.template,e.datasets,{maxRows:1e3});for(const[n,o]of Object.entries(s)){if(r+=o.length,r>1e3)throw new RangeError("模板包每个样例最多1000行");const a=t.contracts?.[n];if(a&&!ue.validateDatasetRows(o,a).ok)throw new TypeError(`样例 ${e.name} 不符合 ${n} 字段契约`)}for(const n of Object.keys(t.contracts??{}))if(!Object.prototype.hasOwnProperty.call(e.datasets,n))throw new TypeError(`样例 ${e.name} 缺少 ${n} 数据集`)}function xt(e){if(e.fixtures===void 0)return;if(!Array.isArray(e.fixtures)||e.fixtures.length>20)throw new RangeError("模板包最多20个脱敏样例");const t=new Set;for(const r of e.fixtures){if(vt(r,e),t.has(r.name))throw new TypeError("模板包样例名称重复");t.add(r.name)}}function It(e,t){if(!Array.isArray(e.resources)||e.resources.length>64)throw new RangeError("模板包最多64个资源依赖");const r=new Set,s=new Set,n=new Set;let o=0;for(const a of e.resources){if(wt(a,e.document),r.has(a.id))throw new TypeError("模板资源ID重复");if(r.add(a.id),o+=a.bytes,o>t)throw new RangeError("模板包资源总大小超过预算");const d=a.font&&JSON.stringify([a.font.family,a.font.face]);if(d&&n.has(d))throw new TypeError("模板包字体family/face重复");d&&n.add(d);for(const c of a.targets??[]){const i=JSON.stringify([c.pageIndex,c.componentPath]);if(s.has(i))throw new TypeError("同一图片位置不能绑定多个资源");s.add(i)}}if(o+ke(e.document,e.resources)>t)throw new RangeError("模板包内嵌与外部资源总大小超过预算")}function X(e,t={}){p.throwIfAborted(t.signal);const r=K(t.maxBytes,8e6,32e6);if(typeof e=="string"){if(e.length>r||new TextEncoder().encode(e).byteLength>r)throw new RangeError("模板包JSON超过预算");e=JSON.parse(e)}const s=x.snapshotReportJson(e,{maxBytes:r,check:()=>p.throwIfAborted(t.signal),error:(n,o)=>new TypeError(o)});if(!s||typeof s!="object"||Array.isArray(s)||s.schemaVersion!=="1.0"||Object.keys(s).some(n=>!["schemaVersion","minimumVersion","document","contracts","resources","fixtures"].includes(n)))throw new TypeError("模板包结构或版本无效");return yt(s.minimumVersion,t.runtimeVersion??Ee),s.document=B.parseReportTemplate(s.document),bt(s),xt(s),It(s,K(t.maxResourceBytes,32e6,64e6)),s}function Et(e,t={}){const r=x.snapshotReportJson(e,{maxBytes:K(t.maxBytes,8e6,32e6),check:()=>p.throwIfAborted(t.signal),error:(n,o)=>new TypeError(o)}),s=X({schemaVersion:"1.0",...r,minimumVersion:r.minimumVersion??Ee,resources:r.resources??[]},t);for(const n of s.resources)for(const o of n.targets??[])delete H(s.document,o).imageData;return s}async function St(e,t){const{resolve:r,signal:s,maxDurationMs:n}=t,o=X(e,t),a=await ht(o.document,o.resources,r,s,n);return{document:o.document,fonts:a,contracts:o.contracts,fixtures:o.fixtures??[]}}exports.ReportRuntimeError=p.ReportRuntimeError;exports.ReportJobError=w.ReportJobError;exports.checkJobIdentity=w.checkJobIdentity;exports.cloneJob=w.cloneJob;exports.createMemoryReportJobStore=w.createMemoryReportJobStore;exports.runReportBatch=w.runReportBatch;exports.runnableJob=w.runnableJob;exports.serializeJobJson=w.serializeJobJson;exports.snapshotReportBatchCases=w.snapshotReportBatchCases;exports.validateJobRecord=w.validateJobRecord;exports.validateJobTransition=w.validateJobTransition;exports.ReportInstanceError=y;exports.checkInstanceIdentity=j;exports.createManagerTemplateCatalog=xe;exports.createMemoryReportInstanceIds=Ie;exports.createMemoryReportInstanceStore=Ze;exports.createReportGenerationService=ve;exports.createReportInstanceManager=be;exports.createReportJobService=Ve;exports.createReportRuntime=_;exports.createReportTaskQueue=Me;exports.createReportTemplatePackage=Et;exports.createReportWorkflow=ut;exports.parseReportTemplatePackage=X;exports.reportInstanceParameterKey=Ye;exports.reportInstanceSummary=ye;exports.reportPackageResourceDigest=Se;exports.resolveReportTemplatePackage=St;exports.reviewReportPublication=Ue;exports.runLabelStream=dt;exports.saveAndPublishReportTemplate=Re;exports.snapshotReportInstance=L;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("./runtime-dL5ygIfa.cjs"),p=require("./sha256-BshdOkCC.cjs"),C=require("./json-snapshot-D7PE1NsU.cjs"),h=require("./batch-z6Aw5GEY.cjs"),ce=require("./template-catalog-Dua8h9ZA.cjs"),O=require("./template-registry-CpysHAxy.cjs"),M=require("./prepared-Ch1x_Gog.cjs"),fe=require("./param-validation-C3HlcLLO.cjs"),de=require("./record-bindings-B86Sur_y.cjs"),ue=require("./dataset-IrlXbUvh.cjs"),le=require("./media-B7vnpD8k.cjs"),Ee=require("./component-tree-DkGLEfZC.cjs");function Ae(e={}){const t=e.concurrency??1,r=e.maxQueued??20;if(!Number.isSafeInteger(t)||t<1||!Number.isSafeInteger(r)||r<0)throw new p.ReportRuntimeError("budget","队列并发应为正整数,排队上限应为非负整数");const n=[],o=new Set,s=new Set;let a=!1,u=0;const f=()=>{for(;!a&&o.size<t&&n.length;)n.shift().start()};return{get active(){return o.size},get pending(){return n.length},enqueue:(i,d={})=>{if(a)throw new p.ReportRuntimeError("closed","任务队列已关闭");if(p.throwIfAborted(d.signal),o.size>=t&&n.length>=r)throw new p.ReportRuntimeError("queue-full","报表任务队列已满");const l=d.id??`report-${++u}`;if(s.has(l))throw new p.ReportRuntimeError("queue-full","任务 ID 正在执行或排队");const w=new AbortController;let m="queued",b,y,g,R;const P=new Promise((S,A)=>{g=S,R=A}),N=()=>{d.signal?.removeEventListener("abort",$),s.delete(l)},E=S=>{if(m!=="queued"&&m!=="running")return;const A=m==="queued";m="cancelled",w.abort(S);try{p.throwIfAborted(w.signal)}catch(q){R(q)}if(A){const q=n.indexOf(x);q>=0&&n.splice(q,1),N(),f()}},$=()=>E(d.signal?.reason),K=(S,A)=>{m==="running"&&(!Number.isFinite(S)||S<0||A!==void 0&&(!Number.isFinite(A)||A<S)||(b={completed:S,...A===void 0?{}:{total:A}}))},T=S=>{m!=="running"||w.signal.aborted||(y={...S,taskId:l},S.completed!==void 0&&K(S.completed,S.total),C.notifyReportTaskEvent(d.onEvent,y,w.signal))},x={cancel:E,start:()=>{m==="queued"&&(m="running",o.add(x),Promise.resolve().then(()=>(p.throwIfAborted(w.signal),i({taskId:l,signal:w.signal,reportProgress:K,onEvent:T}))).then(S=>{m==="running"&&(m="completed",g(S))},S=>{m==="running"&&(m="failed",R(S))}).finally(()=>{o.delete(x),N(),f()}))}};return s.add(l),d.signal?.addEventListener("abort",$,{once:!0}),d.signal?.aborted?E(d.signal.reason):o.size<t?x.start():n.push(x),{id:l,get status(){return m},get progress(){return b},get event(){return y},result:P,cancel:E}},close:(i={})=>{a=!0;for(const d of[...n])d.cancel(new p.ReportRuntimeError("closed","任务队列已关闭"));if(i.cancelRunning)for(const d of o)d.cancel(new p.ReportRuntimeError("closed","任务队列已关闭"))}}}function ke(e){let t,r;const n=new Promise((o,s)=>{t=o,r=s});return n.catch(()=>{}),{progress:e,promise:n,resolve:t,reject:r}}function Q(e){const t=Promise.reject(e);return t.catch(()=>{}),t}function Oe(e,t){let r,n,o=!0,s;function a(c){s??=c??new Error("任务心跳更新失败"),n?.reject(s),n=void 0,t(s)}function u(c){const i=Promise.resolve().then(()=>e(c?.progress)).then(()=>c?.resolve(),d=>{c?.reject(d),a(d)}).finally(()=>{r=void 0;const d=n;n=void 0,d&&s===void 0&&u(d)});r=i,i.catch(d=>{a(d)})}function f(c){if(!o)return Q(new h.ReportJobError("closed","任务进度上报已结束"));if(s!==void 0)return Q(s);n?n.progress=c:n=ke(c);const i=n;return r||(n=void 0,u(i)),i.promise}return{progress:f,pulse(){o&&!r&&s===void 0&&u()},async finish(){for(o=!1;r;)await r;if(s!==void 0)throw s}}}class W extends h.ReportJobError{constructor(){super("capacity","任务结果超过独立预算,请保存文件引用")}}function Je(e){const t=e.concurrency??1,r=e.leaseMs??3e4,n=e.heartbeatMs??1e4,o=e.maxResultBytes??256*1024;if(![t,r,n,o].every(a=>Number.isSafeInteger(a)&&a>0)||n*2>r)throw new h.ReportJobError("input","并发、租约、心跳应为正整数,租约至少为心跳的两倍");if(n>2147483647)throw new h.ReportJobError("input","心跳间隔超过平台定时器上限(2147483647毫秒)");return{concurrency:t,leaseMs:r,heartbeatMs:n,maxResultBytes:o,now:()=>{const a=(e.now??Date.now)();if(!Number.isSafeInteger(a)||a<0)throw new h.ReportJobError("input","任务时钟应返回非负整数毫秒");return a}}}async function L(e,t,r){h.checkJobIdentity(t,r);const n=await e.read(t,r);if(!n)throw new h.ReportJobError("missing","报表任务不存在");return n}async function D(e,t,r,n=[]){const o={...t,...r,revision:t.revision+1};for(const s of n)delete o[s];if(!await e.compareAndSwap(t.scope,t.id,t.revision,o))throw new h.ReportJobError("conflict","报表任务已被其他请求更新");return h.cloneJob(o)}async function Pe(e,t,r,n){if(!t.trim()||t.length>128)throw new h.ReportJobError("input","workerId应为1–128位标识");for(const o of await e.store.candidates(n,100)){const s=o.cancelRequested?{...o,revision:o.revision+1,status:"cancelled",updatedAt:n}:{...o,revision:o.revision+1,status:"running",attempt:o.attempt+1,updatedAt:n,lease:{owner:t,expiresAt:n+r}};if(s.status==="cancelled"&&delete s.lease,await e.store.compareAndSwap(o.scope,o.id,o.revision,s))return s}}function Y(e,t,r,n){return e.status==="running"&&e.attempt===n&&e.lease?.owner===t&&e.lease.expiresAt>r}async function Te(e,t,r,n){const{scope:o,id:s}=r,a=r.lease.owner;let u;const f=Oe(async y=>{const g=await L(e.store,o,s),R=t.now();if(!Y(g,a,R,r.attempt))throw new h.ReportJobError("lease","报表任务租约已失效");if(g.cancelRequested){n.abort(new h.ReportJobError("closed","任务已请求取消"));return}await D(e.store,g,{updatedAt:R,lease:{owner:a,expiresAt:R+t.leaseMs},...y?{progress:y}:{}})},y=>{u=y,n.abort(y)}),c=(y,g)=>!Number.isFinite(y)||y<0||g!==void 0&&(!Number.isFinite(g)||g<y)?Promise.reject(new h.ReportJobError("input","任务进度无效")):f.progress({completed:y,...g===void 0?{}:{total:g}}),i=setInterval(()=>{f.pulse()},t.heartbeatMs);let d,l;try{const y=Object.prototype.hasOwnProperty.call(e.handlers,r.request.kind)?e.handlers[r.request.kind]:void 0;if(!y)throw new h.ReportJobError("input","报表任务处理器未注册");if(!n.signal.aborted){const g=await y(h.cloneJob(r.request.payload),{scope:o,taskId:s,attempt:r.attempt,executionToken:JSON.stringify([o,s,r.attempt]),signal:n.signal,reportProgress:c});if(d=JSON.parse(h.serializeJobJson(g)),h.jobByteLength(d)>t.maxResultBytes)throw new W}}catch(y){l=y??new Error("报表任务执行失败")}finally{clearInterval(i),await f.finish().catch(()=>{})}const w=await L(e.store,o,s),m=t.now();if(!Y(w,a,m,r.attempt))throw new h.ReportJobError("lease","任务租约已失效,迟到结果不会写回");const b={...w,updatedAt:m};delete b.lease,l??=u,w.cancelRequested||n.signal.aborted&&u===void 0?b.status="cancelled":l!==void 0?(b.status="failed",b.error={code:l instanceof W?"result-budget":l instanceof h.ReportJobError?l.code:"execution",message:l instanceof Error?l.message.slice(0,500):"报表任务执行失败"}):(b.status="completed",b.result=d);try{h.serializeJobJson(b)}catch{delete b.result,b.status="failed",b.error={code:"result-budget",message:"任务结果与请求的组合超过存储预算,请保存文件引用而非文件内容"}}return je(e.store,w,b)}async function je(e,t,r){try{return await D(e,t,r,["lease"])}catch(n){if(!(n instanceof h.ReportJobError)||n.code!=="capacity"||r.status!=="completed")throw n;return delete r.result,r.status="failed",r.error={code:"result-budget",message:"任务结果超过存储剩余预算,请保存文件引用而非文件内容"},D(e,t,r,["lease","result"])}}async function ee(e,t,r,n){const o=await e.readTombstone?.(t,r);if(o){if(o.requestHash!==await h.jobRequestHash(n))throw new h.ReportJobError("conflict","相同任务ID不能提交不同内容(幂等保留期内)");return{scope:t,id:r,revision:o.revision,request:h.cloneJob(n),status:o.status,createdAt:o.createdAt,updatedAt:o.updatedAt,attempt:o.attempt,archived:!0}}}function Ne(e){e={...e,handlers:{...e.handlers}};const t=Je(e),r=new Set,n=new Set;let o=!1,s=0;const a=(c,i)=>(h.checkJobIdentity(c,i),e.store.read(c,i));return{submit:async c=>{if(c={...c},h.checkJobIdentity(c.scope,c.id),!Object.prototype.hasOwnProperty.call(e.handlers,c.kind)||typeof e.handlers[c.kind]!="function")throw new h.ReportJobError("input","报表任务处理器未注册");const i={kind:c.kind,payload:JSON.parse(h.serializeJobJson(c.payload,{maxNodes:19e3,maxCharacters:75e4}))},d=await a(c.scope,c.id);if(d){if(h.serializeJobJson(d.request)!==h.serializeJobJson(i))throw new h.ReportJobError("conflict","相同任务ID不能提交不同内容");return d}const l=await ee(e.store,c.scope,c.id,i);if(l)return l;const w=t.now(),m={scope:c.scope,id:c.id,revision:1,request:i,status:"queued",createdAt:w,updatedAt:w,attempt:0};if(!await e.store.compareAndSwap(c.scope,c.id,null,m)){const b=await a(c.scope,c.id);if(b&&h.serializeJobJson(b.request)===h.serializeJobJson(i))return b;const y=await ee(e.store,c.scope,c.id,i);if(y)return y;throw new h.ReportJobError("conflict","报表任务提交发生冲突")}return h.cloneJob(m)},get:a,runNext:c=>{if(o)return Promise.reject(new h.ReportJobError("closed","报表任务服务已关闭"));if(s>=t.concurrency)return Promise.reject(new h.ReportJobError("capacity","报表任务执行槽位已满"));s++;const i=new AbortController;r.add(i);const d=(async()=>{try{const l=await Pe(e,c,t.leaseMs,t.now());return l?.status==="running"?await Te(e,t,l,i):l}finally{s--,r.delete(i)}})();return n.add(d),d.then(()=>n.delete(d),()=>n.delete(d)),d},get active(){return s},cancel:async(c,i)=>{const d=await L(e.store,c,i);return d.status!=="queued"&&d.status!=="running"?d:D(e.store,d,{updatedAt:t.now(),...d.status==="queued"?{status:"cancelled"}:{cancelRequested:!0}})},retry:async(c,i,d)=>{const l=await L(e.store,c,i);if(l.revision!==d||l.status!=="failed")throw new h.ReportJobError("conflict","仅可重试当前修订的失败任务");const w={...l,status:"queued",updatedAt:t.now()};return delete w.error,delete w.progress,D(e.store,l,w,["error","progress"])},prune:async c=>{if(!e.store.prune||!e.store.readTombstone)throw new h.ReportJobError("input","当前任务适配器未实现可选终态保留能力");return e.store.prune({...c,now:t.now()})},close:async()=>{o=!0;for(const c of r)c.abort(new h.ReportJobError("closed","任务服务正在关闭"));await Promise.allSettled([...n])}}}function pe(e,t){const r=e.assets,n=e[t];if(!(!r&&!n?.assetRenderers&&!n?.assetRegistry))return{...r,...n?.assetFailure===void 0?{}:{assetFailure:n.assetFailure},...n?.onDiagnostic===void 0?{}:{onDiagnostic:n.onDiagnostic},assetRegistry:n?.assetRegistry??r?.assetRegistry,assetRenderers:{...r?.assetRenderers,...n?.assetRenderers},assetBudget:{...r?.assetBudget,...n?.assetBudget}}}function te(e,t){if(!e||e.code!=="missing-image"||e.format!=="pdf"&&e.format!=="xlsx")return!1;const r=pe(t,e.format);return typeof r?.assetRenderers?.[e.kind]=="function"||!!(e.extension&&r?.assetRegistry?.hasExtension(e.extension.id,e.extension.version,e.kind))}function Be(e,t){const r=ce.reviewReportTemplate(e,t),n=r.issues.filter(s=>!te(s.diagnostic,t)),o=r.samples.map(s=>({...s,diagnostics:s.diagnostics.filter(a=>!te(a,t))}));return{...r,issues:n,samples:o,ok:n.every(s=>s.severity!=="error"),artifacts:[]}}async function $e(e,t,r,n,o){const s=H.createReportRuntime({reports:{sample:{template:r,datasets:e.datasets}},assets:pe(n,t),budget:{maxRows:n.maxSampleRows??1e3,maxPages:n.maxPages??100,maxCells:n.maxCells??25e4,maxOutputBytes:n.maxOutputBytes??2e7,maxDurationMs:n.maxDurationMs??3e4}});try{const{result:a,digest:u}=await p.controlled(n.signal,n.maxDurationMs??3e4,async f=>{const c=await s.export({reportIds:["sample"],params:e.params,format:t,signal:f,fidelity:n.strictOutputs?"strict":"warn",pdf:n.pdf,xlsx:n.xlsx}),i=c.diagnostics.filter(l=>l.severity!=="info");if(n.strictOutputs&&i.length)throw new Error(`Strict ${t} encoding found fidelity issues: ${i.slice(0,3).map(l=>l.message).join("; ")}`);const d=await n.digest?.(c.bytes);return p.throwIfAborted(f),await n.onArtifact?.(e.name,c),p.throwIfAborted(f),{result:c,digest:d}});o.artifacts.push({fixture:e.name,format:t,bytes:a.bytes.byteLength,pages:a.stats.pages,...u?{digest:u}:{}}),o.issues.push(...a.diagnostics.map(f=>({code:"output",severity:n.strictOutputs||f.severity==="error"?"error":"warning",path:"$.template",fixture:e.name,message:`${t}: ${f.message}`})))}catch(a){p.throwIfAborted(n.signal),o.issues.push({code:"output",severity:"error",path:"$.template",fixture:e.name,message:`${t}: ${a instanceof Error?a.message:String(a)}`})}}async function Me(e,t={}){p.throwIfAborted(t.signal);const r=Be(e,t);if(!r.ok)return r;const n=O.parseReportTemplate(e).template,o=[...new Set(t.formats??["pdf","xlsx"])];if(!o.length||o.some(s=>s!=="pdf"&&s!=="xlsx"))return r.issues.push({code:"output",severity:"error",path:"$.formats",message:"真实文件验收应至少选择PDF/XLSX之一"}),r.ok=!1,r;for(const s of t.fixtures??[])for(const a of o)p.throwIfAborted(t.signal),!(a!=="pdf"&&a!=="xlsx")&&await $e(s,a,n,t,r);return r.ok=r.issues.every(s=>s.severity!=="error"),r}class v extends Error{constructor(t,r){super(r),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 v("input","实例范围应非空,ID 应为安全标识")}function De(e,t){const r=Object.getPrototypeOf(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t)||Object.getOwnPropertySymbols(e).length)throw new v("input","实例应为普通 JSON 对象");if(t&&Object.keys(e).some(o=>o!==String(Number(o))||!Number.isSafeInteger(Number(o))||Number(o)<0||Number(o)>=e.length))throw new v("input","实例数组不能包含额外属性");if(Object.getOwnPropertyNames(e).filter(o=>!(t&&o==="length")).length!==Object.keys(e).length)throw new v("input","实例不能包含不可枚举属性")}function Ce(e){if(!Number.isSafeInteger(e.revision)||e.revision<1||typeof e.title!="string"||!e.title.trim()||e.title.length>512)throw new v("input","实例修订或标题无效");if(typeof e.generatedAt!="string"||!Number.isFinite(Date.parse(e.generatedAt))||new Date(e.generatedAt).toISOString()!==e.generatedAt)throw new v("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 v("input","实例报表 ID 应非空且唯一")}function qe(e){return e===null||typeof e=="boolean"||typeof e=="string"||typeof e=="number"&&Number.isFinite(e)}function we(e,t){if(!Number.isSafeInteger(t)||t<1)throw new v("input","实例快照字节预算应为正安全整数");let r=0,n=0;const o=new Set;function s(u,f){if(++r>1e6||f>64)throw new v("capacity","实例节点或嵌套深度超过预算");if(typeof u=="string"&&(n+=u.length,n>t))throw new v("capacity","实例文本超过预算");if(qe(u))return u;if(!u||typeof u!="object"||o.has(u))throw new v("input","实例只允许无循环的有限 JSON 值");const c=Array.isArray(u);De(u,c),o.add(u);const i=Object.create(null);for(const d of Object.keys(u)){if(n+=d.length,n>t)throw new v("capacity","实例文本超过预算");const l=Object.getOwnPropertyDescriptor(u,d);if(l.get||l.set||["__proto__","constructor","prototype"].includes(d))throw new v("input","实例不能包含访问器或危险键");l.value!==void 0&&(i[d]=s(l.value,f+1))}if(o.delete(u),c){if(Object.keys(i).length!==u.length)throw new v("input","实例数组不能稀疏或包含额外属性");return Array.from({length:u.length},(d,l)=>i[String(l)])}return i}const a=JSON.stringify(s(e,0));if(new TextEncoder().encode(a).byteLength>t)throw new v("capacity","实例快照超过单条字节预算");return a}function F(e,t=8e6){const r=JSON.parse(we(e,t));j(r.scope,r.id);const n=new Set(["scope","id","revision","title","generatedAt","reportIds","params","templateRevisions","sourceRevisions","plan","artifacts","output"]);if(Object.keys(r).some(s=>!n.has(s)))throw new v("input","实例包含未知字段");Ce(r);for(const s of[r.params,r.templateRevisions,r.sourceRevisions])if(!s||typeof s!="object"||Array.isArray(s)||Object.values(s).some(a=>typeof a!="string"))throw new v("input","实例参数和修订应为字符串字典");if(r.reportIds.some(s=>!r.templateRevisions[s]))throw new v("input","每张报表都应记录生成时的模板修订");const o=O.validateRenderPlan(r.plan);if(!o.ok)throw new v("input",`实例渲染计划无效:${o.errors[0]?.path}`);if(r.output!==void 0){if(!r.output||Object.keys(r.output).some(s=>!["stats","diagnostics","layout","sources"].includes(s)))throw new v("input","实例输出元数据只允许统计、诊断和字体度量;不保存来源令牌");if(M.validatePreparedMetadata({...r.output,plan:r.plan,revisions:{}}),r.output.sources?.some(s=>"sourceToken"in s))throw new v("input","实例来源清单不保存来源令牌")}return r.artifacts!==void 0&&ze(r.artifacts),r}function ze(e){if(!Array.isArray(e)||e.length>100)throw new v("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 v("input","实例文件应包含唯一存储键、格式、大小和可选 SHA256");t.add(r.key)}}function me(e){const{scope:t,id:r,revision:n,title:o,generatedAt:s,reportIds:a,params:u,templateRevisions:f,sourceRevisions:c}=e;return JSON.parse(JSON.stringify({scope:t,id:r,revision:n,title:o,generatedAt:s,reportIds:a,params:u,templateRevisions:f,sourceRevisions:c}))}function _e(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 v("input","实例存储预算应为正安全整数");return t}function Le(e={}){const t=_e(e),r=new Map;let n=0;return{read:async(o,s,a,u)=>{p.throwIfAborted(u),j(o,s);const f=r.get(JSON.stringify([o,s])),c=f?.get(a??f.size);return c?F(c,t.maxSnapshotBytes):void 0},list:async(o,s={})=>{p.throwIfAborted(s.signal),j(o,"list");const a=s.limit??25;if(!Number.isSafeInteger(a)||a<1||a>100)throw new v("input","实例每页数量应为 1–100");const u=Array.from(r.values(),f=>f.get(f.size)).filter(f=>f.scope===o&&(!s.after||f.id>s.after)&&(!s.reportId||f.reportIds.includes(s.reportId))).sort((f,c)=>f.id<c.id?-1:1).slice(0,a+1);return{items:u.slice(0,a).map(me),...u.length>a?{next:u[a-1].id}:{}}},compareAndSwap:async(o,s,a,u,f)=>{p.throwIfAborted(f),j(o,s);const c=F(u,t.maxSnapshotBytes);if(c.scope!==o||c.id!==s||c.revision!==(a??0)+1)throw new v("input","实例身份或修订不一致");const i=JSON.stringify([o,s]),d=r.get(i)??new Map;if((d.size||null)!==a)return!1;const l=new TextEncoder().encode(JSON.stringify(c)).byteLength;if(d.size>=t.maxRevisions||n+l>t.maxBytes||!d.size&&r.size>=t.maxInstances)throw new v("capacity","实例存储达到预算,请使用持久化归档策略或显式调整容量");return d.set(c.revision,c),r.set(i,d),n+=l,!0}}}function ye(e,t={}){const r=t.maxSnapshotBytes??8e6;if(!Number.isSafeInteger(r)||r<1)throw new v("input","实例快照字节预算应为正安全整数");return{read:e.read.bind(e),list:e.list.bind(e),save:async(n,o)=>{const s=o.expectedRevision;if(s!==null&&(!Number.isSafeInteger(s)||s<1||s>=Number.MAX_SAFE_INTEGER))throw new v("input","实例预期修订无效");const a=JSON.parse(we(n,r)),u=F({...a,revision:(s??0)+1},r);if(p.throwIfAborted(o.signal),!await e.compareAndSwap(u.scope,u.id,s,u,o.signal))throw new v("conflict","实例已存在或已变化,请显式确认修订后保存");return u}}}function Fe(e,t){return h.serializeJobJson({reportIds:e,params:t})}function Ve(e){if(!e||typeof e!="object"||Object.getOwnPropertySymbols(e).length)throw new v("input","生成请求应为普通对象");const t=Object.create(null);let r;const n=new Set(["scope","id","title","reportIds","params","expectedRevision","signal"]);for(const o of Object.getOwnPropertyNames(e)){const s=Object.getOwnPropertyDescriptor(e,o);if(!n.has(o)||!s.enumerable||s.get||s.set)throw new v("input","生成请求不能包含未知字段或访问器");o==="signal"?r=s.value:s.value!==void 0&&(t[o]=s.value)}return{signal:r,request:JSON.parse(h.serializeJobJson(t))}}function he(e){const t=JSON.parse(h.serializeJobJson(e.templateRevisions)),r=M.snapshotPdfFonts(e.pdf),n=ye(e.instances,{maxSnapshotBytes:e.maxSnapshotBytes});return{async generate(o){const{signal:s,request:a}=Ve(o);if(j(a.scope,a.id),a.expectedRevision!==null&&(!Number.isSafeInteger(a.expectedRevision)||a.expectedRevision<1))throw new v("input","实例预期修订无效");const u=e.runtime.validate(a);if(!u.ok)throw new fe.ReportParamValidationError(u.issues);const f=Object.create(null);for(const g of a.reportIds){if(typeof t[g]!="string"||!t[g])throw new TypeError(`报表 ${g} 缺少生成时的模板修订`);f[g]=t[g]}if(p.throwIfAborted(s),((await e.instances.read(a.scope,a.id,void 0,s))?.revision??null)!==a.expectedRevision)throw new v("conflict","实例已存在或已变化,请显式确认修订后生成");const i=await e.runtime.prepare({reportIds:a.reportIds,params:u.values,pdf:r,signal:s});p.throwIfAborted(s);const d=Object.create(null);for(const[g,R]of Object.entries(i.revisions))R.revision!==void 0&&(d[g]=R.revision);const{plan:l,revisions:w,sources:m,...b}=i,y={...b,...m?{sources:m.map(({sourceToken:g,...R})=>R)}:{}};return n.save({scope:a.scope,id:a.id,title:a.title,reportIds:a.reportIds,params:u.values,templateRevisions:f,sourceRevisions:d,generatedAt:(e.now?.()??new Date).toISOString(),plan:l,output:y},{expectedRevision:a.expectedRevision,signal:s})},read:n.read,list:n.list,async exportInstance(o){const{scope:s,id:a,revision:u,signal:f,format:c,fidelity:i,taskId:d,correlationId:l,onEvent:w}=o,m=M.snapshotPdfFonts(o.pdf??r),b=M.snapshotXlsxOptions(o.xlsx);j(s,a),p.throwIfAborted(f);const y=await n.read(s,a,u,f);if(!y)throw new v("input","报表实例不存在");const g={plan:y.plan,revisions:Object.fromEntries(y.reportIds.map(R=>[R,{revision:y.sourceRevisions[R]}])),diagnostics:[{code:"instance-row-count",severity:"info",message:"历史实例未保存原始取数行数;本次 rows 统计为 0,页面及单元格数由已保存计划校验。"}],stats:{rows:0,pages:y.plan.pages.length,cells:0,durationMs:0},...y.output};return e.runtime.exportPrepared({prepared:g,format:c,fidelity:i,pdf:m,xlsx:b,signal:f,taskId:d,correlationId:l,onEvent:w})},save:n.save}}function z(e,t,r){if(!Number.isSafeInteger(e)||e<1||e>t)throw new RangeError(`${r} 应为 1–${t} 的安全整数`);return e}function re(e){if(!e||typeof e.key!="string"||!e.key.trim()||e.key.length>1024||!["pdf","xlsx"].includes(e.format)||!Number.isSafeInteger(e.bytes)||e.bytes<0||e.sha256!==void 0&&!/^[a-f0-9]{64}$/i.test(e.sha256))throw new TypeError("分批归档回执应包含存储键、格式、大小和可选 SHA256");return{key:e.key,format:e.format,bytes:e.bytes,...e.sha256?{sha256:e.sha256}:{}}}function He(e){if(!O.validateReportTemplate(e).ok||!e.repeat)throw new TypeError("分批生成仅支持有效的逐记录固定标签模板");return JSON.parse(JSON.stringify(e))}function Ue(e){const t=new Set,r=e.repeat;r.rowKey&&t.add(r.rowKey),typeof r.copies=="object"&&t.add(r.copies.field);const n=o=>{o.binding&&t.add(o.binding.field);for(const s of o.grid?.cells??[])for(const a of s)a?.children?.forEach(n)};return e.pages.forEach(o=>o.components.forEach(s=>n(s))),[...t]}function Ke(e,t,r,n){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError(`标签记录 ${n} 应为对象`);const o=Object.create(null);for(const s of t){const a=de.readRecordScalar(e,s,{dataset:r,rowIndex:n});if(typeof a=="string"&&a.length>1e6)throw new p.ReportRuntimeError("budget","标签字段超过 1 MB 字符预算",`$.datasets.${r}[${n}].${s}`);a!==void 0&&(o[s]=a)}return o}function Ze(e,t,r,n){const o=t.repeat;if(!o.rowKey)return;const s=de.readRecordScalar(e,o.rowKey,{rowIndex:n,dataset:o.dataset});if(!(typeof s=="string"&&s.trim()||typeof s=="number"&&Number.isFinite(s)))throw new TypeError(`标签记录 ${n} 的业务主键无效`);const a=JSON.stringify([typeof s,s]);if(r.keys.has(a))throw new TypeError(`标签记录 ${n} 的业务主键重复(包含先前批次)`);r.bytes+=a.length*2+64,r.keys.add(a)}function Xe(e){return Object.entries(e).reduce((t,[r,n])=>t+64+r.length*2+(typeof n=="string"?n.length*2:8),0)}function Ge(e,t){if(!t)return e;for(const r of e.plan.pages){const n=r.meta?.record;n&&typeof n=="object"&&"rowIndex"in n&&typeof n.rowIndex=="number"&&(n.rowIndex+=t)}return e}async function Qe(e,t){if(!e.return)return;const r=Promise.resolve(e.return());if(t.aborted){r.catch(()=>{});return}await p.controlled(t,void 0,()=>r)}async function ne(e,t,r){const n=Promise.resolve().then(()=>e.onReceipt?.(t,r));n.catch(()=>{}),await p.controlled(r.signal,void 0,()=>n)}function We(e,t,r){return new Promise((n,o)=>{let s=!1,a=!1,u;const f=()=>{clearTimeout(u),t.removeEventListener("abort",c)},c=()=>{s||u!==void 0||(u=setTimeout(()=>{if(!s){s=!0,a=!0,f();try{p.throwIfAborted(t)}catch(i){o(i)}}},0))};e.then(i=>{if(a){Promise.resolve().then(()=>r(i)).catch(()=>{});return}s||(s=!0,f(),n(i))},i=>{s||(s=!0,f(),o(i))}),t.addEventListener("abort",c,{once:!0}),t.aborted&&c()})}async function Ye(e,t){const r=z(t.batchSize??100,1e3,"batchSize"),n=z(t.maxRows??1e5,1e6,"maxRows"),o=z(t.maxChunks??1e3,1e4,"maxChunks"),s=z(t.maxRetainedBytes??16e6,64e6,"maxRetainedBytes"),a=He(t.template),u=Ue(a);if(!e||typeof e[Symbol.asyncIterator]!="function")throw new TypeError("标签来源应为 AsyncIterable");return p.controlled(t.signal,t.runtime?.budget?.maxDurationMs??12e4,async f=>{const c={rows:0,chunks:[]},i={keys:new Set,bytes:0},d=e[Symbol.asyncIterator]();let l=!1,w=!1,m;const b=()=>m??=Qe(d,f),y=()=>{l||b().catch(()=>{})};f.addEventListener("abort",y,{once:!0});try{for(;!l;){p.throwIfAborted(f);const g=[];let R=0;for(;g.length<r;){const x=await p.controlled(f,void 0,()=>Promise.resolve(d.next()));if(x.done){l=!0;break}if(c.rows+g.length>=n)throw new p.ReportRuntimeError("budget","标签来源行数超过预算","$.maxRows");if(c.chunks.length>=o)throw new p.ReportRuntimeError("budget","标签分块数量超过预算","$.maxChunks");const S=Ke(x.value,u,a.repeat.dataset,c.rows+g.length);if(Ze(S,a,i,c.rows+g.length),R+=Xe(S),i.bytes+R>s)throw new p.ReportRuntimeError("budget","标签当前块字段与全局主键索引超过内存预算","$.maxRetainedBytes");g.push(S)}if(!g.length)break;const P=H.createReportRuntime({...t.runtime,reports:{labels:{template:a,datasets:{[a.repeat.dataset]:g}}}});let N;const E={index:c.chunks.length,rowOffset:c.rows,rowCount:g.length,signal:f,export:x=>P.exportPrepared({pdf:t.pdf,...x,prepared:N,signal:f})};let $;const T=(await h.runReportBatch([{id:`labels-${E.index}`,params:{}}],async()=>{try{N=Ge(await P.prepare({reportIds:["labels"],pdf:t.pdf,signal:f}),E.rowOffset),p.throwIfAborted(f);const x=Promise.resolve(t.execute(N,E)),S=await We(x,f,A=>ne(t,re(A),E));return re(S)}catch(x){throw $=x,x}},{concurrency:1,signal:f,failure:"stop"}))[0];if(T.status==="cancelled")throw p.throwIfAborted(f),new Error("标签分批任务已取消");if(T.status==="failed")throw $??new Error(T.error.message);c.chunks.push({...T.value,index:E.index,rowOffset:E.rowOffset,rowCount:E.rowCount}),c.rows+=g.length,await ne(t,T.value,E)}return c}catch(g){throw w=!0,g}finally{f.removeEventListener("abort",y),l||await b().catch(g=>{if(!w)throw g})}})}async function ge(e,t){const r=t.document().id,n=()=>t.editor.saving||t.editor.blocked;if(n())throw new Error("草稿尚未保存,请处理设计器提示后再发布");if(t.editor.pendingLocalChanges){const s=t.successfulSaves();if(await t.editor.save(),await t.afterSave(),t.successfulSaves()===s||t.editor.pendingLocalChanges||n())throw new Error("草稿尚未保存,请处理设计器提示后再发布")}const o=t.document();if(o.id!==r)throw new v("conflict","当前模板已切换,请重新确认后发布");return e.publish(o.id,{expectedRevision:o.revision??null})}function be(e,t){return{async search(r){p.throwIfAborted(r.signal);const n=await e.list(r.signal);if(n.length>1e3)throw new RangeError("本地模板连接目录最多 1000 项;更大目录请使用宿主分页查询适配器");const o=[];for(const s of n){p.throwIfAborted(r.signal);const[a,u]=await Promise.all([e.get(s.id,{draft:!0,signal:r.signal}),e.get(s.id,{signal:r.signal})]),f=a??u;f&&o.push({document:f,published:u,draftRevision:a?.revision,publishedRevision:u?.revision,...t?.(O.parseReportTemplate(f))})}return ce.createLocalTemplateCatalog(o).search(r)},async get(r,n){return n.mode==="published"?e.get(r,{signal:n.signal}):await e.get(r,{draft:!0,signal:n.signal})??e.get(r,{signal:n.signal})}}}function ve(e=1e3){if(!Number.isSafeInteger(e)||e<1||e>1e3)throw new RangeError("本地生成意图上限应为 1–1000");const t=new Map,r=globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;return{forCase(n,o){if(![n,o].every(f=>typeof f=="string"&&f.length>0&&f.length<=256))throw new TypeError("模板与参数组标识无效");const s=JSON.stringify([n,o]),a=t.get(s);if(a)return a;if(t.size>=e)throw new RangeError("本地生成意图已达上限,请使用持久化任务服务");const u=`instance-${r}-${(t.size+1).toString(36)}`;return t.set(s,u),u}}}function et(e,t,r){const n=Object.keys(r);return e.reportIds.length===1&&e.reportIds[0]===t.id&&Object.keys(e.templateRevisions).length===1&&e.templateRevisions[t.id]===t.revision&&Object.keys(e.params).length===n.length&&n.every(o=>r[o]===e.params[o])}function oe(e){return{instanceId:e.id,label:e.title}}function tt(e,t,r){const n=O.parseReportTemplate(e);if(!n.revision)throw new Error("请先发布该模板");const o=typeof t.data=="function"?t.data(O.parseReportTemplate(n)):t.data,s=H.createReportRuntime({...t.runtime,reports:{[n.id]:{...o,template:n.template}}}),a=he({runtime:s,instances:t.instances,templateRevisions:{[n.id]:n.revision},pdf:t.pdf});async function u(f,c,i){p.throwIfAborted(i);const d=await t.instances.read(t.scope,f,void 0,i);if(p.throwIfAborted(i),!!d){if(!et(d,n,c))throw new v("conflict","此参数组已用于其他参数或发布修订,请复制为新任务生成");return oe(d)}}return{document:O.parseReportTemplate(n),async execute(f,{signal:c}){p.throwIfAborted(c);const i=s.validate({reportIds:[n.id],params:f.params});if(!i.ok)throw new Error(i.issues[0]?.message??"生成参数无效");const d=r(n.id,f.id),l=await u(d,i.values,c);if(l)return l;try{return oe(await a.generate({scope:t.scope,id:d,title:(t.title?.(O.parseReportTemplate(n),f,i.values)??`${n.name} · ${f.id}`).slice(0,512),reportIds:[n.id],params:i.values,expectedRevision:null,signal:c}))}catch(w){if(w instanceof v&&w.code==="conflict"){const m=await u(d,i.values,c);if(m)return m}throw w}}}}function rt(e){e={...e};const t=ve(),r=e.instanceId??t.forCase;return{catalog:e.catalog??be(e.templates,e.catalogMetadata),publish:n=>ge(e.templates,n),async batch(n,o={}){const{expectedRevision:s,signal:a}=o,u=await e.templates.get(n,{signal:a});if(p.throwIfAborted(a),!u?.revision)throw new Error("请先发布该模板");if(s!==void 0&&u.revision!==s)throw new v("conflict","模板发布版本已变化,请重新打开后生成");return tt(u,e,r)}}}const Re="2.17.0";function U(e,t){const r=t?.componentPath;if(!Number.isSafeInteger(t?.pageIndex)||t.pageIndex<0||!Array.isArray(r)||r.length<1||r.length>31||r.length%3!==1||r.some(o=>!Number.isSafeInteger(o)||o<0))throw new TypeError("模板包图片位置无效");let n=e.template.pages[t.pageIndex]?.components[r[0]];for(let o=1;n&&o<r.length;o+=3)n=n.grid?.cells[r[o]]?.[r[o+1]]?.children?.[r[o+2]];if(!n||n.kind!=="image"||n.binding)throw new TypeError("模板包图片位置应指向静态图片组件");return n}function nt(e){const t=["id","kind","mediaType","bytes","sha256","license","font","targets"];if(!e||Object.keys(e).some(r=>!t.includes(r)))throw new TypeError("模板资源包含未知字段");if(typeof e.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(e.id))throw new TypeError("模板资源ID应为安全标识");if(!Number.isSafeInteger(e.bytes)||e.bytes<1||e.bytes>32e6||!/^[a-f0-9]{64}$/.test(e.sha256))throw new TypeError("模板资源大小或SHA256无效");if(e.license!==void 0&&(typeof e.license!="string"||e.license.length>512))throw new TypeError("模板资源许可说明无效")}function ot(e,t){if(nt(e),e.kind==="font"){if(!["font/ttf","font/otf"].includes(e.mediaType)||e.targets!==void 0)throw new TypeError("字体资源类型无效");const r=e.font;if(!r||typeof r.family!="string"||!r.family.trim()||r.family.length>128||!["regular","bold","italic","boldItalic"].includes(r.face)||Object.keys(r).some(n=>!["family","face"].includes(n)))throw new TypeError("字体资源需要family和face");return}if(e.kind!=="image"||!["image/png","image/jpeg"].includes(e.mediaType)||e.font!==void 0)throw new TypeError("模板图片仅支持PNG/JPEG");if(!Array.isArray(e.targets)||!e.targets.length||e.targets.length>1e3)throw new TypeError("模板图片需要1–1000个位置");for(const r of e.targets){if(Object.keys(r).some(n=>!["pageIndex","componentPath"].includes(n)))throw new TypeError("模板图片位置包含未知字段");U(t,r)}}function st(e,t){const r=n=>n.every((o,s)=>e[s]===o);return t==="image/png"?r([137,80,78,71,13,10,26,10]):t==="image/jpeg"?r([255,216,255]):t==="font/otf"?r([79,84,84,79]):r([0,1,0,0])||r([116,114,117,101])}function Ie(e){if(!(e instanceof Uint8Array)||!e.byteLength||e.byteLength>32e6)throw new RangeError("资源摘要只接受1–32MB字节");return p.portableSha256Hex(e)}function Se(e,t,r=le.createImageMediaInspector()){const n=new Set(t.flatMap(a=>(a.targets??[]).map(u=>U(e,u)))),o=new Map,s=a=>{if(a.imageData&&!n.has(a)){const u=r(a.imageData);o.set(u.dataUrl,u.bytes.byteLength)}for(const u of a.grid?.cells??[])for(const f of u)for(const c of f?.children??[])s(c)};for(const a of e.template.pages)for(const u of a.components)s(u);return[...o.values()].reduce((a,u)=>a+u,0)}function at(e,t){let r="";for(let n=0;n<e.length;n+=16384)r+=String.fromCharCode(...e.subarray(n,n+16384));return`data:${t};base64,${btoa(r)}`}async function it(e,t,r,n,o=3e4){if(!Number.isFinite(o)||o<1||o>2147483647)throw new RangeError("模板资源加载超时应为1–2147483647毫秒");return p.controlled(n,o,async s=>{const a=[],u=le.createImageMediaInspector();Se(e,t,u);for(const f of t){p.throwIfAborted(s);const c=await p.controlled(s,void 0,()=>Promise.resolve(r(JSON.parse(JSON.stringify(f)),{signal:s})));if(p.throwIfAborted(s),!c||!(c.bytes instanceof Uint8Array)||c.mediaType!==f.mediaType||c.bytes.byteLength!==f.bytes)throw new TypeError(`资源 ${f.id} 的类型或大小与清单不一致`);const i=new Uint8Array(c.bytes);if(!st(i,f.mediaType)||Ie(i)!==f.sha256)throw new TypeError(`资源 ${f.id} 的文件标识或SHA256与清单不一致`);if(f.kind==="font")a.push({id:f.id,family:f.font.family,face:f.font.face,bytes:i});else{const d=u(at(i,f.mediaType)).dataUrl;for(const l of f.targets)U(e,l).imageData=d}}return a})}function se(e){if(typeof e!="string"||!/^(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})\.(0|[1-9]\d{0,5})$/.test(e))throw new TypeError("模板包最低版本与运行版本应为正式版本x.y.z");return e.split(".").map(Number)}function ct(e,t){const r=se(e),n=se(t);for(let o=0;o<3;o++){if(n[o]>r[o])return;if(n[o]<r[o])throw new Error(`模板包需要MachReport ${e}或更新版本`)}}function X(e,t,r){const n=e??t;if(!Number.isSafeInteger(n)||n<1||n>r)throw new RangeError("模板包字节预算无效");return n}function ft(e){if(e.contracts!==void 0){if(!e.contracts||typeof e.contracts!="object"||Array.isArray(e.contracts)||Object.keys(e.contracts).length>100)throw new TypeError("模板包字段契约应为最多100个数据集");for(const[t,r]of Object.entries(e.contracts)){if(!t.trim()||t.length>256)throw new TypeError("模板包数据集名称无效");ue.validateDatasetRows([],r)}}}function dt(e,t){if(!e||e.deidentified!==!0||typeof e.name!="string"||!e.name.trim()||e.name.length>128)throw new TypeError("样例需要名称和明确的deidentified:true确认");if(Object.keys(e).some(n=>!["name","deidentified","datasets","params"].includes(n)))throw new TypeError("模板包样例包含未知字段");if(!e.datasets||typeof e.datasets!="object"||Array.isArray(e.datasets))throw new TypeError("模板包样例数据集无效");if(ut(e,t),!fe.validateReportParams(t.document.template.params??[],e.params).ok)throw new TypeError(`样例 ${e.name} 的参数不符合模板定义`)}function ut(e,t){let r=0;for(const o of Object.values(e.datasets))if(!Array.isArray(o)||o.some(s=>!s||typeof s!="object"||Array.isArray(s)))throw new TypeError("模板包样例应为对象行数组");const n=C.templateValidationDatasets(t.document.template,e.datasets,{maxRows:1e3});for(const[o,s]of Object.entries(n)){if(r+=s.length,r>1e3)throw new RangeError("模板包每个样例最多1000行");const a=t.contracts?.[o];if(a&&!ue.validateDatasetRows(s,a).ok)throw new TypeError(`样例 ${e.name} 不符合 ${o} 字段契约`)}for(const o of Object.keys(t.contracts??{}))if(!Object.prototype.hasOwnProperty.call(e.datasets,o))throw new TypeError(`样例 ${e.name} 缺少 ${o} 数据集`)}function lt(e){if(e.fixtures===void 0)return;if(!Array.isArray(e.fixtures)||e.fixtures.length>20)throw new RangeError("模板包最多20个脱敏样例");const t=new Set;for(const r of e.fixtures){if(dt(r,e),t.has(r.name))throw new TypeError("模板包样例名称重复");t.add(r.name)}}function pt(e,t){if(!Array.isArray(e.resources)||e.resources.length>64)throw new RangeError("模板包最多64个资源依赖");const r=new Set,n=new Set,o=new Set;let s=0;for(const a of e.resources){if(ot(a,e.document),r.has(a.id))throw new TypeError("模板资源ID重复");if(r.add(a.id),s+=a.bytes,s>t)throw new RangeError("模板包资源总大小超过预算");const u=a.font&&JSON.stringify([a.font.family,a.font.face]);if(u&&o.has(u))throw new TypeError("模板包字体family/face重复");u&&o.add(u);for(const f of a.targets??[]){const c=JSON.stringify([f.pageIndex,f.componentPath]);if(n.has(c))throw new TypeError("同一图片位置不能绑定多个资源");n.add(c)}}if(s+Se(e.document,e.resources)>t)throw new RangeError("模板包内嵌与外部资源总大小超过预算")}function G(e,t={}){p.throwIfAborted(t.signal);const r=X(t.maxBytes,8e6,32e6);if(typeof e=="string"){if(e.length>r||new TextEncoder().encode(e).byteLength>r)throw new RangeError("模板包JSON超过预算");e=JSON.parse(e)}const n=C.snapshotReportJson(e,{maxBytes:r,check:()=>p.throwIfAborted(t.signal),error:(o,s)=>new TypeError(s)});if(!n||typeof n!="object"||Array.isArray(n)||n.schemaVersion!=="1.0"||Object.keys(n).some(o=>!["schemaVersion","minimumVersion","document","contracts","resources","fixtures"].includes(o)))throw new TypeError("模板包结构或版本无效");return ct(n.minimumVersion,t.runtimeVersion??Re),n.document=O.parseReportTemplate(n.document),ft(n),lt(n),pt(n,X(t.maxResourceBytes,32e6,64e6)),n}function wt(e,t={}){const r=C.snapshotReportJson(e,{maxBytes:X(t.maxBytes,8e6,32e6),check:()=>p.throwIfAborted(t.signal),error:(o,s)=>new TypeError(s)}),n=G({schemaVersion:"1.0",...r,minimumVersion:r.minimumVersion??Re,resources:r.resources??[]},t);for(const o of n.resources)for(const s of o.targets??[])delete U(n.document,s).imageData;return n}async function mt(e,t){const{resolve:r,signal:n,maxDurationMs:o}=t,s=G(e,t),a=await it(s.document,s.resources,r,n,o);return{document:s.document,fonts:a,contracts:s.contracts,fixtures:s.fixtures??[]}}class I extends Error{constructor(t,r){super(r),this.code=t,this.name="ReportDocumentError"}}function yt(e={}){const t={maxDocuments:e.maxDocuments??32,maxBytes:e.maxBytes??64e6,maxPages:e.maxPages??1e4,maxPageBytes:e.maxPageBytes??4e6,maxManifestBytes:e.maxManifestBytes??1e6};if(Object.values(t).some(r=>!Number.isSafeInteger(r)||r<1))throw new I("input","文档预算应为正安全整数");return t}function J(e,t,r){if([e,t,...r===void 0?[]:[r]].some(n=>typeof n!="string"||!n.trim()||n.length>256))throw new I("input","文档 scope、id、version 应为 1–256 位非空字符串");return JSON.stringify([e,t])}function k(e,t,r){return C.snapshotReportJson(e,{maxBytes:t,maxNodes:t,check:()=>p.throwIfAborted(r),error:(n,o)=>new I(n==="budget"?"capacity":"input",o)})}function B(e){return new TextEncoder().encode(JSON.stringify(e)).byteLength}function ae(e){if(!e||e.schemaVersion!==Ee.RENDER_PLAN_SCHEMA_VERSION||"pages"in e||e.requiresRecalculation!==void 0&&typeof e.requiresRecalculation!="boolean")throw new I("input","文档计划头应使用当前版本,且不得携带 pages")}function _(e,t){e.bytes=0;for(let r=0;r<8;r++){const n=t+B(e);if(n===e.bytes)return;e.bytes=n}throw new I("capacity","文档容量统计无效")}function ht(e,t,r=[]){const n=new Map;let o=0,s=Promise.resolve();for(const i of r){const d=J(i.scope,i.id,i.version);if(ae(i.plan),n.has(d)||!Number.isSafeInteger(i.bytes)||i.bytes<0||!Number.isSafeInteger(i.pageCount)||i.pageCount<0||i.pageCount>t.maxPages||!["building","complete","failed"].includes(i.state)||i.revision!==i.pageCount+(i.state==="building"?0:1))throw new I("input","文档清单无效");n.set(d,k(i,t.maxManifestBytes)),o+=i.bytes}function a(i,d){if(o-(d?.bytes??0)+i.bytes>t.maxBytes||!d&&n.size>=t.maxDocuments)throw new I("capacity","文档存储容量已满,请显式清理旧文档")}if(n.size>t.maxDocuments||o>t.maxBytes)throw new I("capacity","已存文档超过预算");const u=i=>{const d=s.then(i);return s=d.then(()=>{},()=>{}),d},f=(i,d,l,w)=>{const m=n.get(J(i,d,l));if(!m)throw new I("missing","文档不存在");if(m.version!==l||w!==void 0&&m.revision!==w)throw new I("conflict","文档已变化,请重新读取清单");return m},c=async(i,d,l)=>{const w=k(i,t.maxManifestBytes);return a(w,d),await e.write(w,l),n.set(J(i.scope,i.id),w),o+=i.bytes-(d?.bytes??0),k(w,t.maxManifestBytes)};return{create:(i,d)=>{const l=k(i,t.maxManifestBytes,d),w=J(l.scope,l.id,l.version);return ae(l.plan),u(async()=>{if(p.throwIfAborted(d),n.has(w))throw new I("conflict","文档已存在,不可覆盖");const m={...l,revision:0,state:"building",pageCount:0,bytes:0};return _(m,0),c(m)})},append:(i,d,l,w,m,b)=>{const y=k(m,t.maxPageBytes,b),g=O.validateRenderPlan({pages:[y]});if(!g.ok)throw new I("input",g.errors[0].message);return u(async()=>{p.throwIfAborted(b);const R=f(i,d,l,w);if(R.state!=="building")throw new I("conflict","已完成文档不可追加");if(R.pageCount>=t.maxPages)throw new I("capacity","文档页数超过预算");const P={...R,revision:w+1,pageCount:R.pageCount+1};return _(P,R.bytes-B(R)+B(y)),c(P,R,{index:R.pageCount,value:y})})},complete:(i,d,l,w,m,b)=>{const y=m===void 0?void 0:k(m,t.maxManifestBytes,b);return y&&M.validatePreparedMetadata({...y}),u(async()=>{p.throwIfAborted(b);const g=f(i,d,l,w);if(g.state!=="building")throw new I("conflict","文档已完成");if(y&&y.stats.pages!==g.pageCount)throw new I("input","准备结果页数与文档页数不一致");const R={...g,revision:w+1,state:"complete",...y?{metadata:y}:{}};return _(R,g.bytes-B(g)),c(R,g)})},fail:(i,d,l,w,m)=>{const b=k(m,4096);if(!b||!["cancelled","generation"].includes(b.code)||typeof b.message!="string"||!b.message.trim()||b.message.length>1024)throw new I("input","文档失败状态无效");return u(async()=>{const y=f(i,d,l,w);if(y.state!=="building")throw new I("conflict","终态文档不可变更");const g={...y,state:"failed",revision:w+1,failure:b};return _(g,y.bytes-B(y)),c(g,y)})},read:async(i,d,l)=>{p.throwIfAborted(l);const w=J(i,d);await s,p.throwIfAborted(l);const m=n.get(w);return m?k(m,t.maxManifestBytes):void 0},readPage:(i,d,l,w,m)=>u(async()=>{p.throwIfAborted(m);const b=f(i,d,l);if(!Number.isSafeInteger(w)||w<0)throw new I("input","页索引应为非负安全整数");if(w>=b.pageCount)return;const y=await e.readPage(i,d,w);if(p.throwIfAborted(m),!y)throw new I("missing","已提交的文档页缺失");return k(y,t.maxPageBytes,m)}),remove:(i,d,l,w)=>u(async()=>{p.throwIfAborted(w);const m=J(i,d,l),b=n.get(m);return b?(f(i,d,l),await e.remove(b),n.delete(m),o-=b.bytes,!0):!1})}}function gt(e={}){const t=new Map;return ht({write:async(r,n)=>{if(!n)return;const o=J(r.scope,r.id),s=t.get(o)??[];s[n.index]=n.value,t.set(o,s)},readPage:async(r,n,o)=>t.get(J(r,n))?.[o],remove:async r=>{t.delete(J(r.scope,r.id))}},yt(e))}async function bt(e,t){const r=t.fromPage??0,n=t.limit??4,o=t.maxBytes??8e6;if(!Number.isSafeInteger(r)||r<0||!Number.isSafeInteger(n)||n<1||n>32||!Number.isSafeInteger(o)||o<1)throw new I("input","页窗口参数无效;每次最多读取 32 页");const s=await e.read(t.scope,t.id,t.signal);if(!s)throw new I("missing","文档不存在");if(s.version!==t.version)throw new I("conflict","文档版本已变化");const a=[];let u=0,f=Math.min(r,s.pageCount);for(;f<Math.min(s.pageCount,r+n);f++){const c=await e.readPage(t.scope,t.id,t.version,f,t.signal);if(!c)throw new I("missing","文档页缺失");const i=B(c);if(u+i>o){if(!a.length)throw new I("capacity","单页超过读取窗口预算");break}a.push(c),u+=i}return{manifest:s,pages:a,nextPage:f}}async function vt(e,t){const{scope:r,id:n,version:o,signal:s,pages:a}=t,u=t.metadata===void 0?void 0:k(t.metadata,1e6,s);let f=await e.create({scope:r,id:n,version:o,plan:t.plan},s),c;try{const i=Symbol.asyncIterator in a?a[Symbol.asyncIterator]():a[Symbol.iterator]();for(c=i;;){const d=await p.controlled(s,void 0,()=>Promise.resolve(i.next()));if(d.done)break;f=await e.append(r,n,o,f.revision,d.value,s)}return await e.complete(r,n,o,f.revision,u,s)}catch(i){throw Promise.resolve(c?.return?.()).catch(()=>{}),await e.fail(r,n,o,f.revision,s?.aborted?{code:"cancelled",message:"报表文档生成已取消"}:{code:"generation",message:"报表文档生成失败"}).catch(()=>{}),i}}const xe="1.0",ie=Object.freeze({params:422,validate:422,fetch:502,config:400,input:400,budget:413,capacity:413,timeout:504,"queue-full":429,closed:503,cancelled:499,"output-fidelity":422,conflict:409,missing:404});function V(e){return e&&typeof e=="object"?e:{}}function Rt(e){if(Array.isArray(e))return e.slice(0,100).map(t=>Object.fromEntries(["code","path","field","message"].flatMap(r=>typeof V(t)[r]=="string"?[[r,V(t)[r].slice(0,4096)]]:[])))}function It(e,t){const r=V(e),n=r.name==="AbortError"?"cancelled":r.code,o=typeof n=="string"&&Object.prototype.hasOwnProperty.call(ie,n)?n:"internal",s=o==="internal"?void 0:Rt(r.issues??V(r.cause).issues);return{status:ie[o]??500,body:{error:{code:o,message:o==="internal"?"Report execution failed":typeof r.message=="string"?r.message.slice(0,4096):"Report request failed",correlationId:t.slice(0,128),...o!=="internal"&&typeof r.path=="string"?{path:r.path.slice(0,4096)}:{},...s?{issues:s}:{}}}}}function Z(e,t,r){return{description:r,headers:{"X-Request-Id":{schema:{type:"string"},description:"Request correlation identity"}},content:{[e]:{schema:t}}}}function St(e){return{type:"object",additionalProperties:!1,properties:Object.fromEntries(e.params.map(t=>[t.field,{type:"string"}])),required:e.params.filter(t=>t.required&&t.defaultValue===void 0).map(t=>t.field),"x-report-typedSchema":e.paramsSchema}}function xt(e,t={}){const r=t.basePath??"/reports";if(!/^\/[A-Za-z0-9/_-]*[A-Za-z0-9_-]$/.test(r))throw new Error("OpenAPI basePath 应为不含查询串、参数和尾斜线的绝对路径");const n={[r]:{get:{operationId:"describeReports",responses:{200:Z("application/json",{type:"array",items:{type:"object"}},"Authorized report descriptions")}}}},o=new Set;for(const s of e){if(!s.id.trim()||o.has(s.id)||[".",".."].includes(s.id))throw new Error("OpenAPI 报表 ID 应非空、唯一且不是路径跳转段");o.add(s.id);for(const a of["prepare","pdf","xlsx"]){const u=a==="prepare"?"prepare":`export/${a}`,f=a!=="prepare",c={200:Z(f?a==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"application/json",f?{type:"string",format:"binary"}:{type:"object",required:["plan","stats","diagnostics","revisions"]},f?"Report file":"Prepared report snapshot")};for(const i of[400,413,422,429,499,500,502,503,504])c[String(i)]=Z("application/json",{$ref:"#/components/schemas/ReportError"},"Structured report error");n[`${r}/${encodeURIComponent(s.id)}/${u}`]={post:{operationId:`report_${o.size}_${a}`,parameters:[{in:"header",name:"X-Request-Id",schema:{type:"string",pattern:"^[A-Za-z0-9._-]{1,80}$"}}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["params"],additionalProperties:!1,properties:{params:St(s)}}}}},responses:c,"x-report-datasets":s.datasetsSchema}}}}return{openapi:"3.1.0",info:{title:t.title??"MachReport HTTP",version:t.version??xe},paths:n,components:{schemas:{ReportError:{type:"object",required:["error"],properties:{error:{type:"object",required:["code","message","correlationId"],properties:{code:{type:"string"},message:{type:"string"},correlationId:{type:"string"},path:{type:"string"},issues:{type:"array",items:{type:"object",additionalProperties:{type:"string"}}}}}}}}}}}exports.createReportRuntime=H.createReportRuntime;exports.ReportRuntimeError=p.ReportRuntimeError;exports.ReportJobError=h.ReportJobError;exports.checkJobIdentity=h.checkJobIdentity;exports.cloneJob=h.cloneJob;exports.createMemoryReportJobStore=h.createMemoryReportJobStore;exports.runReportBatch=h.runReportBatch;exports.runnableJob=h.runnableJob;exports.serializeJobJson=h.serializeJobJson;exports.snapshotReportBatchCases=h.snapshotReportBatchCases;exports.validateJobRecord=h.validateJobRecord;exports.validateJobTransition=h.validateJobTransition;exports.REPORT_HTTP_CONTRACT_VERSION=xe;exports.ReportDocumentError=I;exports.ReportInstanceError=v;exports.checkInstanceIdentity=j;exports.createManagerTemplateCatalog=be;exports.createMemoryReportDocumentStore=gt;exports.createMemoryReportInstanceIds=ve;exports.createMemoryReportInstanceStore=Le;exports.createReportGenerationService=he;exports.createReportInstanceManager=ye;exports.createReportJobService=Ne;exports.createReportOpenApi=xt;exports.createReportTaskQueue=Ae;exports.createReportTemplatePackage=wt;exports.createReportWorkflow=rt;exports.parseReportTemplatePackage=G;exports.readReportDocumentPages=bt;exports.reportHttpError=It;exports.reportInstanceParameterKey=Fe;exports.reportInstanceSummary=me;exports.reportPackageResourceDigest=Ie;exports.resolveReportTemplatePackage=mt;exports.reviewReportPublication=Me;exports.runLabelStream=Ye;exports.saveAndPublishReportTemplate=ge;exports.snapshotReportInstance=F;exports.writeReportDocument=vt;
|
package/dist/server.d.cts
CHANGED
|
@@ -35,6 +35,8 @@ declare interface AssetRenderBudget {
|
|
|
35
35
|
|
|
36
36
|
declare interface AssetRenderOptions extends OutputDiagnosticOptions, ImageMediaOptions {
|
|
37
37
|
assetRenderers?: Partial<Record<ImageComponentKind, ComponentImageRenderer>>;
|
|
38
|
+
/** Explicit id/version registry; unbound components continue using assetRenderers by kind. */
|
|
39
|
+
assetRegistry?: ComponentAssetRegistry;
|
|
38
40
|
assetBudget?: AssetRenderBudget;
|
|
39
41
|
/** Default throw prevents an incomplete export; placeholder retains the component and emits diagnostics. */
|
|
40
42
|
assetFailure?: "throw" | "placeholder";
|
|
@@ -117,6 +119,11 @@ declare type ColumnFormat_2 = {
|
|
|
117
119
|
pattern?: string;
|
|
118
120
|
};
|
|
119
121
|
|
|
122
|
+
declare interface ComponentAssetRegistry {
|
|
123
|
+
rendererFor(component: Readonly<PlanComponent>): ComponentImageRenderer | undefined;
|
|
124
|
+
hasExtension(id: string, version: string, kind: string): boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
120
127
|
/** A literal own field of the current label record; expressions and paths are not evaluated. */
|
|
121
128
|
declare interface ComponentBinding {
|
|
122
129
|
field: string;
|
|
@@ -219,6 +226,9 @@ declare interface ComputedField_2 extends ExpressionOptions_2 {
|
|
|
219
226
|
|
|
220
227
|
export declare function createManagerTemplateCatalog(manager: ReportTemplateManager, metadata?: (document: ReportTemplateDocument) => Pick<LocalTemplateCatalogItem, "category" | "tags">): ReportTemplateCatalogProvider;
|
|
221
228
|
|
|
229
|
+
/** Bounded, single-process reference store. Scope is host-authorized identity, never a client permission. */
|
|
230
|
+
export declare function createMemoryReportDocumentStore(options?: ReportDocumentBudget): ReportDocumentStore;
|
|
231
|
+
|
|
222
232
|
/** Session-local intents; durable hosts should supply their own authorized stable IDs. */
|
|
223
233
|
export declare function createMemoryReportInstanceIds(maximum?: number): {
|
|
224
234
|
forCase(templateId: string, caseId: string): string;
|
|
@@ -270,6 +280,13 @@ export declare function createReportInstanceManager(store: ReportInstanceStore,
|
|
|
270
280
|
/** Durable at-least-once dispatch; export/artifact handlers must be idempotent by scope+taskId. */
|
|
271
281
|
export declare function createReportJobService(options: ReportJobServiceOptions): ReportJobService;
|
|
272
282
|
|
|
283
|
+
/** OpenAPI 3.1 for the minimal Java/Node wire contract. Host registers routes and authorizes IDs before describe(). */
|
|
284
|
+
export declare function createReportOpenApi(descriptions: readonly ReportDescription[], options?: {
|
|
285
|
+
title?: string;
|
|
286
|
+
version?: string;
|
|
287
|
+
basePath?: string;
|
|
288
|
+
}): Record<string, unknown>;
|
|
289
|
+
|
|
273
290
|
/** 无 Vue、无 HTTP 框架的可选服务端外观;PDF/Excel 仅在对应 export 调用时加载。 */
|
|
274
291
|
export declare function createReportRuntime(options: ReportRuntimeOptions): ReportRuntime;
|
|
275
292
|
|
|
@@ -342,6 +359,8 @@ declare interface FormulaAdapter {
|
|
|
342
359
|
}
|
|
343
360
|
|
|
344
361
|
declare interface GridCell {
|
|
362
|
+
/** Styled cell content; text remains a plain-text fallback. Imported rich cells are read-only. */
|
|
363
|
+
richParagraphs?: RichParagraph[];
|
|
345
364
|
text?: string;
|
|
346
365
|
rawText?: string;
|
|
347
366
|
/** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
|
|
@@ -366,6 +385,8 @@ declare interface GridCell {
|
|
|
366
385
|
}
|
|
367
386
|
|
|
368
387
|
declare interface GridCell_2 {
|
|
388
|
+
/** Styled cell content; text remains a plain-text fallback. Imported rich cells are read-only. */
|
|
389
|
+
richParagraphs?: RichParagraph_2[];
|
|
369
390
|
text?: string;
|
|
370
391
|
rawText?: string;
|
|
371
392
|
/** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
|
|
@@ -705,6 +726,46 @@ declare interface LocalTemplateCatalogItem {
|
|
|
705
726
|
tags?: string[];
|
|
706
727
|
}
|
|
707
728
|
|
|
729
|
+
declare interface MatrixAxisOptions {
|
|
730
|
+
/** Display names in the same outer-to-inner order as the dimension fields. */
|
|
731
|
+
labels?: readonly string[];
|
|
732
|
+
/** Per-level sibling order; omitted levels retain first-seen order. */
|
|
733
|
+
sort?: readonly MatrixDimensionOrder[];
|
|
734
|
+
/** One-based prefix depths. Leaf depths are not subtotals. */
|
|
735
|
+
subtotals?: readonly number[];
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
declare interface MatrixAxisOptions_2 {
|
|
739
|
+
/** Display names in the same outer-to-inner order as the dimension fields. */
|
|
740
|
+
labels?: readonly string[];
|
|
741
|
+
/** Per-level sibling order; omitted levels retain first-seen order. */
|
|
742
|
+
sort?: readonly MatrixDimensionOrder_2[];
|
|
743
|
+
/** One-based prefix depths. Leaf depths are not subtotals. */
|
|
744
|
+
subtotals?: readonly number[];
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
declare type MatrixDimensionOrder = "source" | "asc" | "desc";
|
|
748
|
+
|
|
749
|
+
declare type MatrixDimensionOrder_2 = "source" | "asc" | "desc";
|
|
750
|
+
|
|
751
|
+
declare interface MatrixHierarchyOptions {
|
|
752
|
+
row?: MatrixAxisOptions;
|
|
753
|
+
column?: MatrixAxisOptions;
|
|
754
|
+
/** Only null/missing values use this label; empty strings and zero stay distinct. */
|
|
755
|
+
emptyLabel?: string;
|
|
756
|
+
subtotalLabel?: string;
|
|
757
|
+
totalLabel?: string;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
declare interface MatrixHierarchyOptions_2 {
|
|
761
|
+
row?: MatrixAxisOptions_2;
|
|
762
|
+
column?: MatrixAxisOptions_2;
|
|
763
|
+
/** Only null/missing values use this label; empty strings and zero stay distinct. */
|
|
764
|
+
emptyLabel?: string;
|
|
765
|
+
subtotalLabel?: string;
|
|
766
|
+
totalLabel?: string;
|
|
767
|
+
}
|
|
768
|
+
|
|
708
769
|
declare interface MatrixTableOptions {
|
|
709
770
|
rowFields: readonly string[];
|
|
710
771
|
columnFields: readonly string[];
|
|
@@ -719,6 +780,10 @@ declare interface MatrixTableOptions {
|
|
|
719
780
|
maxColumns?: number;
|
|
720
781
|
maxInputRows?: number;
|
|
721
782
|
maxCells?: number;
|
|
783
|
+
/** Opt-in hierarchical dimensions, physical merged headers and prefix subtotals. */
|
|
784
|
+
hierarchy?: MatrixHierarchyOptions;
|
|
785
|
+
/** Hierarchical aggregate work, checked before measure reads; default 10 million updates. */
|
|
786
|
+
maxAggregateUpdates?: number;
|
|
722
787
|
}
|
|
723
788
|
|
|
724
789
|
declare interface MatrixTableOptions_2 {
|
|
@@ -735,6 +800,10 @@ declare interface MatrixTableOptions_2 {
|
|
|
735
800
|
maxColumns?: number;
|
|
736
801
|
maxInputRows?: number;
|
|
737
802
|
maxCells?: number;
|
|
803
|
+
/** Opt-in hierarchical dimensions, physical merged headers and prefix subtotals. */
|
|
804
|
+
hierarchy?: MatrixHierarchyOptions_2;
|
|
805
|
+
/** Hierarchical aggregate work, checked before measure reads; default 10 million updates. */
|
|
806
|
+
maxAggregateUpdates?: number;
|
|
738
807
|
}
|
|
739
808
|
|
|
740
809
|
export declare interface MemoryReportInstanceStoreOptions {
|
|
@@ -754,6 +823,11 @@ declare interface OutputDiagnostic {
|
|
|
754
823
|
componentPath?: readonly number[];
|
|
755
824
|
kind: string;
|
|
756
825
|
nid?: string;
|
|
826
|
+
/** Declarative extension identity only; no property values or business binding data enter diagnostics. */
|
|
827
|
+
extension?: {
|
|
828
|
+
id: string;
|
|
829
|
+
version: string;
|
|
830
|
+
};
|
|
757
831
|
message: string;
|
|
758
832
|
}
|
|
759
833
|
|
|
@@ -936,6 +1010,21 @@ export declare interface PreparedReport {
|
|
|
936
1010
|
|
|
937
1011
|
declare type PublicationAssets = Omit<AssetRenderOptions, "signal">;
|
|
938
1012
|
|
|
1013
|
+
/** Progressive consumption ends at the currently committed boundary; caller may resume with nextPage. */
|
|
1014
|
+
export declare function readReportDocumentPages(store: ReportDocumentStore, input: {
|
|
1015
|
+
scope: string;
|
|
1016
|
+
id: string;
|
|
1017
|
+
version: string;
|
|
1018
|
+
fromPage?: number;
|
|
1019
|
+
limit?: number;
|
|
1020
|
+
maxBytes?: number;
|
|
1021
|
+
signal?: AbortSignal;
|
|
1022
|
+
}): Promise<{
|
|
1023
|
+
manifest: ReportDocumentManifest;
|
|
1024
|
+
pages: PlanPage[];
|
|
1025
|
+
nextPage: number;
|
|
1026
|
+
}>;
|
|
1027
|
+
|
|
939
1028
|
declare interface RenderPlan {
|
|
940
1029
|
schemaVersion: string;
|
|
941
1030
|
/** 编辑需要模板重算上下文;跨 Worker/JSON 保留要求,但不声明本地会话可用。 */
|
|
@@ -943,6 +1032,8 @@ declare interface RenderPlan {
|
|
|
943
1032
|
pages: PlanPage[];
|
|
944
1033
|
}
|
|
945
1034
|
|
|
1035
|
+
export declare const REPORT_HTTP_CONTRACT_VERSION = "1.0";
|
|
1036
|
+
|
|
946
1037
|
export declare interface ReportBatchCase {
|
|
947
1038
|
id: string;
|
|
948
1039
|
params: Record<string, string>;
|
|
@@ -1081,6 +1172,46 @@ declare interface ReportDiagnostic {
|
|
|
1081
1172
|
target?: ReportDataTarget;
|
|
1082
1173
|
}
|
|
1083
1174
|
|
|
1175
|
+
export declare interface ReportDocumentBudget {
|
|
1176
|
+
maxDocuments?: number;
|
|
1177
|
+
maxBytes?: number;
|
|
1178
|
+
maxPages?: number;
|
|
1179
|
+
maxPageBytes?: number;
|
|
1180
|
+
maxManifestBytes?: number;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
export declare class ReportDocumentError extends Error {
|
|
1184
|
+
readonly code: "input" | "capacity" | "conflict" | "missing" | "closed";
|
|
1185
|
+
constructor(code: "input" | "capacity" | "conflict" | "missing" | "closed", message: string);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
export declare interface ReportDocumentManifest {
|
|
1189
|
+
scope: string;
|
|
1190
|
+
id: string;
|
|
1191
|
+
version: string;
|
|
1192
|
+
/** CAS token increases after each append and completion. */
|
|
1193
|
+
revision: number;
|
|
1194
|
+
state: "building" | "complete" | "failed";
|
|
1195
|
+
failure?: {
|
|
1196
|
+
code: "cancelled" | "generation";
|
|
1197
|
+
message: string;
|
|
1198
|
+
};
|
|
1199
|
+
pageCount: number;
|
|
1200
|
+
bytes: number;
|
|
1201
|
+
plan: Omit<RenderPlan, "pages">;
|
|
1202
|
+
metadata?: Omit<PreparedReport, "plan">;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
export declare interface ReportDocumentStore {
|
|
1206
|
+
create(input: Pick<ReportDocumentManifest, "scope" | "id" | "version" | "plan">, signal?: AbortSignal): Promise<ReportDocumentManifest>;
|
|
1207
|
+
append(scope: string, id: string, version: string, expectedRevision: number, page: PlanPage, signal?: AbortSignal): Promise<ReportDocumentManifest>;
|
|
1208
|
+
complete(scope: string, id: string, version: string, expectedRevision: number, metadata?: Omit<PreparedReport, "plan">, signal?: AbortSignal): Promise<ReportDocumentManifest>;
|
|
1209
|
+
fail(scope: string, id: string, version: string, expectedRevision: number, failure: NonNullable<ReportDocumentManifest["failure"]>): Promise<ReportDocumentManifest>;
|
|
1210
|
+
read(scope: string, id: string, signal?: AbortSignal): Promise<ReportDocumentManifest | undefined>;
|
|
1211
|
+
readPage(scope: string, id: string, version: string, index: number, signal?: AbortSignal): Promise<PlanPage | undefined>;
|
|
1212
|
+
remove(scope: string, id: string, version: string, signal?: AbortSignal): Promise<boolean>;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1084
1215
|
declare type ReportExpression = {
|
|
1085
1216
|
field: string;
|
|
1086
1217
|
} | {
|
|
@@ -1107,7 +1238,15 @@ declare type ReportExpression_2 = {
|
|
|
1107
1238
|
args: readonly ReportExpression_2[];
|
|
1108
1239
|
};
|
|
1109
1240
|
|
|
1110
|
-
declare
|
|
1241
|
+
declare type ReportFieldAggregation = "sum" | "avg" | "min" | "max" | "count" | "none";
|
|
1242
|
+
|
|
1243
|
+
declare interface ReportFieldCalculation {
|
|
1244
|
+
/** Business-owned explanation, never executable JavaScript or an inferred business formula. */
|
|
1245
|
+
description: string;
|
|
1246
|
+
dependsOn: readonly string[];
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
declare interface ReportFieldContract extends ReportFieldSemantics {
|
|
1111
1250
|
field: string;
|
|
1112
1251
|
label?: string;
|
|
1113
1252
|
type: "text" | "number" | "boolean" | "date" | "decimal";
|
|
@@ -1122,6 +1261,17 @@ declare interface ReportFieldContract {
|
|
|
1122
1261
|
unit?: string;
|
|
1123
1262
|
}
|
|
1124
1263
|
|
|
1264
|
+
declare interface ReportFieldSemantics {
|
|
1265
|
+
description?: string;
|
|
1266
|
+
/** Explicit meaning of null/missing; does not convert blanks into zero. */
|
|
1267
|
+
missingMeaning?: string;
|
|
1268
|
+
/** Recommended aggregation; none marks non-additive measures such as ratios. No aggregation runs implicitly. */
|
|
1269
|
+
aggregation?: ReportFieldAggregation;
|
|
1270
|
+
/** Shared presentation only; raw values and calculation precision remain unchanged. */
|
|
1271
|
+
format?: ColumnFormat;
|
|
1272
|
+
calculation?: ReportFieldCalculation;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1125
1275
|
declare interface ReportFlowBand {
|
|
1126
1276
|
/** Exact stable component IDs. Static components use nid, lists use id. */
|
|
1127
1277
|
componentIds: string[];
|
|
@@ -1148,6 +1298,22 @@ export declare interface ReportGenerationInput {
|
|
|
1148
1298
|
signal?: AbortSignal;
|
|
1149
1299
|
}
|
|
1150
1300
|
|
|
1301
|
+
/** Stable transport mapping; unexpected errors never expose exception details or stacks. */
|
|
1302
|
+
export declare function reportHttpError(error: unknown, correlationId: string): {
|
|
1303
|
+
status: number;
|
|
1304
|
+
body: ReportHttpErrorBody;
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
export declare interface ReportHttpErrorBody {
|
|
1308
|
+
error: {
|
|
1309
|
+
code: string;
|
|
1310
|
+
message: string;
|
|
1311
|
+
correlationId: string;
|
|
1312
|
+
path?: string;
|
|
1313
|
+
issues?: Record<string, string>[];
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1151
1317
|
export declare interface ReportInstanceArtifact {
|
|
1152
1318
|
key: string;
|
|
1153
1319
|
format: "pdf" | "xlsx";
|
|
@@ -1560,10 +1726,11 @@ export declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
|
|
|
1560
1726
|
format: "pdf" | "xlsx";
|
|
1561
1727
|
/** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
|
|
1562
1728
|
fidelity?: "warn" | "strict";
|
|
1563
|
-
xlsx?: {
|
|
1729
|
+
xlsx?: ImageMediaOptions & {
|
|
1564
1730
|
sheetMode?: "auto" | "pages" | "continuous";
|
|
1565
1731
|
valueMode?: "text" | "raw";
|
|
1566
1732
|
paperSize?: "auto" | "a3" | "a4" | "a5";
|
|
1733
|
+
sheetName?: (sheetIndex: number) => string;
|
|
1567
1734
|
};
|
|
1568
1735
|
}
|
|
1569
1736
|
|
|
@@ -1594,6 +1761,8 @@ export declare interface ReportRuntimeOptions {
|
|
|
1594
1761
|
/** Encode an existing plan without querying providers or repaginating. */
|
|
1595
1762
|
export declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
|
|
1596
1763
|
prepared: PreparedReport;
|
|
1764
|
+
/** verify checks font metric identity; preserve explicitly keeps existing geometry, with a diagnostic. Encoding fidelity is unchanged. */
|
|
1765
|
+
layoutPolicy?: "verify" | "preserve";
|
|
1597
1766
|
format: ReportRuntimeExportInput["format"];
|
|
1598
1767
|
fidelity?: ReportRuntimeExportInput["fidelity"];
|
|
1599
1768
|
pdf?: ReportPdfFontOptions;
|
|
@@ -2179,4 +2348,15 @@ declare type ValueFormat = ColumnFormat;
|
|
|
2179
2348
|
/** The same declarative formatting used by list columns, before any output backend. */
|
|
2180
2349
|
declare type ValueFormat_2 = ColumnFormat_2;
|
|
2181
2350
|
|
|
2351
|
+
/** Accepts paginateTemplatePages/AsyncIterable without retaining all pages; partial documents stay inspectable on failure. */
|
|
2352
|
+
export declare function writeReportDocument(store: ReportDocumentStore, input: {
|
|
2353
|
+
scope: string;
|
|
2354
|
+
id: string;
|
|
2355
|
+
version: string;
|
|
2356
|
+
plan: Omit<RenderPlan, "pages">;
|
|
2357
|
+
pages: Iterable<PlanPage> | AsyncIterable<PlanPage>;
|
|
2358
|
+
metadata?: Omit<PreparedReport, "plan">;
|
|
2359
|
+
signal?: AbortSignal;
|
|
2360
|
+
}): Promise<ReportDocumentManifest>;
|
|
2361
|
+
|
|
2182
2362
|
export { }
|