react-semaphor 0.1.545 → 0.1.547

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 (159) hide show
  1. package/dist/analytics-protocol/index.js +408 -442
  2. package/dist/assistant-context/index.js +1 -1
  3. package/dist/assistant-protocol/index.js +100 -76
  4. package/dist/brand-studio/index.js +4 -4
  5. package/dist/briefings/index.js +6 -6
  6. package/dist/chunks/{add-to-dashboard-BuAqfA2Y.js → add-to-dashboard-BQRAAnc3.js} +55 -33
  7. package/dist/chunks/{analytics-base-schemas-BFAoRlkU.js → analytics-base-schemas-BKs3flFS.js} +2 -2
  8. package/dist/chunks/applied-constraints-DU-wndZ7.js +47 -0
  9. package/dist/chunks/{assistant-chat-D7sWTypJ.js → assistant-chat-CK84cPAB.js} +2826 -2595
  10. package/dist/chunks/{bookmark-state-CXw7lZ50.js → bookmark-state-Cu-a5ie_.js} +8 -15
  11. package/dist/chunks/comparison-window-caption-C2xF-eWw.js +1433 -0
  12. package/dist/chunks/{context-ClREvqCZ.js → context-BerEBuFR.js} +11 -6
  13. package/dist/chunks/custom-visual-inputs-ChL54gGm.js +295 -0
  14. package/dist/chunks/{dashboard-B1tMju0u.js → dashboard-DCk26-6i.js} +1 -1
  15. package/dist/chunks/{dashboard-briefing-launcher-CePgIu0Z.js → dashboard-briefing-launcher-CQ1eYsGy.js} +1291 -1277
  16. package/dist/chunks/dashboard-controls-BMeZjF7r.js +2307 -0
  17. package/dist/chunks/{dashboard-json-CoYRPqxx.js → dashboard-json-BZqCoanC.js} +5 -5
  18. package/dist/chunks/{document-dashboard-inputs-BesAHZvB.js → document-dashboard-inputs-tYd7ao0o.js} +877 -979
  19. package/dist/chunks/{edit-dashboard-visual-JPtNfJRb.js → edit-dashboard-visual-Bv3MHM_G.js} +2157 -2243
  20. package/dist/chunks/filter-reach-copy-CGWsL_ez.js +3480 -0
  21. package/dist/chunks/{filter-value-text-ff7osJr7.js → filter-value-text-Ddf55Ku1.js} +9 -9
  22. package/dist/chunks/global-date-filter-utils-BhAu8zIM.js +12137 -0
  23. package/dist/chunks/index-CtoK1Lgu.js +586 -0
  24. package/dist/chunks/{index-DRWiuqyd.js → index-DmrLP5Ro.js} +105 -104
  25. package/dist/chunks/list-filter-DsaTbM3J.js +15 -0
  26. package/dist/chunks/matrix-analytical-definition-B9vW-osb.js +717 -0
  27. package/dist/chunks/{matrix-card-DjwWcCo8.js → matrix-card-LiMEipvq.js} +3 -3
  28. package/dist/chunks/{matrix-formatter-DnCyRXJE.js → matrix-formatter-DWEeC0_c.js} +44 -44
  29. package/dist/chunks/{matrix-member-presentation-CQGdVks6.js → matrix-member-presentation-DqzG-UhQ.js} +1 -1
  30. package/dist/chunks/{matrix-operation-contract-8OIO4gob.js → matrix-operation-contract-D6vYkZK4.js} +72 -72
  31. package/dist/chunks/{metric-comparison-DEwi9uc2.js → metric-comparison-zpGw4lD6.js} +2 -2
  32. package/dist/chunks/normalize-dashboard-for-dirty-check-XKgH3GFX.js +119 -0
  33. package/dist/chunks/{pivot-header-presentation-DHcx1XGQ.js → pivot-header-presentation-CQnIDtUv.js} +1 -1
  34. package/dist/chunks/{pivot-result-identity-DJhXXcns.js → pivot-result-identity-C-Q1j1Wb.js} +1 -1
  35. package/dist/chunks/{pivot-result-lifecycle-DM4CyGKs.js → pivot-result-lifecycle-pwq3b7LC.js} +571 -380
  36. package/dist/chunks/{raw-temporal-contract-C51YG48G.js → raw-temporal-contract-WuXA8jBP.js} +1 -1
  37. package/dist/chunks/{raw-temporal-presentation-C3mUgnEx.js → raw-temporal-presentation-DypB7sMX.js} +8 -8
  38. package/dist/chunks/{report-preferences-dialog-DUtuUL_5.js → report-preferences-dialog-DoVyriYC.js} +154 -155
  39. package/dist/chunks/{report-runtime-context-Dq8XyODK.js → report-runtime-context-hWiTCzFV.js} +2 -2
  40. package/dist/chunks/resolve-dashboard-input-context-D0JDUa4h.js +5576 -0
  41. package/dist/chunks/{saved-dashboard-context-LrF_kW0l.js → saved-dashboard-context-BfAH5j4L.js} +34 -34
  42. package/dist/chunks/{selection-reducer-Dj_8xD69.js → selection-reducer-CJzkTZio.js} +15 -15
  43. package/dist/chunks/{semaphor-ready-indicator-BxF96Yhv.js → semaphor-ready-indicator-CRm17oIP.js} +51771 -52574
  44. package/dist/chunks/{shelf-drop-preview-context-CNaM_Gmh.js → shelf-drop-preview-context-vy6P9THz.js} +7 -7
  45. package/dist/chunks/{source-entity-resolution-BYn9giz3.js → source-entity-resolution-BIGRvtbG.js} +13 -13
  46. package/dist/chunks/{switch-uDtPgQlQ.js → switch-CEBOR4n7.js} +3 -3
  47. package/dist/chunks/{table-export-sheet-YzMioA7Y.js → table-export-sheet-4X9mAG3V.js} +1 -1
  48. package/dist/chunks/table-settings-WysCBj62.js +614 -0
  49. package/dist/chunks/{temporal-bucket-D7NBrrtL.js → temporal-bucket-CQOSbv9-.js} +26 -26
  50. package/dist/chunks/{token-types-DBbZVQsm.js → token-types-BMqRmT-C.js} +1 -1
  51. package/dist/chunks/{use-create-flow-overlay-state-CjB7ig1o.js → use-create-flow-overlay-state-Csx_Xjsh.js} +101 -101
  52. package/dist/chunks/{validators-DMHTpf7a.js → validators-C-aOQlTB.js} +713 -658
  53. package/dist/chunks/{relative-date-label-Bk2j94pA.js → zoned-wall-clock-MulfA26h.js} +64 -21
  54. package/dist/dashboard/index.js +2 -2
  55. package/dist/dashboard-authoring/index.js +1895 -1163
  56. package/dist/data-app-sdk/index.js +6 -6
  57. package/dist/data-app-sdk-adapters/index.js +3 -3
  58. package/dist/data-app-sdk-validation/index.js +14 -14
  59. package/dist/format-utils/index.js +133 -133
  60. package/dist/index.js +192 -186
  61. package/dist/layouts/index.js +5 -242
  62. package/dist/report-runtime-context/index.js +2 -2
  63. package/dist/shared/index.js +4 -5
  64. package/dist/style.css +1 -1
  65. package/dist/surfboard/index.js +2 -2
  66. package/dist/types/components/index.d.ts +2 -0
  67. package/dist/types/components/surfboard/arrange-layout-button.d.ts +8 -0
  68. package/dist/types/components/surfboard/filter/types.d.ts +7 -0
  69. package/dist/types/components/surfboard/screen-size-preview-button.d.ts +10 -0
  70. package/dist/types/components/visual/matrix-table/matrix-card-view.d.ts +3 -0
  71. package/dist/types/index.js +6 -6
  72. package/dist/types/lib/charts/table-chart-types.d.ts +4 -0
  73. package/dist/types/lib/charts/types.d.ts +2 -2
  74. package/dist/types/lib/dashboard-inputs/dashboard-filter-mapping-authoring.d.ts +346 -21
  75. package/dist/types/lib/dashboard-inputs/dashboard-filter-value-identity.d.ts +65 -0
  76. package/dist/types/lib/dashboard-inputs/dashboard-input-values.d.ts +6 -0
  77. package/dist/types/lib/dashboard-inputs/filter-settings.d.ts +2 -0
  78. package/dist/types/lib/dashboard-inputs/prepare-loaded-dashboard.d.ts +15 -0
  79. package/dist/types/lib/dashboard-inputs/resolve-selection-input.d.ts +3 -3
  80. package/dist/types/lib/hooks/use-dashboard-card.d.ts +2 -0
  81. package/dist/types/lib/matrix-table/matrix-delivery-policy.d.ts +1 -1
  82. package/dist/types/lib/matrix-table/matrix-editor.d.ts +52 -0
  83. package/dist/types/lib/matrix-table/matrix-runtime-types.d.ts +9 -1
  84. package/dist/types/lib/matrix-table/matrix-runtime.d.ts +5 -1
  85. package/dist/types/lib/query-context/dashboard-filter-mapping-resolution.d.ts +149 -10
  86. package/dist/types/lib/stores/dashboard-store.d.ts +137 -6
  87. package/dist/types/lib/types/common-types.d.ts +8 -0
  88. package/dist/types/lib/types/explorer-types.d.ts +10 -0
  89. package/dist/types/lib/types/semantic-types.d.ts +84 -0
  90. package/dist/types/lib/utils/build-saved-editor-card.d.ts +20 -0
  91. package/dist/types/lib/utils/card-type-change.d.ts +16 -0
  92. package/dist/types/lib/utils/field-availability-context.d.ts +25 -0
  93. package/dist/types/lib/utils/field-placement.d.ts +96 -0
  94. package/dist/types/lib/utils/field-state-calculator.d.ts +161 -0
  95. package/dist/types/lib/utils/qualified-entity-name.d.ts +2 -0
  96. package/dist/types/shared/analytics-protocol/applied-constraints.d.ts +57 -1
  97. package/dist/types/shared/analytics-protocol/field-provenance.d.ts +89 -0
  98. package/dist/types/shared/analytics-protocol/index.d.ts +2 -0
  99. package/dist/types/shared/analytics-protocol/query-policies.d.ts +52 -0
  100. package/dist/types/shared/analytics-protocol/time-window-schema.d.ts +1 -1
  101. package/dist/types/shared/analytics-protocol/time-window.d.ts +40 -1
  102. package/dist/types/shared/assistant-context/saved-dashboard-context.d.ts +4 -1
  103. package/dist/types/shared/assistant-protocol/answer-text.d.ts +20 -0
  104. package/dist/types/shared/assistant-protocol/context.d.ts +29 -29
  105. package/dist/types/shared/assistant-protocol/index.d.ts +1 -0
  106. package/dist/types/shared/assistant-protocol/limits.d.ts +6 -1
  107. package/dist/types/shared/assistant-protocol/parts.d.ts +43 -3
  108. package/dist/types/shared/assistant-protocol/request.d.ts +14 -2
  109. package/dist/types/shared/dashboard-authoring/calculated-field-identity.d.ts +3 -0
  110. package/dist/types/shared/dashboard-authoring/changes/card-query-part.d.ts +487 -0
  111. package/dist/types/shared/dashboard-authoring/changes/card-types.d.ts +34 -0
  112. package/dist/types/shared/dashboard-authoring/changes/dashboard-change.d.ts +7886 -0
  113. package/dist/types/shared/dashboard-authoring/changes/diagnostics.d.ts +45 -0
  114. package/dist/types/shared/dashboard-authoring/changes/read-card-query.d.ts +54 -0
  115. package/dist/types/shared/dashboard-authoring/changes/resolve-dashboard-changes.d.ts +96 -0
  116. package/dist/types/shared/dashboard-authoring/click-to-filter-settings.d.ts +3 -3
  117. package/dist/types/shared/dashboard-authoring/column-catalog.d.ts +32 -0
  118. package/dist/types/shared/dashboard-authoring/contracts.d.ts +0 -55
  119. package/dist/types/shared/dashboard-authoring/control-execution-contract.d.ts +24 -14
  120. package/dist/types/shared/dashboard-authoring/dashboard-card-source-index.d.ts +9 -1
  121. package/dist/types/shared/dashboard-authoring/dashboard-filter-automatic-target.d.ts +4 -4
  122. package/dist/types/shared/dashboard-authoring/dashboard-filter-mapping-contract.d.ts +3 -1
  123. package/dist/types/shared/dashboard-authoring/dashboard-filter-mapping-types.d.ts +27 -1
  124. package/dist/types/shared/dashboard-authoring/dashboard-filter-value-compatibility.d.ts +12 -3
  125. package/dist/types/shared/dashboard-authoring/dashboard-input-scope.d.ts +26 -0
  126. package/dist/types/shared/dashboard-authoring/filter-applicability.d.ts +75 -0
  127. package/dist/types/shared/dashboard-authoring/filter-reach-copy.d.ts +18 -0
  128. package/dist/types/shared/dashboard-authoring/filter-reach-preview.d.ts +97 -0
  129. package/dist/types/shared/dashboard-authoring/index.d.ts +22 -2
  130. package/dist/types/shared/dashboard-authoring/operations/apply-dashboard-operations.d.ts +10 -37
  131. package/dist/types/shared/dashboard-authoring/operations/operation-types.d.ts +189 -0
  132. package/dist/types/shared/dashboard-authoring/outline/outline-dashboard.d.ts +101 -0
  133. package/dist/types/shared/dashboard-authoring/outline/outline-filters.d.ts +100 -0
  134. package/dist/types/shared/dashboard-authoring/semantic-auto-join-card.d.ts +22 -0
  135. package/dist/types/shared/dashboard-authoring/validators.d.ts +1 -2
  136. package/dist/types/shared/layouts/engine/grid.d.ts +25 -0
  137. package/dist/types/shared/layouts/engine/index.d.ts +4 -0
  138. package/dist/types/shared/layouts/engine/sheet-layout.d.ts +7 -0
  139. package/dist/types/shared/layouts/engine/types.d.ts +125 -0
  140. package/dist/types/shared/layouts/index.d.ts +1 -2
  141. package/package.json +2 -2
  142. package/dist/chunks/apply-dashboard-operations-CZEMsx8E.js +0 -2080
  143. package/dist/chunks/calendar-day-equality-dvoQp1xW.js +0 -410
  144. package/dist/chunks/comparison-window-caption-D4E6IHPD.js +0 -1624
  145. package/dist/chunks/custom-visual-inputs-DLCD9Y5V.js +0 -329
  146. package/dist/chunks/dashboard-controls-Cq05n3e0.js +0 -2315
  147. package/dist/chunks/dashboard-filter-value-compatibility-CwQ_iSNb.js +0 -108
  148. package/dist/chunks/matrix-analytical-definition-C7Gb0e12.js +0 -117
  149. package/dist/chunks/normalize-dashboard-for-dirty-check-Bk3VYv_q.js +0 -67
  150. package/dist/chunks/numeric-presentation-7X_IrD58.js +0 -5226
  151. package/dist/chunks/resolve-dashboard-input-context-DJ2tICwz.js +0 -9415
  152. package/dist/chunks/stable-serialize-CfqXeiBP.js +0 -6
  153. package/dist/chunks/table-settings-CLZocegs.js +0 -501
  154. package/dist/chunks/use-debounced-dirty-check-BwAbnX_5.js +0 -59
  155. package/dist/chunks/zoned-wall-clock-BkxV9jS2.js +0 -46
  156. package/dist/types/shared/dashboard-authoring/change-compiler.d.ts +0 -7
  157. package/dist/types/shared/dashboard-authoring/layout-compiler.d.ts +0 -2
  158. package/dist/types/shared/layouts/create-frame-layouts.d.ts +0 -27
  159. package/dist/types/shared/layouts/frame-layouts.d.ts +0 -23
@@ -1,5 +1,5 @@
1
1
  import { SelectionField, SelectionInputValue } from '../../shared/analytics-protocol/selection-contract.js';
2
- import { DashboardFilterTarget } from '../../shared/dashboard-authoring/index.js';
2
+ import { DashboardFilterFieldTarget } from '../../shared/dashboard-authoring/index.js';
3
3
  import { ScopedDashboardInputTarget } from '../../shared/dashboard-authoring/dashboard-input-scope.js';
4
4
  import { NormalizedFilterDashboardInput, SelectionDashboardInput, TCard } from '../types/common-types.js';
5
5
  import { FilterCondition } from '../types/explorer-types.js';
@@ -19,7 +19,7 @@ export type SelectionBlockReason = 'ambiguousAutomaticTarget' | 'staleBinding' |
19
19
  export type SelectionConditionDisposition = {
20
20
  status: 'apply';
21
21
  clickedFieldKey: string;
22
- target: DashboardFilterTarget;
22
+ target: DashboardFilterFieldTarget;
23
23
  provenance: 'automatic' | 'bound' | 'borrowedFromFilter';
24
24
  /** Set when provenance is 'borrowedFromFilter'. */
25
25
  borrowedFromInputId?: string;
@@ -57,7 +57,7 @@ export declare function findBorrowedSelectionBinding(params: {
57
57
  filterInputs: NormalizedFilterDashboardInput[];
58
58
  }): {
59
59
  inputId: string;
60
- target: DashboardFilterTarget;
60
+ target: DashboardFilterFieldTarget;
61
61
  } | undefined;
62
62
  /**
63
63
  * Decides what one source card's selection does on one target card. A viewer's
@@ -21,6 +21,7 @@ export declare function useCard(cardId: string): {
21
21
  resolvedPrimaryDateField: import('../types/semantic-runtime-types.js').ResolvedPrimaryDateField | undefined;
22
22
  effectiveCardConfig: import('../types/index.js').CardConfig | undefined;
23
23
  isCurrentQueryResult: boolean;
24
+ filterReach: import('../../shared/analytics-protocol/index.js').SemaphorFilterReachEntry[];
24
25
  };
25
26
  export declare function useDashboardCard(card: TCard): {
26
27
  isPending: boolean;
@@ -42,4 +43,5 @@ export declare function useDashboardCard(card: TCard): {
42
43
  resolvedPrimaryDateField: import('../types/semantic-runtime-types.js').ResolvedPrimaryDateField | undefined;
43
44
  effectiveCardConfig: import('../types/index.js').CardConfig | undefined;
44
45
  isCurrentQueryResult: boolean;
46
+ filterReach: import('../../shared/analytics-protocol/index.js').SemaphorFilterReachEntry[];
45
47
  };
@@ -31,4 +31,4 @@ export declare function matrixDeliveryOptions(allowDownload?: boolean, content?:
31
31
  formats: ("csv" | "xlsx" | "pdf" | "png")[];
32
32
  };
33
33
  /** Matrix delivery requires an effective capture, never resident cells. */
34
- export declare function resolveMatrixExportEngine(card: TCard | null | undefined, hasContext: boolean): "window" | "unavailable" | "ordinary";
34
+ export declare function resolveMatrixExportEngine(card: TCard | null | undefined, hasContext: boolean): "unavailable" | "window" | "ordinary";
@@ -0,0 +1,52 @@
1
+ import { ContainerId, Field } from '../types/explorer-types.js';
2
+ import { TCard } from '../types/common-types.js';
3
+ import { FieldPlacement, FieldPlacementContext, FieldPlacementOutcome } from '../utils/field-placement.js';
4
+ import { MatrixViewState, MatrixConfig, MatrixSpec } from '../../shared/analytics-protocol/index.js';
5
+ import { MatrixAuthoringChange, MatrixAuthoringNotice } from '../../shared/dashboard-authoring/matrix-authoring.js';
6
+ import { MatrixCardCatalog } from './matrix-card-adapter.js';
7
+ /** Source-panel fields already carry catalog identity; do not infer it from names or SQL. */
8
+ export declare function matrixEditorCatalogFromFields(card: Pick<TCard, 'dataSource'> & {
9
+ config?: {
10
+ matrix?: {
11
+ spec: Pick<MatrixSpec, 'source'>;
12
+ };
13
+ };
14
+ }, fields: readonly Field[]): MatrixCardCatalog;
15
+ export type MatrixEditorChange = {
16
+ card: TCard;
17
+ notices: readonly MatrixAuthoringNotice[];
18
+ };
19
+ export declare function changeMatrixEditor(card: TCard, config: MatrixConfig, change: MatrixAuthoringChange, catalog: MatrixCardCatalog): MatrixEditorChange;
20
+ /**
21
+ * Copy the live session into the authored config: expansion on both axes
22
+ * becomes defaultView and effective sorts become the authored sorts. This is
23
+ * the one explicit path from exploration to persisted state.
24
+ */
25
+ export declare function persistMatrixEditorView(card: TCard, config: MatrixConfig, view: MatrixViewState, catalog: MatrixCardCatalog): MatrixEditorChange;
26
+ /** All editor surfaces replace the canonical config and its bindings atomically. */
27
+ export declare function applyMatrixEditorResult(card: TCard, result: {
28
+ config: MatrixConfig;
29
+ bindings: readonly NonNullable<TCard['controlBindings']>[number][];
30
+ notices: readonly MatrixAuthoringNotice[];
31
+ }): MatrixEditorChange;
32
+ /**
33
+ * Field placement for Matrix cards: the field-list entity gate, then the one
34
+ * spec transaction. Side-effect-free; the new instance id is context input.
35
+ * Called through `evaluateFieldPlacement` by both the drop and its preview.
36
+ */
37
+ export declare function evaluateMatrixPlacement(card: TCard, placement: FieldPlacement, context: FieldPlacementContext): FieldPlacementOutcome;
38
+ /**
39
+ * One atomic mutation for source drops, cross-shelf moves and reordering.
40
+ * A field-list drop creates an instance and needs `newInstanceId`; the
41
+ * committing adapter mints it, so this function reads no random source.
42
+ */
43
+ export declare function dropMatrixEditorField(card: TCard, catalog: MatrixCardCatalog, input: {
44
+ field: Field;
45
+ from: ContainerId;
46
+ to: ContainerId;
47
+ beforeId?: string;
48
+ newInstanceId?: string;
49
+ }): MatrixEditorChange;
50
+ export declare function removeMatrixEditorField(card: TCard, zone: ContainerId, id: string, catalog: MatrixCardCatalog): MatrixEditorChange;
51
+ /** Scope storage stays with calculated-field transitions; this owns selected Matrix copies. */
52
+ export declare function reconcileMatrixCalculatedField(card: TCard, fields: readonly Field[], previous: Field | undefined, updated?: Field): MatrixEditorChange;
@@ -1,4 +1,4 @@
1
- import { MatrixAxis, MatrixAxisPage, MatrixCellBlock, MatrixCoordinate, MatrixFailure, MatrixPageRequest, MatrixPath, MatrixPresentation, MatrixSpec, MatrixViewState, MatrixWindow, MatrixIndexedWindowOutcome, MatrixWindowRequest, OperationTemporalState, SemaphorScalarValue } from '../../shared/analytics-protocol/index.js';
1
+ import { MatrixAxis, MatrixAxisPage, MatrixCellBlock, MatrixCoordinate, MatrixFailure, MatrixPageRequest, MatrixPath, MatrixPresentation, MatrixSpec, MatrixViewState, MatrixWindow, MatrixIndexedWindowOutcome, MatrixWindowRequest, OperationTemporalState, SemaphorScalarValue, SemaphorFilterReachEntry } from '../../shared/analytics-protocol/index.js';
2
2
  export type MatrixRuntimeError = {
3
3
  failure: MatrixFailure;
4
4
  retryKey: string | null;
@@ -124,6 +124,12 @@ export type MatrixDataset = {
124
124
  * or seeded dataset continues on the same instant.
125
125
  */
126
126
  temporalState?: OperationTemporalState;
127
+ /**
128
+ * The per-filter report its latest window returned (relationship filter
129
+ * reach RF-D13): a restored dataset shows rows without running a window, so
130
+ * its filter info reads the report saved with them (ledger R-03).
131
+ */
132
+ filterReach?: readonly SemaphorFilterReachEntry[];
127
133
  };
128
134
  /** What a mounted runtime exposes to History. */
129
135
  export type MatrixLiveView = {
@@ -208,6 +214,8 @@ export type MatrixWindowExecutor = (input: {
208
214
  /** A window outcome and the operation state the server ran it on. */
209
215
  export type MatrixWindowExecution = MatrixIndexedWindowOutcome & {
210
216
  temporalState?: OperationTemporalState;
217
+ /** The per-filter report for this window, as `/api/v1/query` returns it for other cards. */
218
+ filterReach?: SemaphorFilterReachEntry[];
211
219
  };
212
220
  export type MatrixRuntimeInput = {
213
221
  spec: MatrixSpec;
@@ -1,5 +1,5 @@
1
+ import { SemaphorFilterReachEntry, MatrixAxis, MatrixCoordinate, MatrixPath, MatrixSort, MatrixViewState } from '../../shared/analytics-protocol/index.js';
1
2
  import { QueryClient } from '@tanstack/react-query';
2
- import { MatrixAxis, MatrixCoordinate, MatrixPath, MatrixSort, MatrixViewState } from '../../shared/analytics-protocol/index.js';
3
3
  import { MatrixCellAddress, MatrixCellState, MatrixDatasetRetention, MatrixRuntimeInput, MatrixRuntimeSnapshot, MatrixViewport, MatrixVisibleCoverage, MatrixWindowExecutor } from './matrix-runtime-types.js';
4
4
  /** Owns acquisition, errors, generation fencing and retention for exactly one card. */
5
5
  export declare class MatrixRuntimeController {
@@ -26,6 +26,8 @@ export declare class MatrixRuntimeController {
26
26
  * every page and expansion sends it, so they all run on one instant.
27
27
  */
28
28
  private temporalState?;
29
+ /** The latest window's per-filter report (relationship filter reach RF-D13). */
30
+ private filterReach;
29
31
  private error?;
30
32
  private notice?;
31
33
  private blockingFailures;
@@ -73,6 +75,8 @@ export declare class MatrixRuntimeController {
73
75
  * Value, null and empty cells are complete; unloaded and loading cells, axis
74
76
  * pages still loading, and queued or active work are not.
75
77
  */
78
+ /** Which filters the latest window's source applied, and why not, as the server reported it. */
79
+ readFilterReach: () => SemaphorFilterReachEntry[];
76
80
  readVisibleCoverage: () => MatrixVisibleCoverage;
77
81
  /** Used by explicit refresh/retry integrations; latest-issued response wins. */
78
82
  refetchCell: (coordinate: MatrixCoordinate) => void;
@@ -1,6 +1,7 @@
1
1
  import { TFilterValue } from '../../components/surfboard/filter/types.js';
2
2
  import { NormalizedFilterDashboardInput, ResolvedDashboardInput, TCard } from '../types/common-types.js';
3
- import { DashboardFilterLogicalValueField, DashboardFilterTarget, DashboardFilterTargetField, DashboardFilterTargetSource, buildDashboardCardSourceIndex } from '../../shared/dashboard-authoring/index.js';
3
+ import { DashboardFilterLogicalValueField, DashboardFilterFieldTarget, DashboardFilterTargetField, DashboardFilterTargetSource, buildDashboardCardSourceIndex } from '../../shared/dashboard-authoring/index.js';
4
+ import { SemaphorRelationshipRoute, SemaphorSkippedConstraintReason } from '../../shared/analytics-protocol/index.js';
4
5
  import { Field } from '../types/explorer-types.js';
5
6
  export type DashboardFilterMappingSkipReason = 'outsideScope' | 'noSelection' | 'explicitlyExcluded' | 'notApplicable';
6
7
  export type DashboardFilterMappingBlockReason = 'ambiguousAutomaticTarget' | 'staleBinding' | 'invalidSelection' | 'incompatibleValueType' | 'unsupportedTarget';
@@ -35,7 +36,7 @@ export type DashboardFilterMappingResolution = {
35
36
  * use, so the server resolves both to the same table alias. Pass the card's
36
37
  * grounded executable source when validation returned one.
37
38
  */
38
- export declare function explorerFieldFromMappingTarget(target: DashboardFilterTarget, source?: DashboardFilterTargetField['source']): Field;
39
+ export declare function explorerFieldFromMappingTarget(target: DashboardFilterFieldTarget, source?: DashboardFilterTargetField['source']): Field;
39
40
  /** Date and datetime are interchangeable; every other type must match exactly. */
40
41
  export declare function dashboardFilterDataTypesAreCompatible(sourceType: string, targetType: DashboardFilterTargetField['dataType']): boolean;
41
42
  /**
@@ -47,13 +48,7 @@ export declare function automaticTargetCandidates(params: {
47
48
  valueField: DashboardFilterLogicalValueField;
48
49
  valueSources: DashboardFilterTargetSource[];
49
50
  sourceIndex: ReturnType<typeof buildDashboardCardSourceIndex>;
50
- }): DashboardFilterTarget[];
51
- /**
52
- * The source-qualified fields whose values a toolbar filter holds. A filter
53
- * with an option source has exactly one; an ordinary filter has one per
54
- * source it is proven to address.
55
- */
56
- export declare function dashboardFilterInputValueFields(input: NormalizedFilterDashboardInput): DashboardFilterTargetField[];
51
+ }): DashboardFilterFieldTarget[];
57
52
  export type DashboardFilterTargetValidation = {
58
53
  status: 'valid';
59
54
  /** The card's own copy of the source the target addresses. */
@@ -71,8 +66,152 @@ export type DashboardFilterTargetValidation = {
71
66
  */
72
67
  export declare function validateDashboardFilterTargetForCard(params: {
73
68
  sourceIndex: ReturnType<typeof buildDashboardCardSourceIndex>;
74
- target: DashboardFilterTarget;
69
+ target: DashboardFilterFieldTarget;
75
70
  }): DashboardFilterTargetValidation;
71
+ /**
72
+ * Where a filter input lands on a card: the one decision execution
73
+ * (`resolveDashboardFilterMappings`) and every description of reach (the
74
+ * dashboard outline, the change resolver's reach warnings and filter-effect
75
+ * check) make, in one order: the card's mapping entry (excluded, or a bound
76
+ * target the card must still address), then SQL Auto, then the automatic and
77
+ * inherited targets. A selected value only supplies the automatic target's
78
+ * data type when the input states none.
79
+ */
80
+ export type DashboardFilterCardTarget = {
81
+ status: 'excluded';
82
+ } | {
83
+ status: 'bound';
84
+ bindingId: string;
85
+ target: DashboardFilterFieldTarget;
86
+ validation: Extract<DashboardFilterTargetValidation, {
87
+ status: 'valid';
88
+ }>;
89
+ }
90
+ /**
91
+ * A bound target the card can't run, no longer addresses, or whose type the
92
+ * filter's values can't take: the card blocks until it is mapped again.
93
+ */
94
+ | {
95
+ status: 'unsupportedTarget' | 'stale' | 'incompatible';
96
+ bindingId: string;
97
+ } | {
98
+ status: 'sql';
99
+ } | {
100
+ status: 'automatic';
101
+ target: DashboardFilterFieldTarget;
102
+ }
103
+ /**
104
+ * The card's data takes the filter's field (the one applicability rule) but
105
+ * not through a source its query uses, such as a dataset it selects or
106
+ * joins: the value applies as it is, as it does for a filter with no card
107
+ * mappings.
108
+ */
109
+ | {
110
+ status: 'passthrough';
111
+ }
112
+ /**
113
+ * The value's dataset is one the card's query doesn't use, in the card's
114
+ * semantic domain: the value is sent as it is and the server decides,
115
+ * through the domain's relationships, whether and how it reaches the card
116
+ * (relationship filter reach row 7r). The browser loads no relationships.
117
+ * With `route`, the author chose the relationships (a mapping `relationship`
118
+ * target, RF-D10): the value carries their ids and the server resolves
119
+ * exactly them or blocks the card.
120
+ */
121
+ | {
122
+ status: 'relationship';
123
+ route?: {
124
+ bindingId: string;
125
+ relationshipIds: string[];
126
+ };
127
+ } | {
128
+ status: 'ambiguous';
129
+ } | {
130
+ status: 'notApplicable';
131
+ };
132
+ /** The filter's mapping marks the card "Don't apply" (the first step of `decideDashboardFilterCardTarget`). */
133
+ export declare function isDashboardFilterCardExcluded(input: NormalizedFilterDashboardInput, cardId: string): boolean;
134
+ export declare function decideDashboardFilterCardTarget(input: NormalizedFilterDashboardInput, card: TCard, sourceIndex?: ReturnType<typeof buildDashboardCardSourceIndex>, selectedValue?: TFilterValue): DashboardFilterCardTarget;
135
+ /** How a filter applies to a card, whatever value it holds. */
136
+ export type DashboardFilterCardReach =
137
+ /** The mapping marks the card "Don't apply". */
138
+ 'excluded'
139
+ /** The mapping binds the filter to a field of the card. */
140
+ | 'bound'
141
+ /** The card executes the filter's own field (or a proven binding's), so it applies with no mapping. */
142
+ | 'automatic'
143
+ /** A SQL card takes the filter's value as is. */
144
+ | 'sql'
145
+ /** More than one field of the card could take it: the card blocks until it is mapped. */
146
+ | 'ambiguous'
147
+ /** The mapping binds a target the card can't run or no longer has: the card blocks until it is mapped again. */
148
+ | 'blocked'
149
+ /**
150
+ * The server decides when the card runs, through the domain's
151
+ * relationships: it may apply the value or skip it with a reason. A reader
152
+ * never counts it as reached.
153
+ */
154
+ | 'relationship'
155
+ /** A server-side resolver confirmed the route the card will apply (RF-D15). */
156
+ | 'relationshipApplied' | 'notApplicable';
157
+ /** How a filter reaches a card, with the route or the reason a resolver gave (RF-D15). */
158
+ export type DashboardFilterCardReachDetail = {
159
+ reach: DashboardFilterCardReach;
160
+ /** With 'relationshipApplied'. */
161
+ route?: SemaphorRelationshipRoute;
162
+ /** With 'notApplicable' from a resolver. */
163
+ reason?: SemaphorSkippedConstraintReason;
164
+ /** With reason 'relationship_ambiguous'. */
165
+ candidates?: SemaphorRelationshipRoute[];
166
+ /** With 'blocked' from a resolver. */
167
+ message?: string;
168
+ /**
169
+ * With 'automatic' from a resolver: a card the target decision sends to the
170
+ * server to place applies the value on data its query already uses, so no
171
+ * route is needed (ledger R-05).
172
+ */
173
+ kept?: true;
174
+ };
175
+ /**
176
+ * Supplied by semaphor-app to server-side readers (RF-D15). Synchronous: the
177
+ * app preloads each card's domain. In the browser readers have none and
178
+ * report `relationship` unresolved.
179
+ */
180
+ export type DashboardRelationshipReachResolver = (query: {
181
+ card: TCard;
182
+ value: TFilterValue;
183
+ }) => {
184
+ status: 'applied';
185
+ route: SemaphorRelationshipRoute;
186
+ }
187
+ /** The card's query already uses the value's dataset: it applies as any filter. */
188
+ | {
189
+ status: 'kept';
190
+ } | {
191
+ status: 'skipped';
192
+ reason: SemaphorSkippedConstraintReason;
193
+ candidates?: SemaphorRelationshipRoute[];
194
+ } | {
195
+ status: 'blocked';
196
+ message: string;
197
+ };
198
+ /**
199
+ * Whether a filter in scope reaches a card, read without a value, from the
200
+ * decision execution makes (`decideDashboardFilterCardTarget`). The dashboard
201
+ * outline and the change resolver read it, so they report what the card runs
202
+ * (MCP dashboard editing SPEC 3.6, 5.4).
203
+ */
204
+ export declare function describeDashboardFilterCardReach(input: NormalizedFilterDashboardInput, card: TCard): DashboardFilterCardReach;
205
+ /**
206
+ * `describeDashboardFilterCardReach` with the route or reason. With a
207
+ * resolver (server-side readers, RF-D15) a `relationship` card is resolved
208
+ * the way the card query resolves it: applied with its route, not applicable
209
+ * with the reason, or blocked. The value is the filter's own field, as the
210
+ * card would send it; no policy step depends on the operator.
211
+ */
212
+ export declare function describeDashboardFilterCardReachDetail(input: NormalizedFilterDashboardInput, card: TCard, options?: {
213
+ relationshipReach?: DashboardRelationshipReachResolver;
214
+ }): DashboardFilterCardReachDetail;
76
215
  export declare function resolveDashboardFilterMappings({ card, inputs, resolvedInputs, activeFilterValues, shouldApplyDashboardFilters, }: {
77
216
  card: TCard;
78
217
  inputs: NormalizedFilterDashboardInput[];
@@ -9,7 +9,8 @@ import { TFilter, TFilterValue } from '../../components/surfboard/filter/types.j
9
9
  import { TransientInputContext } from '../dashboard-inputs/transient-input-context.js';
10
10
  import { MissingPrintInputs } from '../print/print-inputs.js';
11
11
  import { default as ReactGridLayout } from 'react-grid-layout';
12
- import { DashboardFramePlacement } from '../../shared/dashboard-authoring/operations/apply-dashboard-operations.js';
12
+ import { CustomizableBreakpoint, EditableBreakpoint, FramePlacement, GridEditBreakpoint, LayoutItem } from '../../shared/layouts/index.js';
13
+ import { DashboardOperation, OperationContext } from '../../shared/dashboard-authoring/operations/apply-dashboard-operations.js';
13
14
  import { FilterGroup, Field } from '../types/explorer-types.js';
14
15
  import { DashboardControlsModelOptions } from '../controls/control-authoring-types.js';
15
16
  import { SemanticExecutionPayload } from '../types/semantic-runtime-types.js';
@@ -26,15 +27,92 @@ import { CardViewStateMap, DrillStep } from '../dashboard-view-state/index.js';
26
27
  import { DashboardCardPaginationState } from '../dashboard-pagination/dashboard-card-pagination.js';
27
28
  export declare function mergeSemanticExecutionPayloadIntoTarget(target: SemanticExecutionPayload, incoming?: SemanticExecutionPayload): void;
28
29
  type AddFrameOptions = {
29
- /** Default `end`; beside a frame is how a duplicate lands next to its original. */
30
- placement?: DashboardFramePlacement;
30
+ /** By intent; absent: placed by kind (RL-D12). A duplicate passes `{ position: { beside: originalId } }`. */
31
+ placement?: FramePlacement;
31
32
  semanticExecutionPayload?: SemanticExecutionPayload;
32
33
  };
34
+ /**
35
+ * A proposal the assistant applied in this edit session (analytics agent
36
+ * Plan 1, spec 8.1, D7-20): the document before and after it, for Undo.
37
+ */
38
+ export type AppliedProposal = {
39
+ proposalId: string;
40
+ before: TDashboard;
41
+ beforePayload: SemanticExecutionPayload;
42
+ after: TDashboard;
43
+ };
44
+ export type ApplyProposalInput = {
45
+ proposalId: string;
46
+ operations: DashboardOperation[];
47
+ /** The context the proposal was resolved with: its pinned calendar. */
48
+ context: OperationContext;
49
+ /** The exact document the proposal was built from (D7-19). */
50
+ basedOn: TDashboard;
51
+ /** Metadata loaded for cards the loaded metadata doesn't cover. */
52
+ semanticExecutionPayload?: SemanticExecutionPayload;
53
+ };
54
+ export type ApplyProposalRefusal = {
55
+ ok: false;
56
+ reason: 'dashboard_changed' | 'not_editable' | 'refused' | 'previous_not_applied';
57
+ message: string;
58
+ };
59
+ export type ApplyProposalResult = {
60
+ ok: true;
61
+ after: TDashboard;
62
+ } | ApplyProposalRefusal;
63
+ export type UndoProposalResult = {
64
+ ok: true;
65
+ } | {
66
+ ok: false;
67
+ reason: 'changed_since' | 'not_found' | 'not_editable';
68
+ };
69
+ /** Arrange from the toolbar (responsive layouts SPEC §6.4, RL-D13). */
70
+ export type ArrangeSheetResult = {
71
+ ok: true;
72
+ } | {
73
+ ok: false;
74
+ reason: 'not_editable' | 'not_a_grid';
75
+ };
76
+ export type UndoArrangeResult = {
77
+ ok: true;
78
+ } | {
79
+ ok: false;
80
+ reason: 'changed_since' | 'not_found';
81
+ };
82
+ /** The last toolbar Arrange: `after` is the store's own document, so Undo can tell whether anything changed since (RL-INV-7). */
83
+ export type LastArrange = {
84
+ sheetId: string;
85
+ before: TDashboard;
86
+ after: TDashboard;
87
+ };
88
+ /** The words for a proposal the dashboard could not take, for the viewer. */
89
+ export declare const PROPOSAL_REFUSALS: {
90
+ readonly dashboard_changed: "Not applied: the dashboard changed while I was answering.";
91
+ readonly not_editable: "Not applied: close the editor and ask again.";
92
+ readonly no_save: "Not applied: changes to this dashboard can't be saved here.";
93
+ /** A change built on one that wasn't applied here: nothing to build on (P7-46). */
94
+ readonly previous_not_applied: "Not applied: the change before it wasn't applied.";
95
+ };
33
96
  export type DashboardStore = {
34
97
  isDownloadingPdf?: boolean;
35
98
  isSessionExpired: boolean;
36
99
  authToken?: AuthToken;
100
+ /** The breakpoint the sheet grid renders: from the container width in view mode, `layoutEditBreakpoint` while editing, `lg` in print (responsive layouts SPEC §6.3). semaphor-app's BreakpointIndicator reads it. */
37
101
  currentBreakpoint: Breakpoint;
102
+ /** The breakpoint the editor edits (RL-D11). Reset to `lg` on dashboard load and on leaving edit mode. */
103
+ layoutEditBreakpoint: EditableBreakpoint;
104
+ /**
105
+ * A screen size shown look-only, or Laptop or Small phone while editing
106
+ * (responsive layouts RL-D18, RL-D19). null: no preview. Never saved; cleared
107
+ * on load, on entering or leaving edit mode, and when an editable size is chosen.
108
+ */
109
+ layoutPreviewBreakpoint: Breakpoint | null;
110
+ /**
111
+ * Whether the screen-size bar is open (responsive layouts RL-D21). Closed by
112
+ * default: the editor edits Desktop and the bar appears only when someone
113
+ * opens it. Closed on load and on entering or leaving edit mode.
114
+ */
115
+ screenSizesOpen: boolean;
38
116
  theme?: 'light' | 'dark' | 'system';
39
117
  themeStyle?: StyleProps;
40
118
  filteringCards?: TCard[];
@@ -70,6 +148,14 @@ export type DashboardStore = {
70
148
  dashboard: TDashboard;
71
149
  semanticExecutionPayload: SemanticExecutionPayload;
72
150
  } | null;
151
+ /**
152
+ * The assistant's proposals applied in this edit session, oldest first
153
+ * (analytics agent Plan 1, spec 8.1, D7-20). Leaving edit mode, and every
154
+ * replacement of the document but a proposal's own Undo, clears them.
155
+ */
156
+ appliedProposals: AppliedProposal[];
157
+ /** The last toolbar Arrange, for its Undo. Cleared by any dashboard load, leaving edit mode, or a successful undo (responsive layouts SPEC §6.4). */
158
+ lastArrange?: LastArrange;
73
159
  isVisualEditing: boolean;
74
160
  showDashboardJSON: boolean;
75
161
  showFilters: boolean;
@@ -273,7 +359,26 @@ type Actions = {
273
359
  clearDocumentInputRuntime: (sheetId?: string) => void;
274
360
  setSelectedSheetId: (sheetId: string | null) => void;
275
361
  setSheetLayout: (sheetId: string, layout: ReactGridLayout.Layout[]) => void;
276
- setSheetLayouts: (sheetId: string, layouts: ReactGridLayout.Layouts) => void;
362
+ /** The grid's items at the edited breakpoint after a drag or resize stop, through the layout engine (`grid_edited`). */
363
+ editSheetLayout: (sheetId: string, breakpoint: GridEditBreakpoint, items: LayoutItem[]) => void;
364
+ /** Shows a screen size look-only, or ends the preview with null (RL-D19). */
365
+ setLayoutPreviewBreakpoint: (breakpoint: Breakpoint | null) => void;
366
+ /**
367
+ * Opens or closes the screen-size bar (RL-D21). Opening in view mode starts a
368
+ * look-only preview at the size shown now; closing ends any preview and
369
+ * returns the editor to Desktop.
370
+ */
371
+ setScreenSizesOpen: (open: boolean) => void;
372
+ /** The screen size the editor edits: Desktop, Tablet or Phone (RL-D11). */
373
+ setLayoutEditBreakpoint: (breakpoint: EditableBreakpoint) => void;
374
+ /** "Back to automatic" for a customized Tablet or Phone layout, through the layout engine (`reset_to_automatic`). */
375
+ resetSheetLayout: (sheetId: string, breakpoint: CustomizableBreakpoint) => void;
376
+ /** Arrange from the toolbar: the `layout.arrange` operation, with edit mode on and an undo record (RL-D13, RL-INV-7). */
377
+ arrangeSheet: (sheetId: string, options?: {
378
+ keepOrder?: boolean;
379
+ }) => ArrangeSheetResult;
380
+ /** Restores the dashboard from before the last toolbar Arrange while it is still what the Arrange left. */
381
+ undoArrange: () => UndoArrangeResult;
277
382
  setSelectedCardId: (sheetId: string, cardId: string | null) => void;
278
383
  setSelectedFrameId: (frameId: string) => void;
279
384
  clearSelectedFrameId: () => void;
@@ -281,7 +386,7 @@ type Actions = {
281
386
  setCardInfo: (cardId: string, info: string) => void;
282
387
  setCardSql: (sheetId: string, cardId: string, sql: string) => void;
283
388
  setCardPython: (cardId: string, pythonCode: string) => void;
284
- setCardDescription: (sheetId: string, cardId: string, description: string, preferences?: TCard['preferences']) => void;
389
+ setCardDescription: (sheetId: string, cardId: string, description: string) => void;
285
390
  setCardKpiOptions: (sheetId: string, cardId: string, kpiOptions: Record<string, any>) => void;
286
391
  updateCardFilters: (cardId: string, filters: FilterGroup | undefined) => void;
287
392
  clearCardFilters: (cardId: string) => void;
@@ -301,7 +406,7 @@ type Actions = {
301
406
  clearAllInlineFilterValues: () => void;
302
407
  setInlineFilterValuesMap: (map: Record<string, TFilterValue[]>) => void;
303
408
  setCardInlineFilterDefaultValues: (sheetId: string, cardId: string, filterId: string, defaultValues: (string | number)[] | undefined) => void;
304
- addFrame: (sheetId: string, frame: TFrame, positionOrOptions?: 'start' | 'end' | AddFrameOptions) => void;
409
+ addFrame: (sheetId: string, frame: TFrame, options?: AddFrameOptions) => void;
305
410
  updateFrame: (sheetId: string, frame: TFrame, options?: {
306
411
  semanticExecutionPayload?: SemanticExecutionPayload;
307
412
  }) => void;
@@ -315,6 +420,15 @@ type Actions = {
315
420
  removeFrame: (sheetId: string, frameId: string) => void;
316
421
  removeCard: (sheetId: string, card: TCard) => void;
317
422
  setIsDashboardEditing: (editing: boolean) => void;
423
+ /**
424
+ * Applies an assistant proposal to the dashboard on screen (spec 8.1,
425
+ * D7-18, D7-27): only while the dashboard is still `basedOn`, checked and
426
+ * written in one step, with edit mode on and an undo record. Callers go
427
+ * through `useApplyProposal`, which loads the metadata first.
428
+ */
429
+ applyProposal: (input: ApplyProposalInput) => ApplyProposalResult;
430
+ /** Undoes the newest applied proposal while the dashboard is still what it left (D7-20). */
431
+ undoProposal: (proposalId: string) => UndoProposalResult;
318
432
  setShowDashboardJSON: (show: boolean) => void;
319
433
  setIsVisualEditing: (editing: boolean) => void;
320
434
  setShowFilters: (show: boolean) => void;
@@ -435,6 +549,23 @@ export type ViewerRequestToken = {
435
549
  * editing turned on, else the dashboard as it is now. Both toolbars' "before
436
550
  * editing" capture reads this.
437
551
  */
552
+ /**
553
+ * Whether a toolbar that owns the edit session (the package's or the app's)
554
+ * is mounted: each registers its unsaved-changes check while mounted. Where
555
+ * none is, there is no Save, so nothing changes the dashboard (D7-32).
556
+ */
557
+ export declare function selectHasEditingToolbar(state: Pick<DashboardStore, 'checkUnsavedDashboardChanges'>): boolean;
558
+ /**
559
+ * Where an applied proposal stands for its block (spec 8.1, D7-20):
560
+ * `undoable` while it is the newest and the dashboard is still what it left,
561
+ * `older` with a newer one after it while the dashboard is still what the
562
+ * newest left, `changed_since` for every record after the person's own edit
563
+ * (their change may have undone this one, P7-36), `none` when its record is
564
+ * gone.
565
+ */
566
+ export type ProposalRecordState = 'undoable' | 'older' | 'changed_since' | 'none';
567
+ export declare function selectProposalRecordState(state: Pick<DashboardStore, 'appliedProposals' | 'dashboard'>, proposalId: string): ProposalRecordState;
568
+ export declare function selectProposalUndoable(state: Pick<DashboardStore, 'appliedProposals' | 'dashboard'>, proposalId: string): boolean;
438
569
  export declare function selectEditSessionStart(state: Pick<DashboardStore, 'editingStartedWith' | 'dashboard' | 'semanticExecutionPayload'>): {
439
570
  dashboard: TDashboard;
440
571
  semanticExecutionPayload: SemanticExecutionPayload;
@@ -315,6 +315,8 @@ export type AuthToken = {
315
315
  refreshToken?: string;
316
316
  };
317
317
  export type Breakpoint = 'lg' | 'md' | 'sm' | 'xs' | 'xxs';
318
+ /** The breakpoints a person may customize on purpose: Tablet and Phone (responsive layouts RL-D14). */
319
+ export type CustomizableBreakpoint = Extract<Breakpoint, 'sm' | 'xs'>;
318
320
  type FilterOnClick = {
319
321
  expression?: string;
320
322
  columnIndex: number;
@@ -1521,6 +1523,12 @@ export type TSheet = {
1521
1523
  description?: string;
1522
1524
  layout?: ReactGridLayout.Layout[];
1523
1525
  layouts?: ReactGridLayout.Layouts;
1526
+ /**
1527
+ * The breakpoints edited on purpose (responsive layouts RL-D3); every other
1528
+ * breakpoint but `lg` is derived from `lg` by the layout engine
1529
+ * (`src/shared/layouts`). Absent on a sheet the engine has never written.
1530
+ */
1531
+ customizedBreakpoints?: CustomizableBreakpoint[];
1524
1532
  cards?: TCard[];
1525
1533
  frames?: TFrame[];
1526
1534
  calculatedFields?: Field[];
@@ -212,6 +212,14 @@ export interface MetricField extends Field {
212
212
  * pre-aggregated metric input.
213
213
  */
214
214
  isPreAggregated?: boolean;
215
+ /**
216
+ * The governed compiler's aggregate provenance, saved with every card it
217
+ * compiles (semaphor-app `buildMetricField`): the semantic model's
218
+ * aggregate, the one applied, and where it came from.
219
+ */
220
+ semanticAggregate?: AggregateFunction;
221
+ effectiveAggregate?: AggregateFunction;
222
+ aggregateSource?: 'semantic_model' | 'caller_override' | 'default_sum';
215
223
  comparison?: MetricComparisonConfig;
216
224
  comparisonPolarity?: MetricComparisonPolarity;
217
225
  /** Governed runtime annotation. When present, authoring polarity is read-only. */
@@ -478,6 +486,8 @@ export interface FilterCondition {
478
486
  * it was saved.
479
487
  */
480
488
  latestValue?: true;
489
+ /** Set when the governed compiler added the latest-value condition by a snapshot dataset's policy (no stated window), not someone's choice: a read leaves it unstated and a recompile adds it again. */
490
+ latestValuePolicy?: 'snapshot';
481
491
  }
482
492
  export interface FilterGroup {
483
493
  id: string;