@kanunilabs/pivotgrid-core 1.1.0 → 1.2.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.cts CHANGED
@@ -1046,10 +1046,37 @@ interface PivotControllerOptions<TRow = any> extends PivotControllerCallbacks<TR
1046
1046
  * step instead of applying immediately. Defaults to false (apply directly).
1047
1047
  */
1048
1048
  previewImport?: boolean;
1049
+ /**
1050
+ * Where the grid's layout is persisted between sessions.
1051
+ *
1052
+ * Omitted, it is localStorage keyed by `gridId` — the historical behaviour,
1053
+ * kept so an upgrade does not lose anyone's saved layout.
1054
+ */
1055
+ stateStoring?: PivotStateStoringConfig;
1056
+ /**
1057
+ * Turns on the Enterprise edition for this controller.
1058
+ *
1059
+ * `BasePivotGrid` sets it from the `advancedExport` prop, which is what
1060
+ * `EnterprisePivotGrid` passes — so a normal React app never touches this.
1061
+ * It exists because `usePivotController`, `PivotGridBody` and `PivotFooter`
1062
+ * are all public: building your own shell is supported, and without a
1063
+ * documented way in, that path would go from "exports a file" to "throws"
1064
+ * with nothing to set.
1065
+ */
1066
+ enterpriseEdition?: boolean;
1049
1067
  }
1050
1068
  /** Imperative API handle exposed via React ref or Angular adapter. */
1051
1069
  interface PivotGridRef {
1052
- exportData: (format: ExportFormat | string, options?: ExportOptions) => void;
1070
+ /**
1071
+ * Returns a promise so a caller can handle a refusal.
1072
+ *
1073
+ * It used to be `void`. That was harmless while an unavailable format was a
1074
+ * `console.warn` and a resolved promise; the controller now REJECTS for the
1075
+ * three Enterprise formats, and a `void` return meant the caller could not
1076
+ * catch it even if they wanted to. Widening `void` to `Promise<void>` is
1077
+ * source-compatible — existing callers ignore the return either way.
1078
+ */
1079
+ exportData: (format: ExportFormat | string, options?: ExportOptions) => Promise<void>;
1053
1080
  expandAll: () => void;
1054
1081
  collapseAll: () => void;
1055
1082
  getState: () => PivotControllerState;
@@ -1062,13 +1089,37 @@ interface PivotGridRef {
1062
1089
  declare const defaultPivotLayout: PivotLayoutState;
1063
1090
 
1064
1091
  type PivotStateListener = () => void;
1065
- /** Immutable-snapshot state store with debounced localStorage persistence. */
1092
+ /**
1093
+ * Where the store reads and writes.
1094
+ *
1095
+ * It used to be `localStorage`, unconditionally. `PivotStateStoringConfig`
1096
+ * declared `enabled`, `type`, `onSave` and `onLoad`, and NONE of them were
1097
+ * read — only `storageKey`, and only as a `gridId` fallback. So
1098
+ * `enabled: false` did not disable anything, `type: 'sessionStorage'` still
1099
+ * wrote to localStorage, and the `type: 'custom'` + `onSave`/`onLoad` pair
1100
+ * documented on the features page as "persist to your own backend" was a hook
1101
+ * that nothing ever called.
1102
+ */
1103
+ /** What actually goes in and out of storage. */
1104
+ interface PersistedPivotState {
1105
+ fields?: unknown[];
1106
+ layout?: Partial<PivotLayoutState>;
1107
+ columnWidths?: Record<string, number>;
1108
+ expandedPaths?: string[];
1109
+ expandedColPaths?: string[];
1110
+ }
1111
+ interface PivotStatePersistence {
1112
+ load(): PersistedPivotState | null;
1113
+ save(state: PersistedPivotState): void;
1114
+ }
1115
+ /** Immutable-snapshot state store with debounced persistence. */
1066
1116
  declare class PivotStateStore<TRow> {
1067
1117
  private snapshot;
1068
1118
  private listeners;
1069
1119
  private storageKey;
1070
1120
  private persistScheduled;
1071
- constructor(gridId: string, initialFields: PivotField<TRow>[]);
1121
+ private persistence;
1122
+ constructor(gridId: string, initialFields: PivotField<TRow>[], persistence?: PivotStatePersistence);
1072
1123
  getSnapshot: () => PivotControllerState<TRow>;
1073
1124
  subscribe: (listener: PivotStateListener) => (() => void);
1074
1125
  setState(updates: Partial<PivotControllerState<TRow>>): void;
@@ -1207,6 +1258,43 @@ declare class PivotController<TRow> {
1207
1258
  deleteReport(id: string): void;
1208
1259
  setDefaultReport(id: string): void;
1209
1260
  refreshEngine(): void;
1261
+ /**
1262
+ * Which edition is driving this controller. Set by the React adapter from the
1263
+ * flag `EnterprisePivotGrid` passes; Community never turns it on.
1264
+ *
1265
+ * The engine keeps the capability either way — the pipeline is one piece and
1266
+ * an edition boundary that tried to cut through it would be a fork, not a
1267
+ * gate. What the flag decides is what the controller AGREES to do.
1268
+ *
1269
+ * This mirrors `DataGridController.setEnterpriseEdition` deliberately: the two
1270
+ * products should not have two different answers to the same question.
1271
+ */
1272
+ setEnterpriseEdition(on: boolean): void;
1273
+ isEnterpriseEdition(): boolean;
1274
+ private enterpriseEdition;
1275
+ /** Seeded from the options so a headless caller has a documented way in. */
1276
+ private applyEditionOption;
1277
+ /**
1278
+ * Refuse an Enterprise-only call in a clear voice.
1279
+ *
1280
+ * Throws rather than resolving empty: an export that silently returns nothing
1281
+ * looks like a bug in the caller's data, and they would go looking there
1282
+ * first. That is not hypothetical here — until this existed, a Community
1283
+ * grid asking for `excel-pivot` got a `console.warn` and a resolved promise,
1284
+ * AFTER `onExporting` had already fired, so an app showing a spinner on that
1285
+ * event span forever.
1286
+ */
1287
+ private requireEnterprise;
1288
+ /**
1289
+ * The formats that need the Enterprise package.
1290
+ *
1291
+ * The exporter itself is registered globally by a side-effect import, so
1292
+ * before this gate existed, one Enterprise import anywhere in a bundle
1293
+ * enabled styled export for EVERY grid in it — including a Community
1294
+ * `BasePivotGrid`. The registry is a module-level `let` and cannot tell who
1295
+ * is asking; the controller can.
1296
+ */
1297
+ private static readonly ENTERPRISE_FORMATS;
1210
1298
  exportData(format: ExportFormat | string, options?: ExportOptions): Promise<void>;
1211
1299
  getRawData(): TRow[];
1212
1300
  getEngineResult(): PivotEngineResult | null;
package/dist/index.d.ts CHANGED
@@ -1046,10 +1046,37 @@ interface PivotControllerOptions<TRow = any> extends PivotControllerCallbacks<TR
1046
1046
  * step instead of applying immediately. Defaults to false (apply directly).
1047
1047
  */
1048
1048
  previewImport?: boolean;
1049
+ /**
1050
+ * Where the grid's layout is persisted between sessions.
1051
+ *
1052
+ * Omitted, it is localStorage keyed by `gridId` — the historical behaviour,
1053
+ * kept so an upgrade does not lose anyone's saved layout.
1054
+ */
1055
+ stateStoring?: PivotStateStoringConfig;
1056
+ /**
1057
+ * Turns on the Enterprise edition for this controller.
1058
+ *
1059
+ * `BasePivotGrid` sets it from the `advancedExport` prop, which is what
1060
+ * `EnterprisePivotGrid` passes — so a normal React app never touches this.
1061
+ * It exists because `usePivotController`, `PivotGridBody` and `PivotFooter`
1062
+ * are all public: building your own shell is supported, and without a
1063
+ * documented way in, that path would go from "exports a file" to "throws"
1064
+ * with nothing to set.
1065
+ */
1066
+ enterpriseEdition?: boolean;
1049
1067
  }
1050
1068
  /** Imperative API handle exposed via React ref or Angular adapter. */
1051
1069
  interface PivotGridRef {
1052
- exportData: (format: ExportFormat | string, options?: ExportOptions) => void;
1070
+ /**
1071
+ * Returns a promise so a caller can handle a refusal.
1072
+ *
1073
+ * It used to be `void`. That was harmless while an unavailable format was a
1074
+ * `console.warn` and a resolved promise; the controller now REJECTS for the
1075
+ * three Enterprise formats, and a `void` return meant the caller could not
1076
+ * catch it even if they wanted to. Widening `void` to `Promise<void>` is
1077
+ * source-compatible — existing callers ignore the return either way.
1078
+ */
1079
+ exportData: (format: ExportFormat | string, options?: ExportOptions) => Promise<void>;
1053
1080
  expandAll: () => void;
1054
1081
  collapseAll: () => void;
1055
1082
  getState: () => PivotControllerState;
@@ -1062,13 +1089,37 @@ interface PivotGridRef {
1062
1089
  declare const defaultPivotLayout: PivotLayoutState;
1063
1090
 
1064
1091
  type PivotStateListener = () => void;
1065
- /** Immutable-snapshot state store with debounced localStorage persistence. */
1092
+ /**
1093
+ * Where the store reads and writes.
1094
+ *
1095
+ * It used to be `localStorage`, unconditionally. `PivotStateStoringConfig`
1096
+ * declared `enabled`, `type`, `onSave` and `onLoad`, and NONE of them were
1097
+ * read — only `storageKey`, and only as a `gridId` fallback. So
1098
+ * `enabled: false` did not disable anything, `type: 'sessionStorage'` still
1099
+ * wrote to localStorage, and the `type: 'custom'` + `onSave`/`onLoad` pair
1100
+ * documented on the features page as "persist to your own backend" was a hook
1101
+ * that nothing ever called.
1102
+ */
1103
+ /** What actually goes in and out of storage. */
1104
+ interface PersistedPivotState {
1105
+ fields?: unknown[];
1106
+ layout?: Partial<PivotLayoutState>;
1107
+ columnWidths?: Record<string, number>;
1108
+ expandedPaths?: string[];
1109
+ expandedColPaths?: string[];
1110
+ }
1111
+ interface PivotStatePersistence {
1112
+ load(): PersistedPivotState | null;
1113
+ save(state: PersistedPivotState): void;
1114
+ }
1115
+ /** Immutable-snapshot state store with debounced persistence. */
1066
1116
  declare class PivotStateStore<TRow> {
1067
1117
  private snapshot;
1068
1118
  private listeners;
1069
1119
  private storageKey;
1070
1120
  private persistScheduled;
1071
- constructor(gridId: string, initialFields: PivotField<TRow>[]);
1121
+ private persistence;
1122
+ constructor(gridId: string, initialFields: PivotField<TRow>[], persistence?: PivotStatePersistence);
1072
1123
  getSnapshot: () => PivotControllerState<TRow>;
1073
1124
  subscribe: (listener: PivotStateListener) => (() => void);
1074
1125
  setState(updates: Partial<PivotControllerState<TRow>>): void;
@@ -1207,6 +1258,43 @@ declare class PivotController<TRow> {
1207
1258
  deleteReport(id: string): void;
1208
1259
  setDefaultReport(id: string): void;
1209
1260
  refreshEngine(): void;
1261
+ /**
1262
+ * Which edition is driving this controller. Set by the React adapter from the
1263
+ * flag `EnterprisePivotGrid` passes; Community never turns it on.
1264
+ *
1265
+ * The engine keeps the capability either way — the pipeline is one piece and
1266
+ * an edition boundary that tried to cut through it would be a fork, not a
1267
+ * gate. What the flag decides is what the controller AGREES to do.
1268
+ *
1269
+ * This mirrors `DataGridController.setEnterpriseEdition` deliberately: the two
1270
+ * products should not have two different answers to the same question.
1271
+ */
1272
+ setEnterpriseEdition(on: boolean): void;
1273
+ isEnterpriseEdition(): boolean;
1274
+ private enterpriseEdition;
1275
+ /** Seeded from the options so a headless caller has a documented way in. */
1276
+ private applyEditionOption;
1277
+ /**
1278
+ * Refuse an Enterprise-only call in a clear voice.
1279
+ *
1280
+ * Throws rather than resolving empty: an export that silently returns nothing
1281
+ * looks like a bug in the caller's data, and they would go looking there
1282
+ * first. That is not hypothetical here — until this existed, a Community
1283
+ * grid asking for `excel-pivot` got a `console.warn` and a resolved promise,
1284
+ * AFTER `onExporting` had already fired, so an app showing a spinner on that
1285
+ * event span forever.
1286
+ */
1287
+ private requireEnterprise;
1288
+ /**
1289
+ * The formats that need the Enterprise package.
1290
+ *
1291
+ * The exporter itself is registered globally by a side-effect import, so
1292
+ * before this gate existed, one Enterprise import anywhere in a bundle
1293
+ * enabled styled export for EVERY grid in it — including a Community
1294
+ * `BasePivotGrid`. The registry is a module-level `let` and cannot tell who
1295
+ * is asking; the controller can.
1296
+ */
1297
+ private static readonly ENTERPRISE_FORMATS;
1210
1298
  exportData(format: ExportFormat | string, options?: ExportOptions): Promise<void>;
1211
1299
  getRawData(): TRow[];
1212
1300
  getEngineResult(): PivotEngineResult | null;