@agile-team/mach-report 2.12.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +27 -3
  2. package/dist/ExcelBindingWizard-CLT2p7P3.cjs +1 -0
  3. package/dist/ExcelBindingWizard-CvsWR8Ga.js +1485 -0
  4. package/dist/{ParamEditor-BLaE5q5W.js → ParamEditor-CflQV3eQ.js} +191 -187
  5. package/dist/ParamEditor-vIDzvpPV.cjs +1 -0
  6. package/dist/ReportBatchPanel-DkxTzBkD.cjs +1 -0
  7. package/dist/{ReportBatchPanel-B5ClP9tm.js → ReportBatchPanel-LqVgiqp7.js} +3 -3
  8. package/dist/ReportPreview-CvbqLUzM.cjs +6 -0
  9. package/dist/ReportPreview-D_ywJ_-H.js +4533 -0
  10. package/dist/{ReportTemplateLibrary-BZB-XWjj.js → ReportTemplateLibrary-MjWEtc7X.js} +1 -1
  11. package/dist/ReportTemplateLibrary-cQ1sqNYo.cjs +1 -0
  12. package/dist/RuleEditor-BaR6xUiI.cjs +1 -0
  13. package/dist/RuleEditor-ChuXMlei.js +2037 -0
  14. package/dist/TemplateOutlinePanel-BHKP89Xz.cjs +1 -0
  15. package/dist/TemplateOutlinePanel-Dci6aRn1.js +96 -0
  16. package/dist/TemplateReusePanel-B7Gmyc1z.js +388 -0
  17. package/dist/TemplateReusePanel-CY5eO2Sh.cjs +1 -0
  18. package/dist/TemplateReviewPanel-DjlX3xpt.js +592 -0
  19. package/dist/TemplateReviewPanel-JvZe9_4G.cjs +1 -0
  20. package/dist/{batch-mRqhhhjt.js → batch-DzaTNLWI.js} +23 -16
  21. package/dist/batch-xMkqYiTr.cjs +1 -0
  22. package/dist/config-0UIohTS7.cjs +1 -0
  23. package/dist/{config-B612mw0x.js → config-Dt9NtCPl.js} +227 -186
  24. package/dist/data-explanation-BktvER5B.cjs +1 -0
  25. package/dist/data-explanation-C_J6jYNi.js +16 -0
  26. package/dist/designer-Ci1LizA9.js +5020 -0
  27. package/dist/designer-rtmVIIdN.cjs +2 -0
  28. package/dist/designer.cjs +1 -2
  29. package/dist/designer.d.cts +306 -3
  30. package/dist/designer.d.ts +306 -3
  31. package/dist/designer.js +21 -4266
  32. package/dist/font-loader-DHto6Lra.js +297 -0
  33. package/dist/font-loader-vhCT8znW.cjs +1 -0
  34. package/dist/index.cjs +8 -8
  35. package/dist/index.d.cts +182 -1
  36. package/dist/index.d.ts +182 -1
  37. package/dist/index.js +728 -628
  38. package/dist/{template-review-BzpcI-tR.js → json-snapshot-BeFT3Tso.js} +867 -637
  39. package/dist/json-snapshot-D1NTP2oI.cjs +2 -0
  40. package/dist/pdf-8UPQebOE.js +36288 -0
  41. package/dist/pdf-AyJGb22z.cjs +101 -0
  42. package/dist/pdf.cjs +1 -101
  43. package/dist/pdf.js +9 -36579
  44. package/dist/plugin-BGKf-Tqg.js +22 -0
  45. package/dist/{plugin-BDTU4D94.cjs → plugin-CktLH_Iy.cjs} +1 -1
  46. package/dist/{region-binding-workflow-CcUq8W2Q.js → region-binding-workflow-DEJbhpCv.js} +1 -1
  47. package/dist/server/node.d.cts +46 -11
  48. package/dist/server/node.d.ts +46 -11
  49. package/dist/server-node.cjs +1 -1
  50. package/dist/server-node.js +294 -280
  51. package/dist/server.cjs +1 -1
  52. package/dist/server.d.cts +107 -12
  53. package/dist/server.d.ts +107 -12
  54. package/dist/server.js +713 -453
  55. package/dist/style.css +1 -1
  56. package/dist/template-bindings-BJR4k7qZ.cjs +1 -0
  57. package/dist/template-bindings-Daui7hLF.js +252 -0
  58. package/dist/template-fragments-CLkGo6To.js +187 -0
  59. package/dist/template-fragments-DFUpq5QM.cjs +1 -0
  60. package/dist/template-outline-B3xVkzSv.cjs +1 -0
  61. package/dist/template-outline-CFenM1PV.js +88 -0
  62. package/dist/{template-registry-BjE1VS6g.js → template-registry-COXDEJEM.js} +1 -1
  63. package/dist/{useLocalDraft-C07SYRnC.js → useLocalDraft-BnhcxXk_.js} +1 -1
  64. package/dist/{useLocalDraft-Yiw1wFgI.cjs → useLocalDraft-CioIfDb6.cjs} +1 -1
  65. package/dist/{validate-DbgEM1Hh.js → validate-CkQBWCeg.js} +3 -3
  66. package/dist/vue/async.d.cts +72 -2
  67. package/dist/vue/async.d.ts +72 -2
  68. package/dist/vue/index.d.cts +124 -5
  69. package/dist/vue/index.d.ts +124 -5
  70. package/dist/vue-async.cjs +1 -1
  71. package/dist/vue-async.js +5 -5
  72. package/dist/vue.cjs +1 -1
  73. package/dist/vue.js +78 -71
  74. package/dist/{workbook-session-BPb3TMnT.js → workbook-session-BfK1yHOO.js} +1 -1
  75. package/dist/worker.cjs +1 -1
  76. package/dist/worker.d.cts +46 -11
  77. package/dist/worker.d.ts +46 -11
  78. package/dist/worker.js +59 -55
  79. package/dist/xlsx.js +3 -3
  80. package/package.json +1 -1
  81. package/dist/ExcelBindingWizard-CeAf4QSE.js +0 -1465
  82. package/dist/ExcelBindingWizard-y0mT-AHR.cjs +0 -1
  83. package/dist/ParamEditor-MBBC7lUE.cjs +0 -1
  84. package/dist/ReportBatchPanel-Dc-SDkYA.cjs +0 -1
  85. package/dist/ReportPreview-DWXROHBP.cjs +0 -6
  86. package/dist/ReportPreview-DiNXhQI0.js +0 -4138
  87. package/dist/ReportTemplateLibrary-5fk5CQBO.cjs +0 -1
  88. package/dist/RuleEditor-ChRzNQuF.cjs +0 -1
  89. package/dist/RuleEditor-DzAmW5YH.js +0 -2024
  90. package/dist/TemplateReviewPanel-BKofGrV9.js +0 -222
  91. package/dist/TemplateReviewPanel-DwtOcLue.cjs +0 -1
  92. package/dist/batch-Bt3Fd27Z.cjs +0 -1
  93. package/dist/config-BRoLo2oj.cjs +0 -1
  94. package/dist/plugin-Cd5G2QQn.js +0 -22
  95. package/dist/record-bindings-By_UKZ2g.cjs +0 -1
  96. package/dist/record-bindings-D-5jQlTj.js +0 -196
  97. package/dist/template-review-BfCC8Ng9.cjs +0 -2
package/dist/worker.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("./task-events-DQ276fn2.cjs"),A=require("./validate-BJ5HIWY8.cjs"),u="mach-report-worker/1";class l extends Error{constructor(r){super(r.message),this.name=r.name,this.code=r.code,this.path=r.path,this.issues=r.issues,this.diagnostics=r.diagnostics}}function p(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function L(e){return p(e)?["rows","pages","cells"].every(r=>typeof e[r]=="number"&&Number.isSafeInteger(e[r])&&e[r]>=0)&&typeof e.durationMs=="number"&&Number.isFinite(e.durationMs)&&e.durationMs>=0:!1}function P(e){return Array.isArray(e)&&e.every(r=>p(r)&&typeof r.code=="string"&&typeof r.message=="string"&&["info","warning","error"].includes(r.severity))}function T(e){return p(e)&&Object.values(e).every(r=>p(r)&&(r.revision===void 0||typeof r.revision=="string")&&(r.sourceToken===void 0||typeof r.sourceToken=="string"))}function v(e,r){if(!p(e)||!L(e.stats)||!P(e.diagnostics)||!T(e.revisions))return!1;if(r==="prepare")return A.validateRenderPlan(e.plan).ok;const t=e.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";return e.bytes instanceof Uint8Array&&(e.format==="pdf"||e.format==="xlsx")&&e.contentType===t}function W(e){if(!e||typeof e!="object")return{message:String(e)};const r={};for(const t of["code","path","field","message"]){const o=e[t];typeof o=="string"&&(r[t]=o)}return r}function j(e){const r=W(e);if(!p(e))return r;for(const t of["format","severity","kind","nid"])typeof e[t]=="string"&&(r[t]=e[t]);for(const t of["pageIndex","componentIndex"])Number.isSafeInteger(e[t])&&e[t]>=0&&(r[t]=e[t]);return Array.isArray(e.componentPath)&&e.componentPath.every(t=>Number.isSafeInteger(t)&&t>=0)&&(r.componentPath=e.componentPath),r}function O(e){if(!(e instanceof Error))return{name:"Error",message:String(e)};const r=e;return{name:e.name,message:e.message,...typeof r.code=="string"?{code:r.code}:{},...typeof r.path=="string"?{path:r.path}:{},...Array.isArray(r.issues)?{issues:r.issues.map(W)}:{},...Array.isArray(r.diagnostics)?{diagnostics:r.diagnostics.map(j)}:{}}}function S(e){if(!e||typeof e!="object")return!1;const r=e;return r.protocol===u&&typeof r.id=="string"&&(r.operation==="prepare"||r.operation==="export")&&!!r.input&&typeof r.input=="object"}async function N(e,r,t){try{const o=r.operation==="prepare"?await e.prepare({...r.input,onEvent:t}):await e.export({...r.input,onEvent:t});return{protocol:u,id:r.id,result:o}}catch(o){return{protocol:u,id:r.id,error:O(o)}}}function z(e){const r=e.result;return!r||!("bytes"in r)||!(r.bytes.buffer instanceof ArrayBuffer)?[]:[r.bytes.buffer]}function _(e,r){if(!p(e)||typeof e.taskId!="string"||!e.taskId||r.taskId!==void 0&&e.taskId!==r.taskId||e.correlationId!==r.correlationId||e.reportId!==void 0&&(typeof e.reportId!="string"||!r.reportIds.includes(e.reportId))||!["query","validate","layout","assets","encode"].includes(e.stage)||!["started","completed","failed"].includes(e.status))return!1;for(const t of["completed","total"])if(e[t]!==void 0&&(typeof e[t]!="number"||!Number.isFinite(e[t])||e[t]<0))return!1;return e.completed===void 0||e.total===void 0||e.completed<=e.total}let q=0;function w(e){const r=new Error("报表 Worker 任务已取消");return r.name="AbortError",Object.defineProperty(r,"cause",{value:e}),r}function B(e,r){if(!e||typeof e!="object")return;const t=e;return t.protocol===u&&t.id===r?t:void 0}function F(e,r={}){const t=r.timeoutMs??12e4;if(!Number.isFinite(t)||t<=0||t>2147483647)throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");const o=(i,c,n,d)=>n?.aborted?Promise.reject(w(n.reason)):new Promise((I,b)=>{let g;try{g=e()}catch(a){b(a);return}const R=`mach-report-${Date.now()}-${++q}`;let y=!1,E=()=>{},k;const f=(a,s)=>{y||(y=!0,k&&clearTimeout(k),E(),n?.removeEventListener("abort",h),Promise.resolve().then(()=>g.terminate()).then(()=>a===void 0?I(s):b(a),m=>b(a??m)))},h=()=>f(w(n?.reason)),M=a=>{const s=B(a,R);if(!(!s||y)){if("type"in s&&s.type==="event"){const m="event"in s?s.event:void 0;_(m,c)?x.notifyReportTaskEvent(d,m,n):f(new Error("报表 Worker 返回无效阶段事件"));return}s.error&&typeof s.error.name=="string"&&typeof s.error.message=="string"?f(new l(s.error)):v(s.result,i)&&(i!=="export"||"format"in s.result&&"format"in c&&s.result.format===c.format)?f(void 0,s.result):f(new Error("报表 Worker 返回无效响应"))}};try{if(E=g.subscribe(M,a=>f(a??new Error("报表 Worker 执行失败"))),y){E();return}if(n?.addEventListener("abort",h,{once:!0}),k=setTimeout(()=>f(new l({name:"ReportRuntimeError",code:"timeout",message:`报表 Worker 执行超过 ${t}ms`})),t),n?.aborted)h();else{const{onEvent:a,signal:s,...m}=c;g.postMessage({protocol:u,id:R,operation:i,input:m})}}catch(a){f(a)}});return{prepare:(i,c,n)=>o("prepare",i,c,n),export:(i,c,n)=>o("export",i,c,n)}}function $(e,r={}){return F(()=>{const t=e();return{postMessage:o=>t.postMessage(o),terminate:()=>t.terminate(),subscribe:(o,i)=>{const c=d=>o(d.data),n=d=>i(d instanceof ErrorEvent?new Error(d.message):new Error("报表 Worker 消息无法解码"));return t.addEventListener("message",c),t.addEventListener("error",n),t.addEventListener("messageerror",n),()=>{t.removeEventListener("message",c),t.removeEventListener("error",n),t.removeEventListener("messageerror",n)}}}},r)}function D(e,r=globalThis){const t=o=>{S(o.data)&&N(e,o.data,i=>r.postMessage({protocol:u,id:o.data.id,type:"event",event:i})).then(i=>r.postMessage(i,z(i)))};return r.addEventListener("message",t),()=>r.removeEventListener("message",t)}exports.ReportWorkerError=l;exports.createBrowserReportExecutor=$;exports.serveReportWorker=D;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("./task-events-DQ276fn2.cjs"),P=require("./data-explanation-BktvER5B.cjs"),A=require("./validate-BJ5HIWY8.cjs"),u="mach-report-worker/1";class l extends Error{constructor(r){super(r.message),this.name=r.name,this.code=r.code,this.path=r.path,this.issues=r.issues,this.diagnostics=r.diagnostics}}function p(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function L(e){return p(e)?["rows","pages","cells"].every(r=>typeof e[r]=="number"&&Number.isSafeInteger(e[r])&&e[r]>=0)&&typeof e.durationMs=="number"&&Number.isFinite(e.durationMs)&&e.durationMs>=0:!1}function T(e){return Array.isArray(e)&&e.every(r=>p(r)&&typeof r.code=="string"&&typeof r.message=="string"&&["info","warning","error"].includes(r.severity)&&P.hasValidDataExplanation(r))}function j(e){return p(e)&&Object.values(e).every(r=>p(r)&&(r.revision===void 0||typeof r.revision=="string")&&(r.sourceToken===void 0||typeof r.sourceToken=="string"))}function O(e){return e===void 0?!0:p(e)&&["heuristic","provided","font-bytes"].includes(e.textMetrics)&&(e.fontFingerprint===void 0||typeof e.fontFingerprint=="string"&&/^[a-f0-9]{64}$/.test(e.fontFingerprint))}function S(e,r){if(!p(e)||!L(e.stats)||!T(e.diagnostics)||!j(e.revisions)||!O(e.layout))return!1;if(r==="prepare")return A.validateRenderPlan(e.plan).ok;const t=e.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";return e.bytes instanceof Uint8Array&&(e.format==="pdf"||e.format==="xlsx")&&e.contentType===t}function x(e){if(!e||typeof e!="object")return{message:String(e)};const r={};for(const t of["code","path","field","message"]){const o=e[t];typeof o=="string"&&(r[t]=o)}return r}function F(e){const r=x(e);if(!p(e))return r;for(const t of["format","severity","kind","nid"])typeof e[t]=="string"&&(r[t]=e[t]);for(const t of["pageIndex","componentIndex"])Number.isSafeInteger(e[t])&&e[t]>=0&&(r[t]=e[t]);return Array.isArray(e.componentPath)&&e.componentPath.every(t=>Number.isSafeInteger(t)&&t>=0)&&(r.componentPath=e.componentPath),r}function N(e){if(!(e instanceof Error))return{name:"Error",message:String(e)};const r=e;return{name:e.name,message:e.message,...typeof r.code=="string"?{code:r.code}:{},...typeof r.path=="string"?{path:r.path}:{},...Array.isArray(r.issues)?{issues:r.issues.map(x)}:{},...Array.isArray(r.diagnostics)?{diagnostics:r.diagnostics.map(F)}:{}}}function v(e){if(!e||typeof e!="object")return!1;const r=e;return r.protocol===u&&typeof r.id=="string"&&(r.operation==="prepare"||r.operation==="export"||r.operation==="exportPrepared")&&!!r.input&&typeof r.input=="object"}async function z(e,r,t){try{const o=r.operation==="prepare"?await e.prepare({...r.input,onEvent:t}):r.operation==="exportPrepared"?await e.exportPrepared({...r.input,onEvent:t}):await e.export({...r.input,onEvent:t});return{protocol:u,id:r.id,result:o}}catch(o){return{protocol:u,id:r.id,error:N(o)}}}function _(e){const r=e.result;return!r||!("bytes"in r)||!(r.bytes.buffer instanceof ArrayBuffer)?[]:[r.bytes.buffer]}function $(e,r){if(!p(e)||typeof e.taskId!="string"||!e.taskId||r.taskId!==void 0&&e.taskId!==r.taskId||e.correlationId!==r.correlationId||e.reportId!==void 0&&(typeof e.reportId!="string"||!("reportIds"in r&&r.reportIds.includes(e.reportId)))||!["query","validate","layout","assets","encode"].includes(e.stage)||!["started","completed","failed"].includes(e.status))return!1;for(const t of["completed","total"])if(e[t]!==void 0&&(typeof e[t]!="number"||!Number.isFinite(e[t])||e[t]<0))return!1;return e.completed===void 0||e.total===void 0||e.completed<=e.total}let B=0;function w(e){const r=new Error("报表 Worker 任务已取消");return r.name="AbortError",Object.defineProperty(r,"cause",{value:e}),r}function D(e,r){if(!e||typeof e!="object")return;const t=e;return t.protocol===u&&t.id===r?t:void 0}function q(e,r={}){const t=r.timeoutMs??12e4;if(!Number.isFinite(t)||t<=0||t>2147483647)throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");const o=(s,a,n,d)=>n?.aborted?Promise.reject(w(n.reason)):new Promise((I,b)=>{let g;try{g=e()}catch(c){b(c);return}const R=`mach-report-${Date.now()}-${++B}`;let y=!1,E=()=>{},k;const f=(c,i)=>{y||(y=!0,k&&clearTimeout(k),E(),n?.removeEventListener("abort",h),Promise.resolve().then(()=>g.terminate()).then(()=>c===void 0?I(i):b(c),m=>b(c??m)))},h=()=>f(w(n?.reason)),W=c=>{const i=D(c,R);if(!(!i||y)){if("type"in i&&i.type==="event"){const m="event"in i?i.event:void 0;$(m,a)?M.notifyReportTaskEvent(d,m,n):f(new Error("报表 Worker 返回无效阶段事件"));return}i.error&&typeof i.error.name=="string"&&typeof i.error.message=="string"?f(new l(i.error)):S(i.result,s)&&(s==="prepare"||"format"in i.result&&"format"in a&&i.result.format===a.format)?f(void 0,i.result):f(new Error("报表 Worker 返回无效响应"))}};try{if(E=g.subscribe(W,c=>f(c??new Error("报表 Worker 执行失败"))),y){E();return}if(n?.addEventListener("abort",h,{once:!0}),k=setTimeout(()=>f(new l({name:"ReportRuntimeError",code:"timeout",message:`报表 Worker 执行超过 ${t}ms`})),t),n?.aborted)h();else{const{onEvent:c,signal:i,...m}=a;g.postMessage({protocol:u,id:R,operation:s,input:m})}}catch(c){f(c)}});return{exportPrepared:(s,a,n)=>o("exportPrepared",s,a,n),prepare:(s,a,n)=>o("prepare",s,a,n),export:(s,a,n)=>o("export",s,a,n)}}function C(e,r={}){return q(()=>{const t=e();return{postMessage:o=>t.postMessage(o),terminate:()=>t.terminate(),subscribe:(o,s)=>{const a=d=>o(d.data),n=d=>s(d instanceof ErrorEvent?new Error(d.message):new Error("报表 Worker 消息无法解码"));return t.addEventListener("message",a),t.addEventListener("error",n),t.addEventListener("messageerror",n),()=>{t.removeEventListener("message",a),t.removeEventListener("error",n),t.removeEventListener("messageerror",n)}}}},r)}function K(e,r=globalThis){const t=o=>{v(o.data)&&z(e,o.data,s=>r.postMessage({protocol:u,id:o.data.id,type:"event",event:s})).then(s=>r.postMessage(s,_(s)))};return r.addEventListener("message",t),()=>r.removeEventListener("message",t)}exports.ReportWorkerError=l;exports.createBrowserReportExecutor=C;exports.serveReportWorker=K;
package/dist/worker.d.cts CHANGED
@@ -181,6 +181,11 @@ declare interface PreparedReport {
181
181
  revision?: string;
182
182
  sourceToken?: string;
183
183
  }>;
184
+ /** Captured metrics identity; absence on old saved instances remains supported with diagnostics. */
185
+ layout?: {
186
+ textMetrics: "heuristic" | "provided" | "font-bytes";
187
+ fontFingerprint?: string;
188
+ };
184
189
  }
185
190
 
186
191
  declare interface RenderPlan {
@@ -199,6 +204,14 @@ declare interface ReportCellSource {
199
204
  sourceToken?: string;
200
205
  }
201
206
 
207
+ declare interface ReportDataTarget {
208
+ datasetId: string;
209
+ field: string;
210
+ rowKey?: string | number;
211
+ /** Use table identity when the same dataset appears in several tables. */
212
+ tableId?: string;
213
+ }
214
+
202
215
  declare interface ReportDescription {
203
216
  id: string;
204
217
  params: ReportParamDef[];
@@ -217,6 +230,9 @@ declare interface ReportDiagnostic {
217
230
  message: string;
218
231
  path?: string;
219
232
  severity: "warning" | "error" | "info";
233
+ /** Optional explanation supplied by the business source, not inferred from blank cells. */
234
+ valueState?: ReportValueState;
235
+ target?: ReportDataTarget;
220
236
  }
221
237
 
222
238
  /** 报表参数定义(声明式,模板自描述参数面:渲染组件据此生成查询面板) */
@@ -259,15 +275,30 @@ declare interface ReportParamValidation {
259
275
  issues: ReportParamIssue[];
260
276
  }
261
277
 
278
+ /** Licensed local font bytes; never downloaded implicitly by the runtime. */
279
+ declare interface ReportPdfFontOptions {
280
+ customFontBytes?: Uint8Array | ArrayBuffer;
281
+ customFontName?: string;
282
+ customFontFaces?: {
283
+ regular: Uint8Array | ArrayBuffer;
284
+ bold?: Uint8Array | ArrayBuffer;
285
+ italic?: Uint8Array | ArrayBuffer;
286
+ boldItalic?: Uint8Array | ArrayBuffer;
287
+ };
288
+ }
289
+
262
290
  declare interface ReportRuntime {
263
291
  describe(reportIds?: string[]): ReportDescription[];
264
292
  validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
265
293
  prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
266
294
  export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
295
+ exportPrepared(input: ReportRuntimePreparedExportInput): Promise<ReportRuntimeExportResult>;
267
296
  }
268
297
 
269
298
  /** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
270
299
  declare interface ReportRuntimeExecutor {
300
+ /** Old custom executors may omit this; the runtime explicitly rejects unsupported prepared output. */
301
+ exportPrepared?(input: Omit<ReportRuntimePreparedExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
271
302
  prepare(input: Omit<ReportRuntimeInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<PreparedReport>;
272
303
  export(input: Omit<ReportRuntimeExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
273
304
  }
@@ -276,17 +307,6 @@ declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
276
307
  format: "pdf" | "xlsx";
277
308
  /** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
278
309
  fidelity?: "warn" | "strict";
279
- /** PDF 中文需宿主显式提供有授权的字体;不隐式下载字体或资源。 */
280
- pdf?: {
281
- customFontBytes?: Uint8Array | ArrayBuffer;
282
- customFontName?: string;
283
- customFontFaces?: {
284
- regular: Uint8Array | ArrayBuffer;
285
- bold?: Uint8Array | ArrayBuffer;
286
- italic?: Uint8Array | ArrayBuffer;
287
- boldItalic?: Uint8Array | ArrayBuffer;
288
- };
289
- };
290
310
  xlsx?: {
291
311
  sheetMode?: "auto" | "pages" | "continuous";
292
312
  valueMode?: "text" | "raw";
@@ -304,6 +324,18 @@ declare interface ReportRuntimeInput extends ReportTaskMonitoring {
304
324
  reportIds: string[];
305
325
  params?: Record<string, string>;
306
326
  signal?: AbortSignal;
327
+ /** Prepare using the same licensed font bytes later supplied to PDF output. */
328
+ pdf?: ReportPdfFontOptions;
329
+ }
330
+
331
+ /** Encode an existing plan without querying providers or repaginating. */
332
+ declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
333
+ prepared: PreparedReport;
334
+ format: ReportRuntimeExportInput["format"];
335
+ fidelity?: ReportRuntimeExportInput["fidelity"];
336
+ pdf?: ReportPdfFontOptions;
337
+ xlsx?: ReportRuntimeExportInput["xlsx"];
338
+ signal?: AbortSignal;
307
339
  }
308
340
 
309
341
  declare interface ReportRuntimeStats {
@@ -333,6 +365,9 @@ declare interface ReportTaskMonitoring {
333
365
 
334
366
  declare type ReportTaskObserver = (event: ReportTaskEvent) => void;
335
367
 
368
+ /** Optional business explanations never replace raw data or schema validation. */
369
+ declare type ReportValueState = "missing-source" | "not-applicable" | "not-calculable";
370
+
336
371
  export declare class ReportWorkerError extends Error {
337
372
  readonly code?: string;
338
373
  readonly path?: string;
package/dist/worker.d.ts CHANGED
@@ -181,6 +181,11 @@ declare interface PreparedReport {
181
181
  revision?: string;
182
182
  sourceToken?: string;
183
183
  }>;
184
+ /** Captured metrics identity; absence on old saved instances remains supported with diagnostics. */
185
+ layout?: {
186
+ textMetrics: "heuristic" | "provided" | "font-bytes";
187
+ fontFingerprint?: string;
188
+ };
184
189
  }
185
190
 
186
191
  declare interface RenderPlan {
@@ -199,6 +204,14 @@ declare interface ReportCellSource {
199
204
  sourceToken?: string;
200
205
  }
201
206
 
207
+ declare interface ReportDataTarget {
208
+ datasetId: string;
209
+ field: string;
210
+ rowKey?: string | number;
211
+ /** Use table identity when the same dataset appears in several tables. */
212
+ tableId?: string;
213
+ }
214
+
202
215
  declare interface ReportDescription {
203
216
  id: string;
204
217
  params: ReportParamDef[];
@@ -217,6 +230,9 @@ declare interface ReportDiagnostic {
217
230
  message: string;
218
231
  path?: string;
219
232
  severity: "warning" | "error" | "info";
233
+ /** Optional explanation supplied by the business source, not inferred from blank cells. */
234
+ valueState?: ReportValueState;
235
+ target?: ReportDataTarget;
220
236
  }
221
237
 
222
238
  /** 报表参数定义(声明式,模板自描述参数面:渲染组件据此生成查询面板) */
@@ -259,15 +275,30 @@ declare interface ReportParamValidation {
259
275
  issues: ReportParamIssue[];
260
276
  }
261
277
 
278
+ /** Licensed local font bytes; never downloaded implicitly by the runtime. */
279
+ declare interface ReportPdfFontOptions {
280
+ customFontBytes?: Uint8Array | ArrayBuffer;
281
+ customFontName?: string;
282
+ customFontFaces?: {
283
+ regular: Uint8Array | ArrayBuffer;
284
+ bold?: Uint8Array | ArrayBuffer;
285
+ italic?: Uint8Array | ArrayBuffer;
286
+ boldItalic?: Uint8Array | ArrayBuffer;
287
+ };
288
+ }
289
+
262
290
  declare interface ReportRuntime {
263
291
  describe(reportIds?: string[]): ReportDescription[];
264
292
  validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
265
293
  prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
266
294
  export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
295
+ exportPrepared(input: ReportRuntimePreparedExportInput): Promise<ReportRuntimeExportResult>;
267
296
  }
268
297
 
269
298
  /** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
270
299
  declare interface ReportRuntimeExecutor {
300
+ /** Old custom executors may omit this; the runtime explicitly rejects unsupported prepared output. */
301
+ exportPrepared?(input: Omit<ReportRuntimePreparedExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
271
302
  prepare(input: Omit<ReportRuntimeInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<PreparedReport>;
272
303
  export(input: Omit<ReportRuntimeExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
273
304
  }
@@ -276,17 +307,6 @@ declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
276
307
  format: "pdf" | "xlsx";
277
308
  /** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
278
309
  fidelity?: "warn" | "strict";
279
- /** PDF 中文需宿主显式提供有授权的字体;不隐式下载字体或资源。 */
280
- pdf?: {
281
- customFontBytes?: Uint8Array | ArrayBuffer;
282
- customFontName?: string;
283
- customFontFaces?: {
284
- regular: Uint8Array | ArrayBuffer;
285
- bold?: Uint8Array | ArrayBuffer;
286
- italic?: Uint8Array | ArrayBuffer;
287
- boldItalic?: Uint8Array | ArrayBuffer;
288
- };
289
- };
290
310
  xlsx?: {
291
311
  sheetMode?: "auto" | "pages" | "continuous";
292
312
  valueMode?: "text" | "raw";
@@ -304,6 +324,18 @@ declare interface ReportRuntimeInput extends ReportTaskMonitoring {
304
324
  reportIds: string[];
305
325
  params?: Record<string, string>;
306
326
  signal?: AbortSignal;
327
+ /** Prepare using the same licensed font bytes later supplied to PDF output. */
328
+ pdf?: ReportPdfFontOptions;
329
+ }
330
+
331
+ /** Encode an existing plan without querying providers or repaginating. */
332
+ declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
333
+ prepared: PreparedReport;
334
+ format: ReportRuntimeExportInput["format"];
335
+ fidelity?: ReportRuntimeExportInput["fidelity"];
336
+ pdf?: ReportPdfFontOptions;
337
+ xlsx?: ReportRuntimeExportInput["xlsx"];
338
+ signal?: AbortSignal;
307
339
  }
308
340
 
309
341
  declare interface ReportRuntimeStats {
@@ -333,6 +365,9 @@ declare interface ReportTaskMonitoring {
333
365
 
334
366
  declare type ReportTaskObserver = (event: ReportTaskEvent) => void;
335
367
 
368
+ /** Optional business explanations never replace raw data or schema validation. */
369
+ declare type ReportValueState = "missing-source" | "not-applicable" | "not-calculable";
370
+
336
371
  export declare class ReportWorkerError extends Error {
337
372
  readonly code?: string;
338
373
  readonly path?: string;
package/dist/worker.js CHANGED
@@ -1,5 +1,6 @@
1
- import { n as A } from "./task-events-Dpsvf_t2.js";
2
- import { c as M } from "./validate-DbgEM1Hh.js";
1
+ import { n as P } from "./task-events-Dpsvf_t2.js";
2
+ import { h as W } from "./data-explanation-C_J6jYNi.js";
3
+ import { v as A } from "./validate-CkQBWCeg.js";
3
4
  const u = "mach-report-worker/1";
4
5
  class R extends Error {
5
6
  constructor(r) {
@@ -12,19 +13,22 @@ function p(e) {
12
13
  function L(e) {
13
14
  return p(e) ? ["rows", "pages", "cells"].every((r) => typeof e[r] == "number" && Number.isSafeInteger(e[r]) && e[r] >= 0) && typeof e.durationMs == "number" && Number.isFinite(e.durationMs) && e.durationMs >= 0 : !1;
14
15
  }
15
- function P(e) {
16
- return Array.isArray(e) && e.every((r) => p(r) && typeof r.code == "string" && typeof r.message == "string" && ["info", "warning", "error"].includes(r.severity));
17
- }
18
16
  function T(e) {
17
+ return Array.isArray(e) && e.every((r) => p(r) && typeof r.code == "string" && typeof r.message == "string" && ["info", "warning", "error"].includes(r.severity) && W(r));
18
+ }
19
+ function j(e) {
19
20
  return p(e) && Object.values(e).every((r) => p(r) && (r.revision === void 0 || typeof r.revision == "string") && (r.sourceToken === void 0 || typeof r.sourceToken == "string"));
20
21
  }
21
- function j(e, r) {
22
- if (!p(e) || !L(e.stats) || !P(e.diagnostics) || !T(e.revisions)) return !1;
23
- if (r === "prepare") return M(e.plan).ok;
22
+ function O(e) {
23
+ return e === void 0 ? !0 : p(e) && ["heuristic", "provided", "font-bytes"].includes(e.textMetrics) && (e.fontFingerprint === void 0 || typeof e.fontFingerprint == "string" && /^[a-f0-9]{64}$/.test(e.fontFingerprint));
24
+ }
25
+ function F(e, r) {
26
+ if (!p(e) || !L(e.stats) || !T(e.diagnostics) || !j(e.revisions) || !O(e.layout)) return !1;
27
+ if (r === "prepare") return A(e.plan).ok;
24
28
  const t = e.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
25
29
  return e.bytes instanceof Uint8Array && (e.format === "pdf" || e.format === "xlsx") && e.contentType === t;
26
30
  }
27
- function I(e) {
31
+ function x(e) {
28
32
  if (!e || typeof e != "object") return { message: String(e) };
29
33
  const r = {};
30
34
  for (const t of ["code", "path", "field", "message"]) {
@@ -33,14 +37,14 @@ function I(e) {
33
37
  }
34
38
  return r;
35
39
  }
36
- function O(e) {
37
- const r = I(e);
40
+ function N(e) {
41
+ const r = x(e);
38
42
  if (!p(e)) return r;
39
43
  for (const t of ["format", "severity", "kind", "nid"]) typeof e[t] == "string" && (r[t] = e[t]);
40
44
  for (const t of ["pageIndex", "componentIndex"]) Number.isSafeInteger(e[t]) && e[t] >= 0 && (r[t] = e[t]);
41
45
  return Array.isArray(e.componentPath) && e.componentPath.every((t) => Number.isSafeInteger(t) && t >= 0) && (r.componentPath = e.componentPath), r;
42
46
  }
43
- function N(e) {
47
+ function S(e) {
44
48
  if (!(e instanceof Error)) return { name: "Error", message: String(e) };
45
49
  const r = e;
46
50
  return {
@@ -48,111 +52,111 @@ function N(e) {
48
52
  message: e.message,
49
53
  ...typeof r.code == "string" ? { code: r.code } : {},
50
54
  ...typeof r.path == "string" ? { path: r.path } : {},
51
- ...Array.isArray(r.issues) ? { issues: r.issues.map(I) } : {},
52
- ...Array.isArray(r.diagnostics) ? { diagnostics: r.diagnostics.map(O) } : {}
55
+ ...Array.isArray(r.issues) ? { issues: r.issues.map(x) } : {},
56
+ ...Array.isArray(r.diagnostics) ? { diagnostics: r.diagnostics.map(N) } : {}
53
57
  };
54
58
  }
55
- function v(e) {
59
+ function z(e) {
56
60
  if (!e || typeof e != "object") return !1;
57
61
  const r = e;
58
- return r.protocol === u && typeof r.id == "string" && (r.operation === "prepare" || r.operation === "export") && !!r.input && typeof r.input == "object";
62
+ return r.protocol === u && typeof r.id == "string" && (r.operation === "prepare" || r.operation === "export" || r.operation === "exportPrepared") && !!r.input && typeof r.input == "object";
59
63
  }
60
- async function S(e, r, t) {
64
+ async function _(e, r, t) {
61
65
  try {
62
- const o = r.operation === "prepare" ? await e.prepare({ ...r.input, onEvent: t }) : await e.export({ ...r.input, onEvent: t });
66
+ const o = r.operation === "prepare" ? await e.prepare({ ...r.input, onEvent: t }) : r.operation === "exportPrepared" ? await e.exportPrepared({ ...r.input, onEvent: t }) : await e.export({ ...r.input, onEvent: t });
63
67
  return { protocol: u, id: r.id, result: o };
64
68
  } catch (o) {
65
- return { protocol: u, id: r.id, error: N(o) };
69
+ return { protocol: u, id: r.id, error: S(o) };
66
70
  }
67
71
  }
68
- function z(e) {
72
+ function $(e) {
69
73
  const r = e.result;
70
74
  return !r || !("bytes" in r) || !(r.bytes.buffer instanceof ArrayBuffer) ? [] : [r.bytes.buffer];
71
75
  }
72
- function _(e, r) {
73
- if (!p(e) || typeof e.taskId != "string" || !e.taskId || r.taskId !== void 0 && e.taskId !== r.taskId || e.correlationId !== r.correlationId || e.reportId !== void 0 && (typeof e.reportId != "string" || !r.reportIds.includes(e.reportId)) || !["query", "validate", "layout", "assets", "encode"].includes(e.stage) || !["started", "completed", "failed"].includes(e.status)) return !1;
76
+ function D(e, r) {
77
+ if (!p(e) || typeof e.taskId != "string" || !e.taskId || r.taskId !== void 0 && e.taskId !== r.taskId || e.correlationId !== r.correlationId || e.reportId !== void 0 && (typeof e.reportId != "string" || !("reportIds" in r && r.reportIds.includes(e.reportId))) || !["query", "validate", "layout", "assets", "encode"].includes(e.stage) || !["started", "completed", "failed"].includes(e.status)) return !1;
74
78
  for (const t of ["completed", "total"]) if (e[t] !== void 0 && (typeof e[t] != "number" || !Number.isFinite(e[t]) || e[t] < 0)) return !1;
75
79
  return e.completed === void 0 || e.total === void 0 || e.completed <= e.total;
76
80
  }
77
- let F = 0;
81
+ let v = 0;
78
82
  function w(e) {
79
83
  const r = new Error("报表 Worker 任务已取消");
80
84
  return r.name = "AbortError", Object.defineProperty(r, "cause", { value: e }), r;
81
85
  }
82
- function $(e, r) {
86
+ function B(e, r) {
83
87
  if (!e || typeof e != "object") return;
84
88
  const t = e;
85
89
  return t.protocol === u && t.id === r ? t : void 0;
86
90
  }
87
- function B(e, r = {}) {
91
+ function C(e, r = {}) {
88
92
  const t = r.timeoutMs ?? 12e4;
89
93
  if (!Number.isFinite(t) || t <= 0 || t > 2147483647) throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");
90
- const o = (i, c, n, d) => n?.aborted ? Promise.reject(w(n.reason)) : new Promise((W, b) => {
94
+ const o = (s, a, n, d) => n?.aborted ? Promise.reject(w(n.reason)) : new Promise((I, b) => {
91
95
  let g;
92
96
  try {
93
97
  g = e();
94
- } catch (a) {
95
- b(a);
98
+ } catch (c) {
99
+ b(c);
96
100
  return;
97
101
  }
98
- const l = `mach-report-${Date.now()}-${++F}`;
102
+ const l = `mach-report-${Date.now()}-${++v}`;
99
103
  let y = !1, E = () => {
100
104
  }, h;
101
- const f = (a, s) => {
105
+ const f = (c, i) => {
102
106
  y || (y = !0, h && clearTimeout(h), E(), n?.removeEventListener("abort", k), Promise.resolve().then(() => g.terminate()).then(
103
- () => a === void 0 ? W(s) : b(a),
104
- (m) => b(a ?? m)
107
+ () => c === void 0 ? I(i) : b(c),
108
+ (m) => b(c ?? m)
105
109
  ));
106
- }, k = () => f(w(n?.reason)), x = (a) => {
107
- const s = $(a, l);
108
- if (!(!s || y)) {
109
- if ("type" in s && s.type === "event") {
110
- const m = "event" in s ? s.event : void 0;
111
- _(m, c) ? A(d, m, n) : f(new Error("报表 Worker 返回无效阶段事件"));
110
+ }, k = () => f(w(n?.reason)), M = (c) => {
111
+ const i = B(c, l);
112
+ if (!(!i || y)) {
113
+ if ("type" in i && i.type === "event") {
114
+ const m = "event" in i ? i.event : void 0;
115
+ D(m, a) ? P(d, m, n) : f(new Error("报表 Worker 返回无效阶段事件"));
112
116
  return;
113
117
  }
114
- s.error && typeof s.error.name == "string" && typeof s.error.message == "string" ? f(new R(s.error)) : j(s.result, i) && (i !== "export" || "format" in s.result && "format" in c && s.result.format === c.format) ? f(void 0, s.result) : f(new Error("报表 Worker 返回无效响应"));
118
+ i.error && typeof i.error.name == "string" && typeof i.error.message == "string" ? f(new R(i.error)) : F(i.result, s) && (s === "prepare" || "format" in i.result && "format" in a && i.result.format === a.format) ? f(void 0, i.result) : f(new Error("报表 Worker 返回无效响应"));
115
119
  }
116
120
  };
117
121
  try {
118
- if (E = g.subscribe(x, (a) => f(a ?? new Error("报表 Worker 执行失败"))), y) {
122
+ if (E = g.subscribe(M, (c) => f(c ?? new Error("报表 Worker 执行失败"))), y) {
119
123
  E();
120
124
  return;
121
125
  }
122
126
  if (n?.addEventListener("abort", k, { once: !0 }), h = setTimeout(() => f(new R({ name: "ReportRuntimeError", code: "timeout", message: `报表 Worker 执行超过 ${t}ms` })), t), n?.aborted) k();
123
127
  else {
124
- const { onEvent: a, signal: s, ...m } = c;
125
- g.postMessage({ protocol: u, id: l, operation: i, input: m });
128
+ const { onEvent: c, signal: i, ...m } = a;
129
+ g.postMessage({ protocol: u, id: l, operation: s, input: m });
126
130
  }
127
- } catch (a) {
128
- f(a);
131
+ } catch (c) {
132
+ f(c);
129
133
  }
130
134
  });
131
- return { prepare: (i, c, n) => o("prepare", i, c, n), export: (i, c, n) => o("export", i, c, n) };
135
+ return { exportPrepared: (s, a, n) => o("exportPrepared", s, a, n), prepare: (s, a, n) => o("prepare", s, a, n), export: (s, a, n) => o("export", s, a, n) };
132
136
  }
133
- function C(e, r = {}) {
134
- return B(() => {
137
+ function G(e, r = {}) {
138
+ return C(() => {
135
139
  const t = e();
136
140
  return {
137
141
  postMessage: (o) => t.postMessage(o),
138
142
  terminate: () => t.terminate(),
139
- subscribe: (o, i) => {
140
- const c = (d) => o(d.data), n = (d) => i(d instanceof ErrorEvent ? new Error(d.message) : new Error("报表 Worker 消息无法解码"));
141
- return t.addEventListener("message", c), t.addEventListener("error", n), t.addEventListener("messageerror", n), () => {
142
- t.removeEventListener("message", c), t.removeEventListener("error", n), t.removeEventListener("messageerror", n);
143
+ subscribe: (o, s) => {
144
+ const a = (d) => o(d.data), n = (d) => s(d instanceof ErrorEvent ? new Error(d.message) : new Error("报表 Worker 消息无法解码"));
145
+ return t.addEventListener("message", a), t.addEventListener("error", n), t.addEventListener("messageerror", n), () => {
146
+ t.removeEventListener("message", a), t.removeEventListener("error", n), t.removeEventListener("messageerror", n);
143
147
  };
144
148
  }
145
149
  };
146
150
  }, r);
147
151
  }
148
- function K(e, r = globalThis) {
152
+ function H(e, r = globalThis) {
149
153
  const t = (o) => {
150
- v(o.data) && S(e, o.data, (i) => r.postMessage({ protocol: u, id: o.data.id, type: "event", event: i })).then((i) => r.postMessage(i, z(i)));
154
+ z(o.data) && _(e, o.data, (s) => r.postMessage({ protocol: u, id: o.data.id, type: "event", event: s })).then((s) => r.postMessage(s, $(s)));
151
155
  };
152
156
  return r.addEventListener("message", t), () => r.removeEventListener("message", t);
153
157
  }
154
158
  export {
155
159
  R as ReportWorkerError,
156
- C as createBrowserReportExecutor,
157
- K as serveReportWorker
160
+ G as createBrowserReportExecutor,
161
+ H as serveReportWorker
158
162
  };
package/dist/xlsx.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { a as x, o as z } from "./progress-7OSZbFok.js";
2
- import { e as P, E as B, m as C } from "./workbook-session-BPb3TMnT.js";
3
- import { i as ke, a as We, o as Ae } from "./workbook-session-BPb3TMnT.js";
2
+ import { e as P, E as B, m as C } from "./workbook-session-BfK1yHOO.js";
3
+ import { i as ke, a as We, o as Ae } from "./workbook-session-BfK1yHOO.js";
4
4
  import { i as $ } from "./render-plan-Ck6koX9L.js";
5
5
  import { r as k } from "./grid-geometry-BNptEcMm.js";
6
6
  import { e as W, r as N } from "./style-CQ1PK8ZB.js";
7
7
  import { r as G } from "./capabilities-CK_7hizc.js";
8
- import { b as Fe, c as Re, a as Te, d as ze, e as Pe, f as Be, g as Ne, h as Ge, p as Le, i as Oe, v as je, j as De, k as _e, l as He, m as Ke, n as Xe } from "./region-binding-workflow-CcUq8W2Q.js";
8
+ import { b as Fe, c as Re, a as Te, d as ze, e as Pe, f as Be, g as Ne, h as Ge, p as Le, i as Oe, v as je, j as De, k as _e, l as He, m as Ke, n as Xe } from "./region-binding-workflow-DEJbhpCv.js";
9
9
  function y(e, t) {
10
10
  const r = e ?? t;
11
11
  if (!Number.isSafeInteger(r) || r <= 0) throw new Error("Excel 图片字节预算应为正安全整数");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/mach-report",
3
- "version": "2.12.0",
3
+ "version": "2.14.0",
4
4
  "description": "独立的 TypeScript 报表引擎:模板分页、DOM/Canvas/PDF/Excel 输出与 Vue 3 预览组件",
5
5
  "type": "module",
6
6
  "sideEffects": [