@sectile/chart 0.11.1

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/dist/contract.d.ts +194 -0
  4. package/dist/contract.js +2 -0
  5. package/dist/contract.js.map +1 -0
  6. package/dist/controller.d.ts +45 -0
  7. package/dist/controller.js +2 -0
  8. package/dist/controller.js.map +1 -0
  9. package/dist/definition.d.ts +40 -0
  10. package/dist/definition.js +2 -0
  11. package/dist/definition.js.map +1 -0
  12. package/dist/index.d.ts +12 -0
  13. package/dist/index.js +2 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/interaction.d.ts +95 -0
  16. package/dist/interaction.js +2 -0
  17. package/dist/interaction.js.map +1 -0
  18. package/dist/internal/layer-owner.d.ts +145 -0
  19. package/dist/internal/layer-owner.js +2 -0
  20. package/dist/internal/layer-owner.js.map +1 -0
  21. package/dist/internal/model-store.d.ts +32 -0
  22. package/dist/internal/model-store.js +2 -0
  23. package/dist/internal/model-store.js.map +1 -0
  24. package/dist/internal/query-index.d.ts +24 -0
  25. package/dist/internal/query-index.js +2 -0
  26. package/dist/internal/query-index.js.map +1 -0
  27. package/dist/internal/result.d.ts +4 -0
  28. package/dist/internal/result.js +2 -0
  29. package/dist/internal/result.js.map +1 -0
  30. package/dist/layout.d.ts +61 -0
  31. package/dist/layout.js +2 -0
  32. package/dist/layout.js.map +1 -0
  33. package/dist/model.d.ts +128 -0
  34. package/dist/model.js +2 -0
  35. package/dist/model.js.map +1 -0
  36. package/dist/projection.d.ts +149 -0
  37. package/dist/projection.js +2 -0
  38. package/dist/projection.js.map +1 -0
  39. package/dist/query.d.ts +47 -0
  40. package/dist/query.js +2 -0
  41. package/dist/query.js.map +1 -0
  42. package/dist/result.d.ts +5 -0
  43. package/dist/result.js +2 -0
  44. package/dist/result.js.map +1 -0
  45. package/dist/scale.d.ts +70 -0
  46. package/dist/scale.js +2 -0
  47. package/dist/scale.js.map +1 -0
  48. package/dist/view.d.ts +52 -0
  49. package/dist/view.js +2 -0
  50. package/dist/view.js.map +1 -0
  51. package/package.json +106 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jinyongp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @sectile/chart
2
+
3
+ Renderer-neutral chart models, scales, packed projections, spatial queries, and
4
+ interaction semantics for Sectile.
5
+
6
+ The package root is type-only. Import runtime APIs from focused subpaths such as
7
+ `@sectile/chart/model`, `@sectile/chart/scale`, `@sectile/chart/projection`,
8
+ `@sectile/chart/query`, `@sectile/chart/interaction`, and
9
+ `@sectile/chart/controller`.
10
+
11
+ Browser rendering and input live in `@sectile/dom/chart`. Vue composition lives
12
+ in `@sectile/vue/chart`. Both treat Chart as an optional peer dependency; this
13
+ package never reads host elements or owns rendering resources.
14
+
15
+ See the [Chart manual](https://sectile.github.io/sectile/packages/chart) for
16
+ supported profiles, resource ceilings, performance contracts, and adapter
17
+ guidance.
@@ -0,0 +1,194 @@
1
+ import type { StableID } from '@sectile/core';
2
+ import type { UnitID } from '@sectile/core/units';
3
+ import type { ChartLimits } from './model.js';
4
+ import type { ChartResult } from './result.js';
5
+ import type { ChartScaleKind } from './scale.js';
6
+ export type ChartCoordinateKind = 'cartesian' | 'radial';
7
+ export type ChartAxisOrientation = 'x' | 'y';
8
+ export type ChartLayerKind = 'line' | 'scatter' | 'bar' | 'heatmap' | 'pie' | 'donut';
9
+ export type ChartCategory = string | number;
10
+ export type ChartTemporalValue = number | Date;
11
+ export type ChartAxisInputValue = number | string | Date;
12
+ export type ChartAxisValue = number | string;
13
+ export type ChartAccessor<Datum, Value> = (datum: Datum) => Value;
14
+ export type ChartInferredIdentity<Datum> = Datum extends {
15
+ readonly id: infer ID extends StableID;
16
+ } ? ID : StableID;
17
+ export interface ChartNumericDomainInput {
18
+ readonly kind: 'numeric';
19
+ readonly minimum: number;
20
+ readonly maximum: number;
21
+ }
22
+ export interface ChartTemporalDomainInput {
23
+ readonly kind: 'temporal';
24
+ readonly minimum: ChartTemporalValue;
25
+ readonly maximum: ChartTemporalValue;
26
+ }
27
+ export interface ChartCategoricalDomainInput {
28
+ readonly kind: 'categorical';
29
+ readonly values: readonly ChartCategory[];
30
+ }
31
+ export type ChartAxisDomainInput = 'auto' | ChartNumericDomainInput | ChartTemporalDomainInput | ChartCategoricalDomainInput;
32
+ export interface ChartAxisNumericDomain {
33
+ readonly kind: 'numeric';
34
+ readonly minimum: number;
35
+ readonly maximum: number;
36
+ }
37
+ export interface ChartAxisTemporalDomain {
38
+ readonly kind: 'temporal';
39
+ readonly minimum: number;
40
+ readonly maximum: number;
41
+ }
42
+ export interface ChartAxisCategoricalDomain {
43
+ readonly kind: 'categorical';
44
+ readonly values: readonly ChartCategory[];
45
+ }
46
+ export type ChartAxisDomain = 'auto' | ChartAxisNumericDomain | ChartAxisTemporalDomain | ChartAxisCategoricalDomain;
47
+ export interface ChartAxisDefinition<Datum = unknown, ID extends StableID = StableID> {
48
+ readonly id: ID;
49
+ readonly orientation: ChartAxisOrientation;
50
+ readonly scale: ChartScaleKind;
51
+ readonly domain?: ChartAxisDomainInput;
52
+ readonly field?: string;
53
+ readonly getValue?: ChartAccessor<Datum, ChartAxisInputValue>;
54
+ readonly ticks?: number;
55
+ readonly label?: string;
56
+ readonly unit?: UnitID;
57
+ }
58
+ export interface NormalizedChartAxisDefinition<Datum = unknown, ID extends StableID = StableID> extends Omit<ChartAxisDefinition<Datum, ID>, 'domain'> {
59
+ readonly domain: ChartAxisDomain;
60
+ }
61
+ export interface ChartCartesianCoordinateDefinition<Datum = unknown, ID extends StableID = StableID> {
62
+ readonly kind: 'cartesian';
63
+ readonly axes: readonly ChartAxisDefinition<Datum, ID>[];
64
+ }
65
+ export interface ChartRadialCoordinateDefinition {
66
+ readonly kind: 'radial';
67
+ }
68
+ export type ChartCoordinateDefinition<Datum = unknown, ID extends StableID = StableID> = ChartCartesianCoordinateDefinition<Datum, ID> | ChartRadialCoordinateDefinition;
69
+ export interface NormalizedChartCartesianCoordinateDefinition<Datum = unknown, ID extends StableID = StableID> {
70
+ readonly kind: 'cartesian';
71
+ readonly axes: readonly NormalizedChartAxisDefinition<Datum, ID>[];
72
+ }
73
+ export type NormalizedChartCoordinateDefinition<Datum = unknown, ID extends StableID = StableID> = NormalizedChartCartesianCoordinateDefinition<Datum, ID> | ChartRadialCoordinateDefinition;
74
+ interface ChartLayerDefinitionBase<Datum, ID extends StableID> {
75
+ readonly id: ID;
76
+ readonly data: readonly Datum[];
77
+ readonly getId?: ChartAccessor<Datum, ID>;
78
+ readonly label?: string;
79
+ }
80
+ interface ChartCartesianLayerDefinitionBase<Datum, ID extends StableID> extends ChartLayerDefinitionBase<Datum, ID> {
81
+ readonly xAxis: ID;
82
+ readonly yAxis: ID;
83
+ readonly getX?: ChartAccessor<Datum, ChartAxisInputValue>;
84
+ readonly getY?: ChartAccessor<Datum, ChartAxisInputValue>;
85
+ }
86
+ export interface ChartLineLayerDefinition<Datum = unknown, ID extends StableID = StableID> extends ChartCartesianLayerDefinitionBase<Datum, ID> {
87
+ readonly kind: 'line';
88
+ }
89
+ export interface ChartScatterLayerDefinition<Datum = unknown, ID extends StableID = StableID> extends ChartCartesianLayerDefinitionBase<Datum, ID> {
90
+ readonly kind: 'scatter';
91
+ readonly projection?: 'raw' | 'density';
92
+ }
93
+ export interface ChartBarLayerDefinition<Datum = unknown, ID extends StableID = StableID> extends ChartCartesianLayerDefinitionBase<Datum, ID> {
94
+ readonly kind: 'bar';
95
+ readonly orientation?: 'vertical' | 'horizontal';
96
+ }
97
+ export type ChartHeatmapReduction = 'sum' | 'mean' | 'minimum' | 'maximum';
98
+ export interface ChartHeatmapLayerDefinition<Datum = unknown, ID extends StableID = StableID> extends ChartCartesianLayerDefinitionBase<Datum, ID> {
99
+ readonly kind: 'heatmap';
100
+ readonly getValue?: ChartAccessor<Datum, number>;
101
+ readonly valueField?: string;
102
+ readonly projection?: 'raw' | {
103
+ readonly kind: 'aggregate';
104
+ readonly reduction: ChartHeatmapReduction;
105
+ };
106
+ }
107
+ interface ChartRadialLayerDefinitionBase<Datum, ID extends StableID> extends ChartLayerDefinitionBase<Datum, ID> {
108
+ readonly getValue?: ChartAccessor<Datum, number>;
109
+ readonly valueField?: string;
110
+ readonly getLabel?: ChartAccessor<Datum, string>;
111
+ readonly labelField?: string;
112
+ }
113
+ export interface ChartPieLayerDefinition<Datum = unknown, ID extends StableID = StableID> extends ChartRadialLayerDefinitionBase<Datum, ID> {
114
+ readonly kind: 'pie';
115
+ }
116
+ export interface ChartDonutLayerDefinition<Datum = unknown, ID extends StableID = StableID> extends ChartRadialLayerDefinitionBase<Datum, ID> {
117
+ readonly kind: 'donut';
118
+ readonly innerRadius?: number;
119
+ readonly outerRadius?: number;
120
+ }
121
+ export type ChartCartesianLayerDefinition<Datum = unknown, ID extends StableID = StableID> = ChartLineLayerDefinition<Datum, ID> | ChartScatterLayerDefinition<Datum, ID> | ChartBarLayerDefinition<Datum, ID> | ChartHeatmapLayerDefinition<Datum, ID>;
122
+ export type ChartRadialLayerDefinition<Datum = unknown, ID extends StableID = StableID> = ChartPieLayerDefinition<Datum, ID> | ChartDonutLayerDefinition<Datum, ID>;
123
+ export type ChartLayerDefinition<Datum = unknown, ID extends StableID = StableID> = ChartCartesianLayerDefinition<Datum, ID> | ChartRadialLayerDefinition<Datum, ID>;
124
+ export interface ChartValueResolution<Datum, Value extends ChartAxisInputValue = ChartAxisInputValue> {
125
+ readonly getValue?: ChartAccessor<Datum, Value>;
126
+ readonly field?: string;
127
+ readonly canonicalField: 'x' | 'y' | 'value' | 'label';
128
+ readonly kind: 'numeric' | 'temporal' | 'categorical';
129
+ }
130
+ export type ChartAggregateReduction = 'density' | ChartHeatmapReduction;
131
+ export interface ChartAggregateBounds {
132
+ readonly minimumX: number;
133
+ readonly maximumX: number;
134
+ readonly minimumY: number;
135
+ readonly maximumY: number;
136
+ }
137
+ export interface ChartDatumRepresentative<ID extends StableID = StableID> {
138
+ readonly kind: 'datum';
139
+ readonly id: ID;
140
+ }
141
+ export interface ChartAggregateRepresentative {
142
+ readonly kind: 'aggregate';
143
+ readonly reduction: ChartAggregateReduction;
144
+ readonly count: number;
145
+ readonly bounds: ChartAggregateBounds;
146
+ }
147
+ export type ChartRepresentative<ID extends StableID = StableID> = ChartDatumRepresentative<ID> | ChartAggregateRepresentative;
148
+ export interface ChartContinuousViewWindow {
149
+ readonly kind: 'continuous';
150
+ readonly minimum: number;
151
+ readonly maximum: number;
152
+ }
153
+ export interface ChartCategoricalViewWindow {
154
+ readonly kind: 'categorical';
155
+ readonly start: number;
156
+ readonly end: number;
157
+ }
158
+ export type ChartAxisViewWindow = ChartContinuousViewWindow | ChartCategoricalViewWindow;
159
+ export type ChartAxisViewUpdateMode = 'preserve' | 'reset' | 'follow-end';
160
+ export interface ChartAxisView<ID extends StableID = StableID> {
161
+ readonly axisID: ID;
162
+ readonly orientation?: ChartAxisOrientation;
163
+ readonly scale: ChartScaleKind;
164
+ readonly base: ChartAxisViewWindow;
165
+ readonly initial?: ChartAxisViewWindow;
166
+ readonly visible: ChartAxisViewWindow;
167
+ readonly minimumSpan?: number;
168
+ readonly maximumSpan?: number;
169
+ readonly update?: ChartAxisViewUpdateMode;
170
+ readonly followingEnd?: boolean;
171
+ readonly categories?: readonly ChartCategory[];
172
+ readonly revision: number;
173
+ }
174
+ export interface ChartViewState<ID extends StableID = StableID> {
175
+ readonly revision: number;
176
+ readonly axes: readonly ChartAxisView<ID>[];
177
+ }
178
+ export declare const DEFAULT_MAXIMUM_CHART_AXES = 16;
179
+ export declare const MAXIMUM_CHART_AXES = 64;
180
+ export declare function normalizeChartTemporalValue(value: ChartTemporalValue): number;
181
+ export declare function tryNormalizeChartTemporalValue(value: unknown): ChartResult<number>;
182
+ export declare function resolveChartIdentity<Datum, ID extends StableID = ChartInferredIdentity<Datum>>(datum: Datum, getId?: ChartAccessor<Datum, ID>, maxIDCodeUnits?: number): ID;
183
+ export declare function tryResolveChartIdentity<Datum, ID extends StableID = ChartInferredIdentity<Datum>>(datum: Datum, getId?: ChartAccessor<Datum, ID>, maxIDCodeUnits?: number): ChartResult<ID>;
184
+ export declare function resolveChartValue<Datum>(datum: Datum, resolution: ChartValueResolution<Datum>): ChartAxisValue;
185
+ export declare function tryResolveChartValue<Datum>(datum: Datum, resolution: ChartValueResolution<Datum>): ChartResult<ChartAxisValue>;
186
+ export declare function normalizeChartRepresentative<ID extends StableID>(representative: ChartRepresentative<ID>): ChartRepresentative<ID>;
187
+ export declare function tryNormalizeChartRepresentative<ID extends StableID>(representative: ChartRepresentative<ID>): ChartResult<ChartRepresentative<ID>>;
188
+ export declare function normalizeChartCoordinate<Datum, ID extends StableID>(input: ChartCoordinateDefinition<Datum, ID>, limits?: Pick<ChartLimits, 'maxAxes' | 'maxIDCodeUnits'>): NormalizedChartCoordinateDefinition<Datum, ID>;
189
+ export declare function tryNormalizeChartCoordinate<Datum, ID extends StableID>(input: ChartCoordinateDefinition<Datum, ID>, limits?: Pick<ChartLimits, 'maxAxes' | 'maxIDCodeUnits'>): ChartResult<NormalizedChartCoordinateDefinition<Datum, ID>>;
190
+ export declare function validateChartLayerCoordinate<Datum, ID extends StableID>(coordinate: NormalizedChartCoordinateDefinition<Datum, ID>, layer: ChartLayerDefinition<Datum, ID>): void;
191
+ export declare function tryValidateChartLayerCoordinate<Datum, ID extends StableID>(coordinate: NormalizedChartCoordinateDefinition<Datum, ID>, layer: ChartLayerDefinition<Datum, ID>): ChartResult<void>;
192
+ export declare function createChartViewState<ID extends StableID>(axes: readonly ChartAxisView<ID>[], revision?: number, limits?: Pick<ChartLimits, 'maxAxes' | 'maxIDCodeUnits'>): ChartViewState<ID>;
193
+ export declare function tryCreateChartViewState<ID extends StableID>(axes: readonly ChartAxisView<ID>[], revision?: number, limits?: Pick<ChartLimits, 'maxAxes' | 'maxIDCodeUnits'>): ChartResult<ChartViewState<ID>>;
194
+ export {};
@@ -0,0 +1,2 @@
1
+ import{DEFAULT_MAX_ID_CODE_UNITS,validateStableID}from"@sectile/core/identity";import{unwrap}from"@sectile/core/result";import{chartFail,chartOK}from"./internal/result.js";const DEFAULT_MAXIMUM_CHART_AXES=16;const MAXIMUM_CHART_AXES=64;function normalizeChartTemporalValue(value){return unwrap(tryNormalizeChartTemporalValue(value))}function tryNormalizeChartTemporalValue(value){const normalized=value instanceof Date?value.getTime():value;return typeof normalized==="number"&&Number.isFinite(normalized)?chartOK(normalized):chartFail("construction","chart-temporal-invalid","Temporal chart values must be valid Date objects or finite epoch-millisecond numbers.")}function resolveChartIdentity(datum,getId,maxIDCodeUnits=DEFAULT_MAX_ID_CODE_UNITS){return unwrap(tryResolveChartIdentity(datum,getId,maxIDCodeUnits))}function tryResolveChartIdentity(datum,getId,maxIDCodeUnits=DEFAULT_MAX_ID_CODE_UNITS){const resolved=getId===void 0?readField(datum,"id"):callAccessor(datum,getId,"Chart identity accessor failed.");if(!resolved.ok)return resolved;if(resolved.value===void 0){return chartFail("construction","chart-identity-missing","Chart data requires an explicit identity accessor or canonical id field.")}const error=validateStableID(resolved.value,maxIDCodeUnits);return error===null?chartOK(resolved.value):{ok:false,error}}function resolveChartValue(datum,resolution){return unwrap(tryResolveChartValue(datum,resolution))}function tryResolveChartValue(datum,resolution){if(resolution===null||typeof resolution!=="object")return invalidAccessor("Chart value resolution must be an object.");let resolved;if(resolution.getValue!==void 0){if(typeof resolution.getValue!=="function")return invalidAccessor("Chart value accessor must be a function.");resolved=callAccessor(datum,resolution.getValue,"Chart value accessor failed.")}else if(resolution.field!==void 0){if(!nonEmptyString(resolution.field))return invalidAccessor("Chart value field must be a non-empty string.");resolved=readField(datum,resolution.field)}else{resolved=readField(datum,resolution.canonicalField)}if(!resolved.ok)return resolved;if(resolution.kind==="temporal")return tryNormalizeChartTemporalValue(resolved.value);if(resolution.kind==="numeric"){return typeof resolved.value==="number"&&Number.isFinite(resolved.value)?chartOK(resolved.value):invalidAccessor("Numeric chart values must be finite numbers.")}if(resolution.kind==="categorical"){return validCategory(resolved.value)?chartOK(resolved.value):invalidAccessor("Categorical chart values must be finite numbers or non-empty strings.")}return invalidAccessor("Chart value resolution kind is invalid.")}function normalizeChartRepresentative(representative){return unwrap(tryNormalizeChartRepresentative(representative))}function tryNormalizeChartRepresentative(representative){if(representative===null||typeof representative!=="object"){return invalidAggregate("Chart representative must be an object.")}if(representative.kind==="datum"){const error=validateStableID(representative.id);return error===null?chartOK(Object.freeze({kind:"datum",id:representative.id})):{ok:false,error}}if(representative.kind!=="aggregate"||"id"in representative||!validAggregateReduction(representative.reduction)||!Number.isSafeInteger(representative.count)||representative.count<1||!validAggregateBounds(representative.bounds)){return invalidAggregate("Aggregate chart representatives require a reduction, positive count, finite bounds, and no datum identity.")}return chartOK(Object.freeze({kind:"aggregate",reduction:representative.reduction,count:representative.count,bounds:Object.freeze({...representative.bounds})}))}function normalizeChartCoordinate(input,limits={}){return unwrap(tryNormalizeChartCoordinate(input,limits))}function tryNormalizeChartCoordinate(input,limits={}){if(input===null||typeof input!=="object")return invalidCoordinate("Chart coordinate definition must be an object.");if(input.kind==="radial"){return"axes"in input?chartFail("construction","chart-coordinate-mismatch","Radial coordinates do not accept Cartesian axes."):chartOK(Object.freeze({kind:"radial"}))}if(input.kind!=="cartesian"||!Array.isArray(input.axes)){return invalidCoordinate("Chart coordinate kind must be cartesian or radial.")}const maxAxes=limits.maxAxes??DEFAULT_MAXIMUM_CHART_AXES;const maxIDCodeUnits=limits.maxIDCodeUnits??DEFAULT_MAX_ID_CODE_UNITS;if(!Number.isSafeInteger(maxAxes)||maxAxes<2||maxAxes>MAXIMUM_CHART_AXES){return invalidCoordinate("Chart maxAxes must be a safe integer between 2 and the hard ceiling.")}if(input.axes.length>maxAxes){return chartFail("resource-rejection","chart-axis-ceiling-exceeded","Chart axis count exceeds its ceiling.",{actual:input.axes.length,ceiling:maxAxes})}const axes=[];const identities=new Set;let xAxes=0;let yAxes=0;for(const axis of input.axes){const normalized=tryNormalizeChartAxis(axis,maxIDCodeUnits);if(!normalized.ok)return normalized;if(identities.has(normalized.value.id)){return chartFail("construction","chart-axis-duplicate","Chart axis identities must be unique.",{id:normalized.value.id})}identities.add(normalized.value.id);axes.push(normalized.value);if(normalized.value.orientation==="x")xAxes+=1;else yAxes+=1}if(xAxes===0||yAxes===0){return chartFail("construction","chart-axis-missing","Cartesian coordinates require at least one X axis and one Y axis.")}return chartOK(Object.freeze({kind:"cartesian",axes:Object.freeze(axes)}))}function validateChartLayerCoordinate(coordinate,layer){unwrap(tryValidateChartLayerCoordinate(coordinate,layer))}function tryValidateChartLayerCoordinate(coordinate,layer){if(coordinate===null||typeof coordinate!=="object"||layer===null||typeof layer!=="object"){return chartFail("construction","chart-coordinate-mismatch","Chart coordinate and layer definitions must be objects.")}const radialLayer=layer.kind==="pie"||layer.kind==="donut";if(coordinate.kind==="radial"!==radialLayer){return chartFail("construction","chart-coordinate-mismatch","Chart layer kind is incompatible with its coordinate system.",{coordinate:coordinate.kind,layer:layer.kind})}if(coordinate.kind==="radial"||radialLayer)return chartOK(void 0);const xAxis=coordinate.axes.find(axis=>axis.id===layer.xAxis);const yAxis=coordinate.axes.find(axis=>axis.id===layer.yAxis);if(xAxis===void 0||yAxis===void 0){return chartFail("construction","chart-axis-missing","Cartesian layer axis references must resolve within the same coordinate system.")}if(xAxis.orientation!=="x"||yAxis.orientation!=="y"){return chartFail("construction","chart-coordinate-mismatch","Cartesian layer axes must match their X and Y orientations.")}return chartOK(void 0)}function createChartViewState(axes,revision=0,limits={}){return unwrap(tryCreateChartViewState(axes,revision,limits))}function tryCreateChartViewState(axes,revision=0,limits={}){if(!Array.isArray(axes)||!nonNegativeSafeInteger(revision))return invalidView("Chart view state is invalid.");const maxAxes=limits.maxAxes??DEFAULT_MAXIMUM_CHART_AXES;const maxIDCodeUnits=limits.maxIDCodeUnits??DEFAULT_MAX_ID_CODE_UNITS;if(!Number.isSafeInteger(maxAxes)||maxAxes<0||maxAxes>MAXIMUM_CHART_AXES){return invalidView("Chart view maxAxes must be a non-negative safe integer within the hard ceiling.")}if(axes.length>maxAxes){return chartFail("resource-rejection","chart-axis-ceiling-exceeded","Chart view axis count exceeds its ceiling.",{actual:axes.length,ceiling:maxAxes})}const identities=new Set;const normalized=[];for(const axis of axes){if(axis===null||typeof axis!=="object")return invalidView("Chart axis view must be an object.");const idError=validateStableID(axis.axisID,maxIDCodeUnits);if(idError!==null)return{ok:false,error:idError};if(identities.has(axis.axisID))return chartFail("construction","chart-axis-duplicate","Chart view axis identities must be unique.",{id:axis.axisID});identities.add(axis.axisID);const checked=normalizeAxisView(axis);if(!checked.ok)return checked;normalized.push(checked.value)}return chartOK(Object.freeze({revision,axes:Object.freeze(normalized)}))}function tryNormalizeChartAxis(axis,maxIDCodeUnits){if(axis===null||typeof axis!=="object")return invalidAxis("Chart axis definition must be an object.");const idError=validateStableID(axis.id,maxIDCodeUnits);if(idError!==null)return{ok:false,error:idError};if(axis.orientation!=="x"&&axis.orientation!=="y")return invalidAxis("Chart axis orientation must be x or y.");if(!validScaleKind(axis.scale))return invalidAxis("Chart axis scale kind is invalid.");if(axis.field!==void 0&&!nonEmptyString(axis.field))return invalidAxis("Chart axis field must be a non-empty string.");if(axis.getValue!==void 0&&typeof axis.getValue!=="function")return invalidAxis("Chart axis accessor must be a function.");if(axis.ticks!==void 0&&(!nonNegativeSafeInteger(axis.ticks)||axis.ticks>1e4)){return chartFail("resource-rejection","chart-tick-ceiling-exceeded","Chart axis tick count exceeds its valid range.",{ticks:axis.ticks})}if(axis.label!==void 0&&typeof axis.label!=="string")return invalidAxis("Chart axis label must be a string.");if(axis.unit!==void 0&&!nonEmptyString(axis.unit))return invalidAxis("Chart axis unit must be a non-empty UnitID.");const domain=normalizeAxisDomain(axis.scale,axis.domain??"auto");if(!domain.ok)return domain;return chartOK(Object.freeze({...axis,domain:domain.value}))}function normalizeAxisDomain(scale,domain){if(domain==="auto")return chartOK("auto");if(domain===null||typeof domain!=="object")return invalidDomain("Chart axis domain is invalid.");if(scale==="temporal"){if(domain.kind!=="temporal")return invalidDomain("Temporal axes require a temporal domain.");const minimum=tryNormalizeChartTemporalValue(domain.minimum);if(!minimum.ok)return minimum;const maximum=tryNormalizeChartTemporalValue(domain.maximum);if(!maximum.ok)return maximum;return minimum.value<maximum.value?chartOK(Object.freeze({kind:"temporal",minimum:minimum.value,maximum:maximum.value})):invalidDomain("Temporal chart domains must be increasing.")}if(scale==="categorical"){if(domain.kind!=="categorical"||!Array.isArray(domain.values)||domain.values.length===0){return invalidDomain("Categorical axes require at least one category.")}const values=[];const seen=new Set;for(const value of domain.values){if(!validCategory(value)||seen.has(value))return invalidDomain("Categorical axis values must be unique finite numbers or non-empty strings.");seen.add(value);values.push(value)}return chartOK(Object.freeze({kind:"categorical",values:Object.freeze(values)}))}if(domain.kind!=="numeric"||!finiteIncreasing(domain.minimum,domain.maximum)){return invalidDomain("Linear and logarithmic axes require an increasing numeric domain.")}if(scale==="logarithmic"&&domain.minimum<=0)return invalidDomain("Logarithmic chart domains must be positive.");return chartOK(Object.freeze({kind:"numeric",minimum:domain.minimum,maximum:domain.maximum}))}function normalizeAxisView(axis){if(!validScaleKind(axis.scale)||!nonNegativeSafeInteger(axis.revision))return invalidView("Chart axis view scale or revision is invalid.");if(axis.orientation!==void 0&&axis.orientation!=="x"&&axis.orientation!=="y")return invalidView("Chart axis view orientation is invalid.");const categorical=axis.scale==="categorical";if(categorical!==(axis.base.kind==="categorical")||categorical!==(axis.visible.kind==="categorical")){return invalidView("Chart axis view windows must match the scale kind.")}const initial=axis.initial??axis.visible;if(!validViewWindow(axis.base)||!validViewWindow(initial)||!validViewWindow(axis.visible))return invalidView("Chart axis view windows are invalid.");const baseStart=windowStart(axis.base);const baseEnd=windowEnd(axis.base);const initialStart=windowStart(initial);const initialEnd=windowEnd(initial);const visibleStart=windowStart(axis.visible);const visibleEnd=windowEnd(axis.visible);if(initialStart<baseStart||initialEnd>baseEnd||visibleStart<baseStart||visibleEnd>baseEnd){return invalidView("Initial and visible chart axis views must remain inside their base window.")}if(axis.scale==="logarithmic"&&baseStart<=0)return invalidView("Logarithmic chart axis views must be positive.");const baseSpan=axis.scale==="logarithmic"?Math.log(baseEnd)-Math.log(baseStart):baseEnd-baseStart;const minimumSpan=axis.minimumSpan??(categorical?1:0);const maximumSpan=axis.maximumSpan??baseSpan;const visibleSpan=axis.scale==="logarithmic"?Math.log(visibleEnd)-Math.log(visibleStart):visibleEnd-visibleStart;if(!Number.isFinite(minimumSpan)||minimumSpan<0||!Number.isFinite(maximumSpan)||maximumSpan<minimumSpan||visibleSpan<minimumSpan||visibleSpan>maximumSpan){return invalidView("Chart axis view span limits are invalid.")}const update=axis.update??"preserve";if(update!=="preserve"&&update!=="reset"&&update!=="follow-end")return invalidView("Chart axis view update mode is invalid.");if(axis.followingEnd!==void 0&&typeof axis.followingEnd!=="boolean")return invalidView("Chart follow-end state must be boolean.");if(categorical&&axis.categories!==void 0){if(!Array.isArray(axis.categories)||axis.categories.length!==baseEnd-baseStart){return invalidView("Categorical chart axis view categories must match its base slot count.")}const categories=new Set;for(const category of axis.categories){if(!validCategory(category)||categories.has(category))return invalidView("Categorical chart axis view categories must be unique.");categories.add(category)}}else if(!categorical&&axis.categories!==void 0)return invalidView("Continuous chart axis views do not accept categories.");return chartOK(Object.freeze({axisID:axis.axisID,...axis.orientation===void 0?{}:{orientation:axis.orientation},scale:axis.scale,base:freezeViewWindow(axis.base),initial:freezeViewWindow(initial),visible:freezeViewWindow(axis.visible),minimumSpan,maximumSpan,update,followingEnd:axis.followingEnd??(update==="follow-end"&&visibleEnd===baseEnd),...axis.categories===void 0?{}:{categories:Object.freeze([...axis.categories])},revision:axis.revision}))}function validViewWindow(window){return window!==null&&typeof window==="object"&&(window.kind==="continuous"?finiteIncreasing(window.minimum,window.maximum):window.kind==="categorical"&&nonNegativeSafeInteger(window.start)&&Number.isSafeInteger(window.end)&&window.end>window.start)}function freezeViewWindow(window){return window.kind==="continuous"?Object.freeze({kind:"continuous",minimum:window.minimum,maximum:window.maximum}):Object.freeze({kind:"categorical",start:window.start,end:window.end})}function windowStart(window){return window.kind==="continuous"?window.minimum:window.start}function windowEnd(window){return window.kind==="continuous"?window.maximum:window.end}function readField(value,field){return value!==null&&typeof value==="object"?chartOK(value[field]):invalidAccessor("Chart accessors require object data when resolving a field.")}function callAccessor(datum,accessor,message){try{return chartOK(accessor(datum))}catch{return invalidAccessor(message)}}function validScaleKind(value){return value==="linear"||value==="logarithmic"||value==="temporal"||value==="categorical"}function validCategory(value){return typeof value==="string"?value.length>0:typeof value==="number"&&Number.isFinite(value)}function validAggregateReduction(value){return value==="density"||value==="sum"||value==="mean"||value==="minimum"||value==="maximum"}function validAggregateBounds(value){if(value===null||typeof value!=="object")return false;const bounds=value;return typeof bounds.minimumX==="number"&&Number.isFinite(bounds.minimumX)&&typeof bounds.maximumX==="number"&&Number.isFinite(bounds.maximumX)&&typeof bounds.minimumY==="number"&&Number.isFinite(bounds.minimumY)&&typeof bounds.maximumY==="number"&&Number.isFinite(bounds.maximumY)&&bounds.minimumX<=bounds.maximumX&&bounds.minimumY<=bounds.maximumY}function finiteIncreasing(minimum,maximum){return typeof minimum==="number"&&Number.isFinite(minimum)&&typeof maximum==="number"&&Number.isFinite(maximum)&&minimum<maximum}function nonEmptyString(value){return typeof value==="string"&&value.length>0}function nonNegativeSafeInteger(value){return typeof value==="number"&&Number.isSafeInteger(value)&&value>=0}function invalidAccessor(message){return chartFail("construction","chart-accessor-invalid",message)}function invalidAxis(message){return chartFail("construction","chart-axis-invalid",message)}function invalidAggregate(message){return chartFail("construction","chart-aggregate-invalid",message)}function invalidCoordinate(message){return chartFail("construction","chart-coordinate-invalid",message)}function invalidDomain(message){return chartFail("construction","chart-domain-invalid",message)}function invalidView(message){return chartFail("construction","chart-view-invalid",message)}export{DEFAULT_MAXIMUM_CHART_AXES,MAXIMUM_CHART_AXES,createChartViewState,normalizeChartCoordinate,normalizeChartRepresentative,normalizeChartTemporalValue,resolveChartIdentity,resolveChartValue,tryCreateChartViewState,tryNormalizeChartCoordinate,tryNormalizeChartRepresentative,tryNormalizeChartTemporalValue,tryResolveChartIdentity,tryResolveChartValue,tryValidateChartLayerCoordinate,validateChartLayerCoordinate};
2
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/contract.ts"],"mappings":"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","names":[],"file":"contract.js"}
@@ -0,0 +1,45 @@
1
+ import type { StableID } from '@sectile/core';
2
+ import { type RevisionSnapshot } from '@sectile/core/revision';
3
+ import { type ChartDefinition, type ChartDefinitionState } from './definition.js';
4
+ import { type ChartCommand, type ChartControlledValues, type ChartEvent, type ChartState } from './interaction.js';
5
+ import { type ChartLimits, type ChartModel, type ChartModelState, type ChartPatch } from './model.js';
6
+ import { type ChartProjection, type ChartProjectionInput } from './projection.js';
7
+ import type { ChartResult } from './result.js';
8
+ import { type ChartAxisViewCapability } from './view.js';
9
+ interface ChartControllerOptionsBase<ID extends StableID> {
10
+ readonly limits?: ChartLimits;
11
+ readonly initialValues?: ChartControlledValues<ID>;
12
+ readonly controlled?: ChartControlledValues<ID>;
13
+ }
14
+ export interface ChartModelControllerOptions<ID extends StableID = StableID> extends ChartControllerOptionsBase<ID> {
15
+ readonly model: ChartModel<ID>;
16
+ readonly definition?: never;
17
+ readonly viewCapabilities?: never;
18
+ }
19
+ export interface ChartDefinitionControllerOptions<ID extends StableID = StableID> extends ChartControllerOptionsBase<ID> {
20
+ readonly model?: never;
21
+ readonly definition: ChartDefinition<any, ID>;
22
+ readonly viewCapabilities?: readonly ChartAxisViewCapability<ID>[];
23
+ }
24
+ export type ChartControllerOptions<ID extends StableID = StableID> = ChartModelControllerOptions<ID> | ChartDefinitionControllerOptions<ID>;
25
+ export interface ChartUpdate<ID extends StableID = StableID> {
26
+ readonly snapshot: RevisionSnapshot<ChartState<ID>>;
27
+ readonly commands: readonly ChartCommand<ID>[];
28
+ }
29
+ export interface ChartController<ID extends StableID = StableID> {
30
+ getModel(): ChartModelState<ID>;
31
+ getDefinition(): ChartDefinitionState<ID> | null;
32
+ getSnapshot(): RevisionSnapshot<ChartState<ID>>;
33
+ replaceModel(model: ChartModel<ID>, expectedRevision?: number): ChartResult<RevisionSnapshot<ChartState<ID>>>;
34
+ replaceDefinition<Datum>(definition: ChartDefinition<Datum, ID>, viewCapabilities?: readonly ChartAxisViewCapability<ID>[], expectedRevision?: number): ChartResult<RevisionSnapshot<ChartState<ID>>>;
35
+ applyPatch(patch: ChartPatch<ID>, expectedRevision?: number): ChartResult<RevisionSnapshot<ChartState<ID>>>;
36
+ syncControlledValues(values: ChartControlledValues<ID>): ChartResult<RevisionSnapshot<ChartState<ID>>>;
37
+ dispatch(event: ChartEvent<ID>, expectedRevision?: number): ChartResult<ChartUpdate<ID>>;
38
+ project(input: ChartProjectionInput): ChartResult<ChartProjection<ID>>;
39
+ subscribeSnapshots(listener: (snapshot: RevisionSnapshot<ChartState<ID>>) => void): () => void;
40
+ subscribeCommands(listener: (command: ChartCommand<ID>) => void): () => void;
41
+ dispose(): void;
42
+ }
43
+ export declare function createChartController<ID extends StableID>(options: ChartControllerOptions<ID>): ChartController<ID>;
44
+ export declare function tryCreateChartController<ID extends StableID>(options: ChartControllerOptions<ID>): ChartResult<ChartController<ID>>;
45
+ export {};
@@ -0,0 +1,2 @@
1
+ import{unwrap}from"@sectile/core/result";import{createRevisionSnapshot}from"@sectile/core/revision";import{chartFail,chartOK}from"./internal/result.js";import{tryCreateChartDefinition,tryReplaceChartDefinition}from"./definition.js";import{reconcileChartState,reduceChartEvent,tryCreateChartState}from"./interaction.js";import{tryApplyChartPatch,tryCreateChartModel,tryReplaceChartModel}from"./model.js";import{tryCreateChartProjection}from"./projection.js";import{IDENTITY_CHART_VIEW_TRANSFORM}from"./scale.js";import{tryCreateChartAxisViewState,reconcileChartAxisViewState}from"./view.js";function createChartController(options){return unwrap(tryCreateChartController(options))}function tryCreateChartController(options){if(options===null||typeof options!=="object")return invalidController("Chart controller options must be an object.");if(options.model===void 0===(options.definition===void 0)){return invalidController("Chart controller requires exactly one model or declarative definition.")}const definition=options.definition===void 0?chartOK(null):tryCreateChartDefinition(options.definition,options.limits);if(!definition.ok)return definition;const model=definition.value===null?tryCreateChartModel(options.model,options.limits):chartOK(definition.value.model);if(!model.ok)return model;const controlledValues=options.controlled??{};const capabilities=options.definition===void 0?Object.freeze([]):Object.freeze([...options.viewCapabilities??[]]);const defaultView=definition.value===null||capabilities.length===0?chartOK(void 0):tryCreateChartAxisViewState(definition.value.axes,capabilities);if(!defaultView.ok)return defaultView;const state=tryCreateChartState(model.value,{...defaultView.value===void 0?{}:{view:defaultView.value},...options.initialValues??{},...controlledValues});if(!state.ok)return state;return chartOK(new ImmutableChartController(model.value,definition.value,capabilities,createRevisionSnapshot(state.value),controlFlags(controlledValues),Object.freeze({...controlledValues})))}class ImmutableChartController{#model;#definition;#viewCapabilities;#snapshot;#controlled;#controlledValues;#listeners=new Set;#snapshotListeners=new Set;#projectionCache=null;#disposed=false;constructor(model,definition,viewCapabilities,snapshot,controlled,controlledValues){this.#model=model;this.#definition=definition;this.#viewCapabilities=viewCapabilities;this.#snapshot=snapshot;this.#controlled=controlled;this.#controlledValues=controlledValues}getModel(){return this.#model}getDefinition(){return this.#definition}getSnapshot(){return this.#snapshot}replaceModel(input,expectedRevision=this.#snapshot.revision){const ready=this.#ready(expectedRevision);if(!ready.ok)return ready;const nextModel=tryReplaceChartModel(this.#model,input);if(!nextModel.ok)return nextModel;if(nextModel.value===this.#model&&this.#definition===null)return chartOK(this.#snapshot);return this.#commitModel(nextModel.value,null,null,Object.freeze([]))}replaceDefinition(input,viewCapabilities=this.#viewCapabilities,expectedRevision=this.#snapshot.revision){const ready=this.#ready(expectedRevision);if(!ready.ok)return ready;const next=this.#definition===null?tryCreateChartDefinition(input,this.#model.limits):tryReplaceChartDefinition(this.#definition,input,this.#model.limits);if(!next.ok)return next;const capabilities=Object.freeze([...viewCapabilities]);let view=this.#snapshot.state.view;if(capabilities.length===0)view=null;else if(view===null){const created=tryCreateChartAxisViewState(next.value.axes,capabilities);if(!created.ok)return created;view=created.value}else{const reconciled=reconcileChartAxisViewState(view,next.value.axes,capabilities);if(!reconciled.ok)return reconciled;view=reconciled.value}if(next.value===this.#definition&&view===this.#snapshot.state.view&&sameCapabilities(capabilities,this.#viewCapabilities))return chartOK(this.#snapshot);return this.#commitModel(next.value.model,view,next.value,capabilities)}applyPatch(patch,expectedRevision=this.#snapshot.revision){const ready=this.#ready(expectedRevision);if(!ready.ok)return ready;const nextModel=tryApplyChartPatch(this.#model,patch);if(!nextModel.ok)return nextModel;if(nextModel.value===this.#model)return chartOK(this.#snapshot);const definition=this.#definition===null?null:Object.freeze({...this.#definition,model:nextModel.value});return this.#commitModel(nextModel.value,this.#snapshot.state.view,definition,this.#viewCapabilities)}syncControlledValues(values){if(this.#disposed)return disposedController();if(values===null||typeof values!=="object"||!sameControlledShape(values,this.#controlled)){return invalidController("Controlled chart value shape must remain stable for the controller lifetime.")}const next=reconcileChartState(this.#snapshot.state,this.#model,values);if(!next.ok)return next;if(next.value===this.#snapshot.state){this.#controlledValues=Object.freeze({...values});return chartOK(this.#snapshot)}const projectionViewChanged=next.value.view!==this.#snapshot.state.view;const committed=this.#commitState(next.value,[]);if(committed.ok&&projectionViewChanged)this.#projectionCache=null;if(committed.ok)this.#controlledValues=Object.freeze({...values});return committed}dispatch(event,expectedRevision=this.#snapshot.revision){const ready=this.#ready(expectedRevision);if(!ready.ok)return ready;const reduced=reduceChartEvent(this.#model,this.#snapshot.state,event,this.#controlled);if(!reduced.ok)return reduced;if(reduced.value.changed){if(this.#snapshot.revision===Number.MAX_SAFE_INTEGER)return revisionExhausted();const projectionViewChanged=reduced.value.state.view!==this.#snapshot.state.view;this.#snapshot=createRevisionSnapshot(reduced.value.state,this.#snapshot.revision+1);if(projectionViewChanged)this.#projectionCache=null;for(const listener of this.#snapshotListeners)listener(this.#snapshot)}const update=Object.freeze({snapshot:this.#snapshot,commands:reduced.value.commands});this.#emit(reduced.value.commands);return chartOK(update)}project(input){if(this.#disposed)return disposedController();if(input===null||typeof input!=="object")return invalidController("Chart projection input must be an object.");const view=input.view??this.#snapshot.state.view??void 0;const resolved={...input,viewTransform:input.viewTransform??IDENTITY_CHART_VIEW_TRANSFORM,...view===void 0?{}:{view}};const cacheable=input.xScale===void 0&&input.yScale===void 0;if(cacheable&&this.#projectionCache!==null&&sameProjectionRequest(this.#projectionCache,this.#model,resolved)){return chartOK(this.#projectionCache.projection)}const projection=tryCreateChartProjection(this.#definition??this.#model,resolved);if(cacheable&&projection.ok)this.#projectionCache=projectionCache(this.#model,resolved,projection.value);return projection}subscribeCommands(listener){if(this.#disposed||typeof listener!=="function")return()=>void 0;this.#listeners.add(listener);let active=true;return()=>{if(!active)return;active=false;this.#listeners.delete(listener)}}subscribeSnapshots(listener){if(this.#disposed||typeof listener!=="function")return()=>void 0;this.#snapshotListeners.add(listener);let active=true;return()=>{if(!active)return;active=false;this.#snapshotListeners.delete(listener)}}dispose(){if(this.#disposed)return;this.#disposed=true;this.#listeners.clear();this.#snapshotListeners.clear();this.#projectionCache=null}#commitModel(model,view=this.#snapshot.state.view,definition=this.#definition,capabilities=this.#viewCapabilities){if(this.#snapshot.revision===Number.MAX_SAFE_INTEGER)return revisionExhausted();const state=reconcileChartState(this.#snapshot.state,model,this.#controlled.view===true?this.#controlledValues:{...this.#controlledValues,view});if(!state.ok)return state;this.#model=model;this.#definition=definition;this.#viewCapabilities=capabilities;this.#projectionCache=null;return this.#commitState(state.value,[Object.freeze({type:"render-requested",generation:model.generation})])}#commitState(state,commands){if(this.#snapshot.revision===Number.MAX_SAFE_INTEGER)return revisionExhausted();this.#snapshot=createRevisionSnapshot(state,this.#snapshot.revision+1);for(const listener of this.#snapshotListeners)listener(this.#snapshot);this.#emit(commands);return chartOK(this.#snapshot)}#ready(expectedRevision){if(this.#disposed)return disposedController();if(!Number.isSafeInteger(expectedRevision)||expectedRevision<0||expectedRevision!==this.#snapshot.revision){return chartFail("transition-rejection","stale-revision","Expected Chart revision does not match.",{expectedRevision,currentRevision:this.#snapshot.revision})}return chartOK(true)}#emit(commands){for(const command of commands)for(const listener of this.#listeners)listener(command)}}function sameCapabilities(left,right){if(left.length!==right.length)return false;for(let index=0;index<left.length;index+=1){const a=left[index];const b=right[index];if(a===void 0||b===void 0||a.axisID!==b.axisID||!sameCapabilityWindow(a.initial,b.initial)||a.minimumSpan!==b.minimumSpan||a.maximumSpan!==b.maximumSpan||a.update!==b.update)return false}return true}function sameCapabilityWindow(left,right){if(left===void 0||right===void 0)return left===right;return left.kind===right.kind&&(left.kind==="continuous"&&right.kind==="continuous"?left.minimum===right.minimum&&left.maximum===right.maximum:left.kind==="categorical"&&right.kind==="categorical"&&left.start===right.start&&left.end===right.end)}function projectionCache(model,input,projection){const transform=input.viewTransform;return{generation:model.generation,width:input.viewport.width,height:input.viewport.height,devicePixelRatio:input.viewport.devicePixelRatio,maximumRepresentatives:input.maximumRepresentatives,xScale:transform.xScale,xOffset:transform.xOffset,yScale:transform.yScale,yOffset:transform.yOffset,view:input.view,projection}}function sameProjectionRequest(cache,model,input){const transform=input.viewTransform;return cache.generation===model.generation&&cache.width===input.viewport.width&&cache.height===input.viewport.height&&cache.devicePixelRatio===input.viewport.devicePixelRatio&&cache.maximumRepresentatives===input.maximumRepresentatives&&cache.xScale===transform.xScale&&cache.xOffset===transform.xOffset&&cache.yScale===transform.yScale&&cache.yOffset===transform.yOffset&&cache.view===input.view}function controlFlags(values){return Object.freeze({activeDatum:own(values,"activeDatum"),cursor:own(values,"cursor"),selection:own(values,"selection"),view:own(values,"view")})}function sameControlledShape(values,flags){return own(values,"activeDatum")===flags.activeDatum&&own(values,"cursor")===flags.cursor&&own(values,"selection")===flags.selection&&own(values,"view")===flags.view}function own(value,key){return Object.prototype.hasOwnProperty.call(value,key)}function invalidController(message){return chartFail("construction","chart-controller-invalid",message)}function disposedController(){return chartFail("transition-rejection","chart-controller-disposed","Disposed Chart controller cannot be used.")}function revisionExhausted(){return chartFail("resource-rejection","revision-ceiling-reached","Chart revision is exhausted.")}export{createChartController,tryCreateChartController};
2
+ //# sourceMappingURL=controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/controller.ts"],"mappings":"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","names":[],"file":"controller.js"}
@@ -0,0 +1,40 @@
1
+ import type { StableID } from '@sectile/core';
2
+ import { type ChartCoordinateDefinition, type ChartHeatmapReduction, type ChartLayerDefinition, type NormalizedChartCoordinateDefinition } from './contract.js';
3
+ import { type ResolvedChartAxis } from './layout.js';
4
+ import { type ChartLimits, type ChartModelState, type ChartProfile } from './model.js';
5
+ import type { ChartResult } from './result.js';
6
+ export interface ChartDefinition<Datum = unknown, ID extends StableID = StableID> {
7
+ readonly coordinate: ChartCoordinateDefinition<Datum, ID>;
8
+ readonly layers: readonly ChartLayerDefinition<Datum, ID>[];
9
+ }
10
+ export interface ChartHeatmapGeometry {
11
+ readonly xEdges: Float64Array;
12
+ readonly yEdges: Float64Array;
13
+ }
14
+ export interface ResolvedChartLayer<ID extends StableID = StableID> {
15
+ readonly id: ID;
16
+ readonly kind: ChartLayerDefinition['kind'];
17
+ readonly profile: ChartProfile;
18
+ readonly label?: string;
19
+ readonly xAxis?: ID;
20
+ readonly yAxis?: ID;
21
+ readonly projection: 'exact' | 'density' | 'heatmap-aggregate';
22
+ readonly reduction?: ChartHeatmapReduction;
23
+ readonly heatmap?: ChartHeatmapGeometry;
24
+ }
25
+ export interface ChartDefinitionDiagnostics {
26
+ readonly resolvedAxes: number;
27
+ readonly resolvedLayers: number;
28
+ readonly resolvedDatums: number;
29
+ }
30
+ export interface ChartDefinitionState<ID extends StableID = StableID> {
31
+ readonly coordinate: NormalizedChartCoordinateDefinition<unknown, ID>;
32
+ readonly axes: readonly ResolvedChartAxis<ID>[];
33
+ readonly layers: readonly ResolvedChartLayer<ID>[];
34
+ readonly model: ChartModelState<ID>;
35
+ readonly diagnostics: ChartDefinitionDiagnostics;
36
+ }
37
+ export declare function createChartDefinition<Datum, ID extends StableID>(input: ChartDefinition<Datum, ID>, limits?: ChartLimits): ChartDefinitionState<ID>;
38
+ export declare function tryCreateChartDefinition<Datum, ID extends StableID>(input: ChartDefinition<Datum, ID>, limits?: ChartLimits): ChartResult<ChartDefinitionState<ID>>;
39
+ export declare function replaceChartDefinition<Datum, ID extends StableID>(previous: ChartDefinitionState<ID>, input: ChartDefinition<Datum, ID>, limits?: ChartLimits): ChartDefinitionState<ID>;
40
+ export declare function tryReplaceChartDefinition<Datum, ID extends StableID>(previous: ChartDefinitionState<ID>, input: ChartDefinition<Datum, ID>, limits?: ChartLimits): ChartResult<ChartDefinitionState<ID>>;
@@ -0,0 +1,2 @@
1
+ import{DEFAULT_MAX_ID_CODE_UNITS}from"@sectile/core/identity";import{unwrap}from"@sectile/core/result";import{tryResolveChartIdentity,tryResolveChartValue,tryNormalizeChartCoordinate,tryValidateChartLayerCoordinate}from"./contract.js";import{chartFail,chartOK}from"./internal/result.js";import{tryResolveChartAxes}from"./layout.js";import{tryCreateChartModel,tryReplaceChartModel}from"./model.js";function createChartDefinition(input,limits={}){return unwrap(tryCreateChartDefinition(input,limits))}function tryCreateChartDefinition(input,limits={}){if(input===null||typeof input!=="object"||!Array.isArray(input.layers)){return invalidDefinition("Chart definition requires one coordinate and a layer array.")}const normalizedCoordinate=tryNormalizeChartCoordinate(input.coordinate,limits);if(!normalizedCoordinate.ok)return normalizedCoordinate;const coordinate=normalizedCoordinate.value;const observations=new Map;if(coordinate.kind==="cartesian")for(const axis of coordinate.axes)observations.set(axis.id,[]);const pending=[];let datumCount=0;for(const sourceLayer of input.layers){const layer=sourceLayer;const compatible=tryValidateChartLayerCoordinate(coordinate,layer);if(!compatible.ok)return compatible;const collected=collectLayer(coordinate,layer,observations,limits.maxIDCodeUnits??DEFAULT_MAX_ID_CODE_UNITS);if(!collected.ok)return collected;pending.push(Object.freeze({definition:layer,datums:collected.value}));datumCount+=collected.value.length}const axesResult=coordinate.kind==="cartesian"?tryResolveChartAxes(coordinate,[...observations].map(([axisID,values])=>({axisID,values}))):chartOK(Object.freeze([]));if(!axesResult.ok)return axesResult;const axes=coordinate.kind==="cartesian"?expandHeatmapAutoDomains(coordinate,pending,axesResult.value):axesResult.value;const axisMap=new Map(axes.map(axis=>[axis.id,axis]));const modelLayers=[];const layers=[];for(const layer of pending){const compiled=compileLayer(layer,axisMap);if(!compiled.ok)return compiled;modelLayers.push(compiled.value.model);layers.push(compiled.value.layer)}const modelResult=tryCreateChartModel({layers:Object.freeze(modelLayers)},limits);if(!modelResult.ok)return modelResult;const model=modelResult.value;return chartOK(Object.freeze({coordinate,axes,layers:Object.freeze(layers),model,diagnostics:Object.freeze({resolvedAxes:axes.length,resolvedLayers:layers.length,resolvedDatums:datumCount})}))}function replaceChartDefinition(previous,input,limits=previous.model.limits){return unwrap(tryReplaceChartDefinition(previous,input,limits))}function tryReplaceChartDefinition(previous,input,limits=previous.model.limits){const next=tryCreateChartDefinition(input,limits);if(!next.ok)return next;const model=tryReplaceChartModel(previous.model,next.value.model.toModel());if(!model.ok)return model;if(model.value===previous.model&&sameDefinitionMetadata(previous,next.value))return chartOK(previous);return chartOK(Object.freeze({...next.value,model:model.value}))}function collectLayer(coordinate,layer,observations,maxIDCodeUnits){if(!Array.isArray(layer.data))return invalidDefinition("Chart layer data must be an array.");const output=[];if(coordinate.kind==="radial"){if(layer.kind!=="pie"&&layer.kind!=="donut")return invalidDefinition("Radial coordinates accept only pie and donut layers.");const innerRadius=layer.kind==="pie"?0:layer.innerRadius??.5;const outerRadius=layer.kind==="pie"?1:layer.outerRadius??1;if(!finiteNonNegative(innerRadius)||!finitePositive(outerRadius)||innerRadius>=outerRadius||outerRadius>1){return invalidDefinition("Pie and donut radii must be finite, normalized, and increasing.")}for(const datum of layer.data){const id=tryResolveChartIdentity(datum,layer.getId,maxIDCodeUnits);if(!id.ok)return id;const value=tryResolveChartValue(datum,{...layer.getValue===void 0?{}:{getValue:layer.getValue},...layer.valueField===void 0?{}:{field:layer.valueField},canonicalField:"value",kind:"numeric"});if(!value.ok)return value;if(typeof value.value!=="number"||value.value<0)return invalidDefinition("Pie and donut values must be finite and non-negative.");output.push(Object.freeze({id:id.value,value:value.value,innerRadius,outerRadius}))}return chartOK(Object.freeze(output))}if(layer.kind==="pie"||layer.kind==="donut")return invalidDefinition("Cartesian coordinates do not accept radial layers.");const xAxis=coordinate.axes.find(axis=>axis.id===layer.xAxis);const yAxis=coordinate.axes.find(axis=>axis.id===layer.yAxis);if(xAxis===void 0||yAxis===void 0)return invalidDefinition("Chart layer axes must resolve before data access.");if(layer.kind==="bar"){const vertical=(layer.orientation??"vertical")==="vertical";observations.get(vertical?yAxis.id:xAxis.id)?.push(0)}for(const datum of layer.data){const id=tryResolveChartIdentity(datum,layer.getId,maxIDCodeUnits);if(!id.ok)return id;const x=resolveAxisValue(datum,layer.getX,xAxis,"x");if(!x.ok)return x;const y=resolveAxisValue(datum,layer.getY,yAxis,"y");if(!y.ok)return y;observations.get(xAxis.id)?.push(x.value);observations.get(yAxis.id)?.push(y.value);if(layer.kind==="heatmap"){const value=tryResolveChartValue(datum,{...layer.getValue===void 0?{}:{getValue:layer.getValue},...layer.valueField===void 0?{}:{field:layer.valueField},canonicalField:"value",kind:"numeric"});if(!value.ok)return value;output.push(Object.freeze({id:id.value,x:x.value,y:y.value,value:value.value}))}else output.push(Object.freeze({id:id.value,x:x.value,y:y.value}))}return chartOK(Object.freeze(output))}function resolveAxisValue(datum,layerAccessor,axis,canonicalField){const getValue=layerAccessor??axis.getValue;return tryResolveChartValue(datum,{...getValue===void 0?{}:{getValue},...getValue!==void 0||axis.field===void 0?{}:{field:axis.field},canonicalField,kind:axis.scale==="temporal"?"temporal":axis.scale==="categorical"?"categorical":"numeric"})}function compileLayer(pending,axes){const definition=pending.definition;if(definition.kind==="pie"||definition.kind==="donut"){const data2=pending.datums.map(datum=>Object.freeze({id:datum.id,value:datum.value,innerRadius:datum.innerRadius,outerRadius:datum.outerRadius}));return chartOK({model:Object.freeze({id:definition.id,profile:"radial-segment",data:Object.freeze(data2)}),layer:resolvedLayer(definition,"radial-segment","exact")})}const xAxis=axes.get(definition.xAxis);const yAxis=axes.get(definition.yAxis);if(xAxis===void 0||yAxis===void 0)return invalidDefinition("Resolved Chart axes are missing.");if(definition.kind==="bar")return compileBar(pending,xAxis,yAxis);if(definition.kind==="heatmap")return compileHeatmap(pending,xAxis,yAxis);const data=pending.datums.map(datum=>Object.freeze({id:datum.id,x:geometryValue(datum.x,xAxis),y:geometryValue(datum.y,yAxis)}));if(data.some(datum=>datum.x===null||datum.y===null))return invalidDefinition("Chart values fall outside a declared categorical domain.");const profile=definition.kind==="line"?"ordered-series":"point";return chartOK({model:Object.freeze({id:definition.id,profile,data:Object.freeze(data)}),layer:resolvedLayer(definition,profile,definition.kind==="scatter"&&definition.projection==="density"?"density":"exact")})}function compileBar(pending,xAxis,yAxis){const definition=pending.definition;if(definition.kind!=="bar")return invalidDefinition("Bar compilation requires a bar layer.");const vertical=(definition.orientation??"vertical")==="vertical";const categoryAxis=vertical?xAxis:yAxis;const valueAxis=vertical?yAxis:xAxis;if(categoryAxis.scale!=="categorical"||valueAxis.scale!=="linear"){return invalidDefinition("Vertical bars require categorical X and linear Y axes; horizontal bars require linear X and categorical Y axes.")}const data=pending.datums.map(datum=>{const category=vertical?datum.x:datum.y;const value=vertical?datum.y:datum.x;const slot=categorySlot(category,categoryAxis);return vertical?Object.freeze({id:datum.id,x1:slot,y1:0,x2:slot===null?null:slot+1,y2:value}):Object.freeze({id:datum.id,x1:0,y1:slot,x2:value,y2:slot===null?null:slot+1})});if(data.some(datum=>datum.x1===null||datum.y1===null||datum.x2===null||datum.y2===null)){return invalidDefinition("Bar categories fall outside their declared domain.")}return chartOK({model:Object.freeze({id:definition.id,profile:"cartesian-segment",data:Object.freeze(data)}),layer:resolvedLayer(definition,"cartesian-segment","exact")})}function compileHeatmap(pending,xAxis,yAxis){const definition=pending.definition;if(definition.kind!=="heatmap")return invalidDefinition("Heatmap compilation requires a heatmap layer.");const xValues=heatmapSlots(pending.datums.map(datum=>datum.x),xAxis);const yValues=heatmapSlots(pending.datums.map(datum=>datum.y),yAxis);const xSlots=new Map(xValues.values.map((value,index)=>[value,index]));const ySlots=new Map(yValues.values.map((value,index)=>[value,index]));const data=pending.datums.map(datum=>Object.freeze({id:datum.id,column:xSlots.get(datum.x),row:ySlots.get(datum.y),value:datum.value}));const aggregate=typeof definition.projection==="object"&&definition.projection.kind==="aggregate";return chartOK({model:Object.freeze({id:definition.id,profile:"grid-cell",data:Object.freeze(data)}),layer:Object.freeze({...resolvedLayer(definition,"grid-cell",aggregate?"heatmap-aggregate":"exact"),...aggregate?{reduction:definition.projection.reduction}:{},heatmap:Object.freeze({xEdges:xValues.edges,yEdges:yValues.edges})})})}function heatmapSlots(observed,axis){const values=axis.domain.kind==="categorical"?axis.domain.values:[...new Set(observed)].sort((left,right)=>left-right);if(axis.domain.kind==="categorical"){return{values,edges:Float64Array.from({length:values.length+1},(_,index)=>index)}}const numeric=values;return{values,edges:numericEdges(numeric)}}function expandHeatmapAutoDomains(coordinate,pending,axes){return Object.freeze(axes.map(axis=>{const definition=coordinate.axes.find(candidate=>candidate.id===axis.id);if(definition?.domain!=="auto"||axis.domain.kind==="categorical"||axis.scale==="logarithmic")return axis;const values=[];for(const layer of pending){if(layer.definition.kind!=="heatmap")continue;const useX=layer.definition.xAxis===axis.id;const useY=layer.definition.yAxis===axis.id;if(!useX&&!useY)continue;for(const datum of layer.datums){const value=useX?datum.x:datum.y;if(typeof value==="number")values.push(value)}}if(values.length===0)return axis;const unique=[...new Set(values)].sort((left,right)=>left-right);const edges=numericEdges(unique);return Object.freeze({...axis,domain:Object.freeze({kind:axis.scale==="temporal"?"temporal":"numeric",minimum:Math.min(axis.domain.minimum,edges[0]),maximum:Math.max(axis.domain.maximum,edges[edges.length-1])})})}))}function numericEdges(values){const edges=new Float64Array(values.length+1);if(values.length===1){edges[0]=values[0]-.5;edges[1]=values[0]+.5}else if(values.length>1){edges[0]=values[0]-(values[1]-values[0])/2;for(let index=1;index<values.length;index+=1)edges[index]=(values[index-1]+values[index])/2;edges[values.length]=values.at(-1)+(values.at(-1)-values.at(-2))/2}return edges}function resolvedLayer(definition,profile,projection){const cartesian=definition.kind!=="pie"&&definition.kind!=="donut";return Object.freeze({id:definition.id,kind:definition.kind,profile,...definition.label===void 0?{}:{label:definition.label},...cartesian?{xAxis:definition.xAxis,yAxis:definition.yAxis}:{},projection})}function geometryValue(value,axis){if(axis.domain.kind!=="categorical")return typeof value==="number"?value:null;const slot=categorySlot(value,axis);return slot===null?null:slot+.5}function categorySlot(value,axis){if(axis.domain.kind!=="categorical")return null;let slots=categoricalSlots.get(axis);if(slots===void 0){slots=new Map(axis.domain.values.map((category,index)=>[category,index]));categoricalSlots.set(axis,slots)}return slots.get(value)??null}const categoricalSlots=new WeakMap;function invalidDefinition(message){return chartFail("construction","chart-definition-invalid",message)}function sameDefinitionMetadata(left,right){if(left.coordinate.kind!==right.coordinate.kind||left.axes.length!==right.axes.length||left.layers.length!==right.layers.length)return false;for(let index=0;index<left.axes.length;index+=1){const a=left.axes[index];const b=right.axes[index];if(a.id!==b.id||a.orientation!==b.orientation||a.scale!==b.scale||a.ticks!==b.ticks||a.label!==b.label||a.unit!==b.unit||!sameAxisDomain(a.domain,b.domain))return false}for(let index=0;index<left.layers.length;index+=1){const a=left.layers[index];const b=right.layers[index];if(a.id!==b.id||a.kind!==b.kind||a.profile!==b.profile||a.label!==b.label||a.xAxis!==b.xAxis||a.yAxis!==b.yAxis||a.projection!==b.projection||a.reduction!==b.reduction||!sameNumbers(a.heatmap?.xEdges,b.heatmap?.xEdges)||!sameNumbers(a.heatmap?.yEdges,b.heatmap?.yEdges))return false}return true}function sameAxisDomain(left,right){if(left.kind!==right.kind)return false;if(left.kind==="categorical"&&right.kind==="categorical"){return left.values.length===right.values.length&&left.values.every((value,index)=>value===right.values[index])}return left.kind!=="categorical"&&right.kind!=="categorical"&&left.minimum===right.minimum&&left.maximum===right.maximum}function sameNumbers(left,right){if(left===right)return true;if(left===void 0||right===void 0||left.length!==right.length)return false;for(let index=0;index<left.length;index+=1)if(!Object.is(left[index],right[index]))return false;return true}function finiteNonNegative(value){return typeof value==="number"&&Number.isFinite(value)&&value>=0}function finitePositive(value){return typeof value==="number"&&Number.isFinite(value)&&value>0}export{createChartDefinition,replaceChartDefinition,tryCreateChartDefinition,tryReplaceChartDefinition};
2
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/definition.ts"],"mappings":"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","names":["data"],"file":"definition.js"}
@@ -0,0 +1,12 @@
1
+ /** Type-only package facade. Runtime consumers import a specific subpath. */
2
+ export type * from './model.js';
3
+ export type * from './result.js';
4
+ export type * from './scale.js';
5
+ export type * from './projection.js';
6
+ export type * from './query.js';
7
+ export type * from './interaction.js';
8
+ export type * from './controller.js';
9
+ export type * from './contract.js';
10
+ export type * from './layout.js';
11
+ export type * from './definition.js';
12
+ export type * from './view.js';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,95 @@
1
+ import type { StableID } from '@sectile/core';
2
+ import { type ChartViewState } from './contract.js';
3
+ import type { ChartModelState } from './model.js';
4
+ import type { ChartResult } from './result.js';
5
+ import { type ChartViewAction, type ChartViewPhase } from './view.js';
6
+ export type ChartSelection<ID extends StableID = StableID> = {
7
+ readonly type: 'points';
8
+ readonly ids: readonly ID[];
9
+ } | {
10
+ readonly type: 'axis-interval';
11
+ readonly axisID: ID;
12
+ readonly start: number;
13
+ readonly end: number;
14
+ } | {
15
+ readonly type: 'domain-region';
16
+ readonly xAxisID: ID;
17
+ readonly xStart: number;
18
+ readonly xEnd: number;
19
+ readonly yAxisID: ID;
20
+ readonly yStart: number;
21
+ readonly yEnd: number;
22
+ };
23
+ export interface ChartState<ID extends StableID = StableID> {
24
+ readonly generation: number;
25
+ readonly activeDatum: ID | null;
26
+ readonly cursor: ID | null;
27
+ readonly selection: ChartSelection<ID>;
28
+ readonly view: ChartViewState<ID> | null;
29
+ }
30
+ export interface ChartControlledValues<ID extends StableID = StableID> {
31
+ readonly activeDatum?: ID | null;
32
+ readonly cursor?: ID | null;
33
+ readonly selection?: ChartSelection<ID>;
34
+ readonly view?: ChartViewState<ID> | null;
35
+ }
36
+ export type ChartEvent<ID extends StableID = StableID> = ChartViewAction<ID> | {
37
+ readonly type: 'pointer-candidate';
38
+ readonly id: ID | null;
39
+ } | {
40
+ readonly type: 'set-active';
41
+ readonly id: ID | null;
42
+ } | {
43
+ readonly type: 'set-cursor';
44
+ readonly id: ID | null;
45
+ } | {
46
+ readonly type: 'set-selection';
47
+ readonly selection: ChartSelection<ID>;
48
+ } | {
49
+ readonly type: 'move-focus';
50
+ readonly direction: 'next' | 'previous' | 'first' | 'last';
51
+ };
52
+ export type ChartCommand<ID extends StableID = StableID> = {
53
+ readonly type: 'focus-datum';
54
+ readonly id: ID;
55
+ } | {
56
+ readonly type: 'announce-datum';
57
+ readonly id: ID;
58
+ } | {
59
+ readonly type: 'active-change-requested';
60
+ readonly id: ID | null;
61
+ } | {
62
+ readonly type: 'cursor-change-requested';
63
+ readonly id: ID | null;
64
+ } | {
65
+ readonly type: 'selection-change-requested';
66
+ readonly selection: ChartSelection<ID>;
67
+ } | {
68
+ readonly type: 'view-change-requested';
69
+ readonly view: ChartViewState<ID>;
70
+ readonly phase: ChartViewPhase;
71
+ } | {
72
+ readonly type: 'view-phase';
73
+ readonly axisID: ID;
74
+ readonly phase: ChartViewPhase;
75
+ readonly changed: boolean;
76
+ } | {
77
+ readonly type: 'render-requested';
78
+ readonly generation: number;
79
+ };
80
+ export interface ChartControlFlags {
81
+ readonly activeDatum?: boolean;
82
+ readonly cursor?: boolean;
83
+ readonly selection?: boolean;
84
+ readonly view?: boolean;
85
+ }
86
+ export interface ChartTransition<ID extends StableID = StableID> {
87
+ readonly state: ChartState<ID>;
88
+ readonly commands: readonly ChartCommand<ID>[];
89
+ readonly changed: boolean;
90
+ }
91
+ export declare function chartSelectionContains<ID extends StableID>(selection: ChartSelection<ID>, id: ID): boolean;
92
+ export declare function createChartState<ID extends StableID>(model: ChartModelState<ID>, controlled?: ChartControlledValues<ID>): ChartState<ID>;
93
+ export declare function tryCreateChartState<ID extends StableID>(model: ChartModelState<ID>, controlled?: ChartControlledValues<ID>): ChartResult<ChartState<ID>>;
94
+ export declare function reconcileChartState<ID extends StableID>(state: ChartState<ID>, model: ChartModelState<ID>, controlled?: ChartControlledValues<ID>): ChartResult<ChartState<ID>>;
95
+ export declare function reduceChartEvent<ID extends StableID>(model: ChartModelState<ID>, state: ChartState<ID>, event: ChartEvent<ID>, controlled?: ChartControlFlags): ChartResult<ChartTransition<ID>>;