@freereportjs/core 0.8.0 → 0.9.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/dist/index.d.ts CHANGED
@@ -795,6 +795,21 @@ interface ViewerOptions extends ReportOptions {
795
795
  /** Show the parameter panel open at start (default: when the report has parameters without defaults). */
796
796
  paramsOpen?: boolean;
797
797
  fileName?: string;
798
+ /** After every successful run (start, 조회/Run, setData, setParams, setDefinition): page and row counts. */
799
+ onReady?: (e: ViewerReadyEvent) => void;
800
+ /** When the user submits the parameter panel, before the data is fetched. Return false to stay (e.g. failed validation), or return changed params. */
801
+ onParamsSubmit?: (params: Record<string, unknown>) => boolean | void | Record<string, unknown> | Promise<boolean | void | Record<string, unknown>>;
802
+ /** The page in view changed (1-based). */
803
+ onPageChange?: (page: number, total: number) => void;
804
+ /** Loading data, laying out, printing or saving failed. The viewer still shows its own message. */
805
+ onError?: (error: Error, during: 'data' | 'layout' | 'output') => void;
806
+ }
807
+ interface ViewerReadyEvent {
808
+ pages: number;
809
+ rows: number;
810
+ /** Layout time in milliseconds. */
811
+ ms: number;
812
+ params: Record<string, unknown>;
798
813
  }
799
814
  interface Viewer {
800
815
  readonly report: Report;
@@ -1130,7 +1145,7 @@ declare function verifyLicense(key: string, host: string, opts?: {
1130
1145
  declare function setLicenseKey(key: string): void;
1131
1146
 
1132
1147
  /** FreeReport version (kept in sync with releases.json by scripts/release.mjs). */
1133
- declare const version = "0.8.0";
1148
+ declare const version = "0.9.0";
1134
1149
 
1135
1150
  type Lang = 'ko' | 'en';
1136
1151
 
@@ -1192,4 +1207,4 @@ declare function renderXlsx(def: ReportDefinition, data?: ReportData, opts?: Ser
1192
1207
  mode?: 'form' | 'data';
1193
1208
  }): Promise<Uint8Array>;
1194
1209
 
1195
- export { AgentError, type AgentLogEntry, type AgentPrintOptions, type AgentPrintResult, type AgentPrinter, type AgentStatus, type Align, type Band, type BandKind, type BarcodeElement, type BorderInput, type BorderSide, type BoxItem, type ChartElement, type ChartSeries, type CrosstabElement, type Designer, type DesignerOptions, type ElementType, type Emboss, type Expr, FUNCTIONS, type FieldElement, type FontBytes, type FontEntry, type GroupDefinition, type ImageElement, type ImageItem, type ItemSource, type LayoutOptions, type LayoutResult, type LicenseInfo, type LineElement, type LineItem, type OutputEvent, type OutputKind, PAPER, type PageItem, type PageSetup, type PaperSize, type ParamDefinition, type PathCommand, type PathItem, type PdfFontSource, type PdfOptions, type PdfPermissions, type PdfSecurity, type PrintOptions, type RectElement, type Report, type ReportData, type ReportDefinition, type ReportElement, type ReportOptions, type ReportPage, type ResolvedBorder, type ResolvedFont, type ServerRenderOptions, type Style, type TableColumn, type TableElement, type TextElement, type TextItem, type TextLine, type TextMeasurer, type VAlign, type Viewer, type ViewerOptions, type Watermark, type XCell, type XCellStyle, type XSheet, agent, applyEmboss, blankReport, canonicalText, canvasMeasurer, checkExpression, compile, contentWidth, createDesigner, createReport, createViewer, dataToCsv, dataToXlsx, defaultMeasurer, embossImage, encodeCode128, encodeDataMatrix, encodeEan13, encodePdf417, encodeQr, ensureFonts, estimateMeasurer, evaluate, fingerprintPages, formatDate, formatNumber, formatValue, getFont, interpolate, koreanAmount, koreanNumber, layoutReport, loadFontBytes, loadFonts, pageGeometry, pageToSvg, pagesToHwpx, pagesToXlsx, paramValues, printPages, registerFont, renderPage, renderPdf, renderXlsx, resetMeasurer, rowsOf, saveFile, setLicenseKey, sha256Hex, ttfMeasurer, verifyLicense, version, wrapText, writePdf, writeXlsx };
1210
+ export { AgentError, type AgentLogEntry, type AgentPrintOptions, type AgentPrintResult, type AgentPrinter, type AgentStatus, type Align, type Band, type BandKind, type BarcodeElement, type BorderInput, type BorderSide, type BoxItem, type ChartElement, type ChartSeries, type CrosstabElement, type Designer, type DesignerOptions, type ElementType, type Emboss, type Expr, FUNCTIONS, type FieldElement, type FontBytes, type FontEntry, type GroupDefinition, type ImageElement, type ImageItem, type ItemSource, type LayoutOptions, type LayoutResult, type LicenseInfo, type LineElement, type LineItem, type OutputEvent, type OutputKind, PAPER, type PageItem, type PageSetup, type PaperSize, type ParamDefinition, type PathCommand, type PathItem, type PdfFontSource, type PdfOptions, type PdfPermissions, type PdfSecurity, type PrintOptions, type RectElement, type Report, type ReportData, type ReportDefinition, type ReportElement, type ReportOptions, type ReportPage, type ResolvedBorder, type ResolvedFont, type ServerRenderOptions, type Style, type TableColumn, type TableElement, type TextElement, type TextItem, type TextLine, type TextMeasurer, type VAlign, type Viewer, type ViewerOptions, type ViewerReadyEvent, type Watermark, type XCell, type XCellStyle, type XSheet, agent, applyEmboss, blankReport, canonicalText, canvasMeasurer, checkExpression, compile, contentWidth, createDesigner, createReport, createViewer, dataToCsv, dataToXlsx, defaultMeasurer, embossImage, encodeCode128, encodeDataMatrix, encodeEan13, encodePdf417, encodeQr, ensureFonts, estimateMeasurer, evaluate, fingerprintPages, formatDate, formatNumber, formatValue, getFont, interpolate, koreanAmount, koreanNumber, layoutReport, loadFontBytes, loadFonts, pageGeometry, pageToSvg, pagesToHwpx, pagesToXlsx, paramValues, printPages, registerFont, renderPage, renderPdf, renderXlsx, resetMeasurer, rowsOf, saveFile, setLicenseKey, sha256Hex, ttfMeasurer, verifyLicense, version, wrapText, writePdf, writeXlsx };
package/dist/index.js CHANGED
@@ -187,8 +187,8 @@ function pdfFonts(pages) {
187
187
  }
188
188
 
189
189
  // src/version.ts
190
- var version = "0.8.0";
191
- var releaseDate = "2026-10-15";
190
+ var version = "0.9.0";
191
+ var releaseDate = "2026-10-16";
192
192
 
193
193
  // src/license.ts
194
194
  var PUBLIC_KEY = { kty: "EC", crv: "P-256", x: "MiJXJR8TZJ_-0VKk0wIQ-5mzRsyQ6ruGsbcRRdw9jrw", y: "MTdklYSzCM2pganffz7PPMfxSclQkBLqU_9se_VDznM" };
@@ -5859,6 +5859,27 @@ function createViewer(el, options) {
5859
5859
  const pageH = result.height * MM_PX * scale + PAGE_GAP;
5860
5860
  current = Math.min(result.pages.length - 1, Math.max(0, Math.round(body.scrollTop / pageH)));
5861
5861
  if (pageInput && document.activeElement !== pageInput) pageInput.value = String(current + 1);
5862
+ notifyPage();
5863
+ };
5864
+ let reported = -1;
5865
+ const notifyPage = () => {
5866
+ if (!result?.pages.length || current === reported) return;
5867
+ reported = current;
5868
+ try {
5869
+ options.onPageChange?.(current + 1, result.pages.length);
5870
+ } catch (e) {
5871
+ console.error(e);
5872
+ }
5873
+ };
5874
+ const fail = (e, during) => {
5875
+ const err = e instanceof Error ? e : new Error(String(e));
5876
+ console.error(err);
5877
+ try {
5878
+ options.onError?.(err, during);
5879
+ } catch (x) {
5880
+ console.error(x);
5881
+ }
5882
+ return err;
5862
5883
  };
5863
5884
  const goTo = (n2) => {
5864
5885
  if (!result) return;
@@ -5867,6 +5888,7 @@ function createViewer(el, options) {
5867
5888
  if (holder) body.scrollTop = holder.offsetTop - pagesEl.offsetTop;
5868
5889
  current = i;
5869
5890
  if (pageInput) pageInput.value = String(i + 1);
5891
+ notifyPage();
5870
5892
  };
5871
5893
  const setZoom = (z) => {
5872
5894
  const ratio = result ? body.scrollTop / Math.max(1, body.scrollHeight) : 0;
@@ -5878,20 +5900,28 @@ function createViewer(el, options) {
5878
5900
  const run = async () => {
5879
5901
  const seq2 = ++runSeq;
5880
5902
  busy(t.loading);
5903
+ let during = "data";
5881
5904
  try {
5882
5905
  if (options.fetchData) {
5883
5906
  const fetched = await options.fetchData(params);
5884
5907
  if (seq2 !== runSeq) return;
5885
5908
  report.setData(fetched);
5886
5909
  }
5910
+ during = "layout";
5887
5911
  report.setParams(params);
5888
5912
  await ensureFonts(report.definition);
5889
5913
  if (destroyed) return;
5890
5914
  result = report.layout();
5915
+ reported = -1;
5891
5916
  build();
5917
+ try {
5918
+ options.onReady?.({ pages: result.pages.length, rows: result.rowCount, ms: result.ms, params: { ...params } });
5919
+ } catch (e) {
5920
+ console.error(e);
5921
+ }
5892
5922
  } catch (e) {
5893
- console.error(e);
5894
- pagesEl.innerHTML = `<p class="fr-empty">${t.error}: ${escapeHtml(String(e.message ?? e))}</p>`;
5923
+ const err = fail(e, during);
5924
+ pagesEl.innerHTML = `<p class="fr-empty">${t.error}: ${escapeHtml(err.message)}</p>`;
5895
5925
  } finally {
5896
5926
  busy(null);
5897
5927
  }
@@ -5901,8 +5931,7 @@ function createViewer(el, options) {
5901
5931
  try {
5902
5932
  await report.download(kind, options.fileName);
5903
5933
  } catch (e) {
5904
- console.error(e);
5905
- alertText(`${t.error}: ${e.message}`);
5934
+ alertText(`${t.error}: ${fail(e, "output").message}`);
5906
5935
  } finally {
5907
5936
  busy(null);
5908
5937
  }
@@ -5944,7 +5973,7 @@ function createViewer(el, options) {
5944
5973
  setZoom(Math.round((scale - 0.1) * 10) / 10);
5945
5974
  break;
5946
5975
  case "print":
5947
- void report.print().catch((err) => alertText(`${t.error}: ${err.message}`));
5976
+ void report.print().catch((err) => alertText(`${t.error}: ${fail(err, "output").message}`));
5948
5977
  break;
5949
5978
  case "pdf":
5950
5979
  void exportAs("pdf");
@@ -6019,7 +6048,7 @@ function createViewer(el, options) {
6019
6048
  e.preventDefault();
6020
6049
  setZoom(Math.round(scale * (e.deltaY < 0 ? 1.1 : 1 / 1.1) * 100) / 100);
6021
6050
  }, { passive: false });
6022
- form?.addEventListener("submit", (e) => {
6051
+ form?.addEventListener("submit", async (e) => {
6023
6052
  e.preventDefault();
6024
6053
  const next = { ...params };
6025
6054
  form.querySelectorAll("input, select").forEach((inp) => {
@@ -6027,7 +6056,15 @@ function createViewer(el, options) {
6027
6056
  const v = inp.value;
6028
6057
  next[inp.name] = type === "number" ? v === "" ? null : Number(v) : type === "boolean" ? v === "true" : v;
6029
6058
  });
6030
- params = next;
6059
+ let answer;
6060
+ try {
6061
+ answer = await options.onParamsSubmit?.({ ...next });
6062
+ } catch (x) {
6063
+ fail(x, "data");
6064
+ return;
6065
+ }
6066
+ if (answer === false) return;
6067
+ params = answer && typeof answer === "object" ? { ...next, ...answer } : next;
6031
6068
  void run();
6032
6069
  });
6033
6070
  const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freereportjs/core",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "FreeReport — a web reporting engine (free for personal use): banded report designer, paged viewer, printing, PDF with embedded Korean fonts, Excel export.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",