tinybase 8.4.2 → 8.5.0-beta.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 (141) hide show
  1. package/@types/ui-react-dom/index.d.ts +10 -10
  2. package/@types/ui-react-dom/with-schemas/index.d.ts +10 -10
  3. package/@types/ui-react-dom-charts/index.d.ts +242 -0
  4. package/@types/ui-react-dom-charts/with-schemas/index.d.ts +296 -0
  5. package/@types/ui-react-inspector/index.d.ts +1 -1
  6. package/@types/ui-react-inspector/with-schemas/index.d.ts +1 -1
  7. package/@types/ui-solid-dom/index.d.ts +10 -10
  8. package/@types/ui-solid-dom/with-schemas/index.d.ts +10 -10
  9. package/@types/ui-solid-inspector/index.d.ts +1 -1
  10. package/@types/ui-solid-inspector/with-schemas/index.d.ts +1 -1
  11. package/@types/ui-svelte-dom/index.d.ts +10 -10
  12. package/@types/ui-svelte-dom/with-schemas/index.d.ts +10 -10
  13. package/@types/ui-svelte-inspector/index.d.ts +1 -1
  14. package/@types/ui-svelte-inspector/with-schemas/index.d.ts +1 -1
  15. package/common/index.js +3 -2
  16. package/common/with-schemas/index.js +3 -2
  17. package/index.js +5 -3
  18. package/mergeable-store/index.js +5 -3
  19. package/mergeable-store/with-schemas/index.js +5 -3
  20. package/metrics/index.js +1 -1
  21. package/metrics/with-schemas/index.js +1 -1
  22. package/min/common/index.js +1 -1
  23. package/min/common/index.js.gz +0 -0
  24. package/min/common/with-schemas/index.js +1 -1
  25. package/min/common/with-schemas/index.js.gz +0 -0
  26. package/min/index.js +1 -1
  27. package/min/index.js.gz +0 -0
  28. package/min/mergeable-store/index.js +1 -1
  29. package/min/mergeable-store/index.js.gz +0 -0
  30. package/min/mergeable-store/with-schemas/index.js +1 -1
  31. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  32. package/min/omni/index.js +1 -1
  33. package/min/omni/index.js.gz +0 -0
  34. package/min/omni/with-schemas/index.js +1 -1
  35. package/min/omni/with-schemas/index.js.gz +0 -0
  36. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  37. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  38. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  39. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  40. package/min/persisters/persister-partykit-server/index.js +1 -1
  41. package/min/persisters/persister-partykit-server/index.js.gz +0 -0
  42. package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
  43. package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
  44. package/min/queries/index.js +1 -1
  45. package/min/queries/index.js.gz +0 -0
  46. package/min/queries/with-schemas/index.js +1 -1
  47. package/min/queries/with-schemas/index.js.gz +0 -0
  48. package/min/synchronizers/index.js +1 -1
  49. package/min/synchronizers/index.js.gz +0 -0
  50. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  51. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  52. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  53. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  54. package/min/synchronizers/synchronizer-local/index.js +1 -1
  55. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  56. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  57. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  58. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  59. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  60. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  61. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  62. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  63. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  64. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  65. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  66. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  67. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  68. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  69. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  70. package/min/synchronizers/with-schemas/index.js +1 -1
  71. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  72. package/min/ui-react-dom/index.js +1 -1
  73. package/min/ui-react-dom/index.js.gz +0 -0
  74. package/min/ui-react-dom/with-schemas/index.js +1 -1
  75. package/min/ui-react-dom/with-schemas/index.js.gz +0 -0
  76. package/min/ui-react-dom-charts/index.js +1 -0
  77. package/min/ui-react-dom-charts/index.js.gz +0 -0
  78. package/min/ui-react-dom-charts/with-schemas/index.js +1 -0
  79. package/min/ui-react-dom-charts/with-schemas/index.js.gz +0 -0
  80. package/min/ui-react-inspector/index.js +1 -1
  81. package/min/ui-react-inspector/index.js.gz +0 -0
  82. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  83. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  84. package/min/ui-solid-dom/index.js +1 -1
  85. package/min/ui-solid-dom/index.js.gz +0 -0
  86. package/min/ui-solid-dom/with-schemas/index.js +1 -1
  87. package/min/ui-solid-dom/with-schemas/index.js.gz +0 -0
  88. package/min/ui-solid-inspector/index.js +1 -1
  89. package/min/ui-solid-inspector/index.js.gz +0 -0
  90. package/min/ui-solid-inspector/with-schemas/index.js +1 -1
  91. package/min/ui-solid-inspector/with-schemas/index.js.gz +0 -0
  92. package/min/ui-svelte-dom/index.js +1 -1
  93. package/min/ui-svelte-dom/index.js.gz +0 -0
  94. package/min/ui-svelte-dom/with-schemas/index.js +1 -1
  95. package/min/ui-svelte-dom/with-schemas/index.js.gz +0 -0
  96. package/min/ui-svelte-inspector/index.js +1 -1
  97. package/min/ui-svelte-inspector/index.js.gz +0 -0
  98. package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
  99. package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
  100. package/min/with-schemas/index.js +1 -1
  101. package/min/with-schemas/index.js.gz +0 -0
  102. package/omni/index.js +7 -4
  103. package/omni/with-schemas/index.js +7 -4
  104. package/package.json +38 -2
  105. package/persisters/persister-durable-object-sql-storage/index.js +13 -11
  106. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +13 -11
  107. package/persisters/persister-partykit-client/index.js +2 -1
  108. package/persisters/persister-partykit-client/with-schemas/index.js +2 -1
  109. package/persisters/persister-partykit-server/index.js +2 -1
  110. package/persisters/persister-partykit-server/with-schemas/index.js +2 -1
  111. package/queries/index.js +1 -1
  112. package/queries/with-schemas/index.js +1 -1
  113. package/readme.md +18 -14
  114. package/releases.md +91 -58
  115. package/synchronizers/index.js +3 -2
  116. package/synchronizers/synchronizer-broadcast-channel/index.js +3 -2
  117. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +3 -2
  118. package/synchronizers/synchronizer-local/index.js +3 -2
  119. package/synchronizers/synchronizer-local/with-schemas/index.js +3 -2
  120. package/synchronizers/synchronizer-ws-client/index.js +3 -2
  121. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +3 -2
  122. package/synchronizers/synchronizer-ws-server/index.js +3 -2
  123. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +3 -2
  124. package/synchronizers/synchronizer-ws-server-durable-object/index.js +3 -2
  125. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +3 -2
  126. package/synchronizers/with-schemas/index.js +3 -2
  127. package/ui-react-dom/index.js +10 -7
  128. package/ui-react-dom/with-schemas/index.js +10 -7
  129. package/ui-react-dom-charts/index.js +1229 -0
  130. package/ui-react-dom-charts/with-schemas/index.js +1229 -0
  131. package/ui-react-inspector/index.js +13 -9
  132. package/ui-react-inspector/with-schemas/index.js +13 -9
  133. package/ui-solid-dom/index.js +10 -7
  134. package/ui-solid-dom/with-schemas/index.js +10 -7
  135. package/ui-solid-inspector/index.js +13 -9
  136. package/ui-solid-inspector/with-schemas/index.js +13 -9
  137. package/ui-svelte-dom/index.js +11 -8
  138. package/ui-svelte-dom/with-schemas/index.js +11 -8
  139. package/ui-svelte-inspector/index.js +17 -13
  140. package/ui-svelte-inspector/with-schemas/index.js +17 -13
  141. package/with-schemas/index.js +5 -3
@@ -0,0 +1,1229 @@
1
+ import React from 'react';
2
+ import {Fragment, jsx, jsxs} from 'react/jsx-runtime';
3
+
4
+ const getTypeOf = (thing) => typeof thing;
5
+ const TINYBASE = 'tinybase';
6
+ const EMPTY_STRING = '';
7
+ const STRING = getTypeOf(EMPTY_STRING);
8
+ const NUMBER = getTypeOf(0);
9
+ const LISTENER = 'Listener';
10
+ const RESULT = 'Result';
11
+ const GET = 'get';
12
+ const ADD = 'add';
13
+ const IDS = 'Ids';
14
+ const ROW = 'Row';
15
+ const SORTED_ROW_IDS = 'Sorted' + ROW + IDS;
16
+ const CELL = 'Cell';
17
+
18
+ const math = Math;
19
+ const getIfNotFunction = (predicate) => (value, then, otherwise) =>
20
+ predicate(value)
21
+ ? /* istanbul ignore next */
22
+ otherwise?.()
23
+ : then(value);
24
+ const GLOBAL = globalThis;
25
+ const number = Number;
26
+ const mathMax = math.max;
27
+ const mathMin = math.min;
28
+ const mathCeil = math.ceil;
29
+ const mathFloor = math.floor;
30
+ const mathPow = math.pow;
31
+ const mathRound = math.round;
32
+ const mathAbs = math.abs;
33
+ const mathLog10 = math.log10;
34
+ const infinity = Infinity;
35
+ const epsilon = Number.EPSILON;
36
+ const isFiniteNumber = isFinite;
37
+ const isInteger = number.isInteger;
38
+ const isNullish = (thing) => thing == null;
39
+ const isUndefined = (thing) => thing === void 0;
40
+ const isNull = (thing) => thing === null;
41
+ const ifNotNullish = getIfNotFunction(isNullish);
42
+ const ifNotUndefined = getIfNotFunction(isUndefined);
43
+ const isString = (thing) => getTypeOf(thing) == STRING;
44
+ const isNumber = (thing) => getTypeOf(thing) == NUMBER;
45
+ const isArray = (thing) => Array.isArray(thing);
46
+ const size = (arrayOrString) => arrayOrString.length;
47
+
48
+ const arrayNew = (size2, cb) =>
49
+ arrayMap(new Array(size2).fill(0), (_, index) => cb(index));
50
+ const arrayIndexOf = (array, value) => array.indexOf(value);
51
+ const arrayEvery = (array, cb) => array.every(cb);
52
+ const arrayIsEqual = (array1, array2) =>
53
+ size(array1) === size(array2) &&
54
+ arrayEvery(array1, (value1, index) => array2[index] === value1);
55
+ const arrayOrValueEqual = (value1, value2) =>
56
+ isArray(value1) && isArray(value2)
57
+ ? arrayIsEqual(value1, value2)
58
+ : value1 === value2;
59
+ const arrayForEach = (array, cb) => array.forEach(cb);
60
+ const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
61
+ const arrayMap = (array, cb) => array.map(cb);
62
+ const arrayIsEmpty = (array) => size(array) == 0;
63
+ const arrayFilter = (array, cb) => array.filter(cb);
64
+
65
+ const {
66
+ PureComponent,
67
+ createContext,
68
+ useCallback,
69
+ useContext,
70
+ useEffect,
71
+ useLayoutEffect,
72
+ useMemo,
73
+ useRef,
74
+ useState,
75
+ useSyncExternalStore,
76
+ } = React;
77
+
78
+ const DEFAULT_SIZE = [1e3, 1e3];
79
+ const DEFAULT_FONT_SIZE = 12;
80
+ const DEFAULT_STYLE = [0.5, 0.5, 0.25, 3.5, 4, 1, 1];
81
+ const useLayout = () => {
82
+ const svgRef = useRef(null);
83
+ const [chartLayout, setChartLayout] = useState([
84
+ DEFAULT_SIZE,
85
+ getDefaultStyle(DEFAULT_FONT_SIZE),
86
+ ]);
87
+ useLayoutEffect(() => {
88
+ const svg = svgRef.current;
89
+ if (isNull(svg)) {
90
+ return;
91
+ }
92
+ const updateLayout = ({contentRect}) => {
93
+ const style = svg.ownerDocument.defaultView?.getComputedStyle(svg);
94
+ const nextLayout = [getSvgSize(contentRect), getStyle(style)];
95
+ setChartLayout((chartLayout2) =>
96
+ isLayoutEqual(chartLayout2, nextLayout) ? chartLayout2 : nextLayout,
97
+ );
98
+ };
99
+ const observer = new ResizeObserver(([entry]) => updateLayout(entry));
100
+ observer.observe(svg);
101
+ return () => observer.disconnect();
102
+ }, []);
103
+ return [svgRef, ...chartLayout];
104
+ };
105
+ const getPlotSize = ([, chartSize, chartStyle]) => {
106
+ const [, , width, height] = getPlotFrame(chartSize, chartStyle);
107
+ return [width, height];
108
+ };
109
+ const getLabelSize = ([, , chartStyle]) => chartStyle[6];
110
+ const getPlotFrame = (
111
+ [width, height],
112
+ [, , , xAxisHeight, yAxisWidth, inset, fontSize],
113
+ ) => {
114
+ const plotX = inset + mathMax(mathMin(yAxisWidth, width / 2 - 2 * inset), 0);
115
+ const plotY = inset + fontSize / 2;
116
+ const plotRight = inset + fontSize / 2;
117
+ const plotHeight = mathMax(
118
+ height -
119
+ plotY -
120
+ mathMax(mathMin(xAxisHeight, height / 2 - plotY - inset), 0) -
121
+ inset,
122
+ 0,
123
+ );
124
+ return [plotX, plotY, mathMax(width - plotX - plotRight, 0), plotHeight];
125
+ };
126
+ const getDefaultStyle = (fontSize) =>
127
+ arrayMap(DEFAULT_STYLE, (value) => value * fontSize);
128
+ const getStyle = (style) => {
129
+ const fontSize = parseFloat(style?.fontSize ?? '');
130
+ return getDefaultStyle(
131
+ isFiniteNumber(fontSize) ? fontSize : DEFAULT_FONT_SIZE,
132
+ );
133
+ };
134
+ const getSvgSize = ({width, height}) => [
135
+ mathRound(width) || DEFAULT_SIZE[0],
136
+ mathRound(height) || DEFAULT_SIZE[1],
137
+ ];
138
+ const isLayoutEqual = ([chartSize1, chartStyle1], [chartSize2, chartStyle2]) =>
139
+ arrayIsEqual(chartSize1, chartSize2) &&
140
+ arrayIsEqual(chartStyle1, chartStyle2);
141
+
142
+ const CURRENT_COLOR = 'currentColor';
143
+
144
+ const collSize = (coll) => coll?.size ?? 0;
145
+
146
+ const NICE_NUMBERS = [1, 5, 2, 2.5, 4, 3];
147
+ const WEIGHTS = [0.25, 0.2, 0.5, 0.05];
148
+ const getTicks = (
149
+ min,
150
+ max,
151
+ targetTickCount,
152
+ labelSize,
153
+ axisSize,
154
+ integerTicks,
155
+ ) => {
156
+ let bestTicks = [min, max];
157
+ let bestScore = -2;
158
+ const range = max - min;
159
+ for (let j = 1; j < infinity; j++) {
160
+ for (const niceNumber of NICE_NUMBERS) {
161
+ const simplicityMax =
162
+ 1 -
163
+ arrayIndexOf(NICE_NUMBERS, niceNumber) /
164
+ mathMax(size(NICE_NUMBERS) - 1, 1) -
165
+ j +
166
+ 1;
167
+ if (
168
+ WEIGHTS[0] * simplicityMax + WEIGHTS[1] + WEIGHTS[2] + WEIGHTS[3] <
169
+ bestScore
170
+ ) {
171
+ return bestTicks;
172
+ }
173
+ for (let tickCount = 2; tickCount < infinity; tickCount++) {
174
+ const densityMax =
175
+ tickCount >= targetTickCount
176
+ ? 2 - (tickCount - 1) / (targetTickCount - 1)
177
+ : 1;
178
+ if (
179
+ WEIGHTS[0] * simplicityMax +
180
+ WEIGHTS[1] +
181
+ WEIGHTS[2] * densityMax +
182
+ WEIGHTS[3] <
183
+ bestScore
184
+ ) {
185
+ break;
186
+ }
187
+ for (
188
+ let exponent = mathCeil(
189
+ mathLog10(range / (tickCount + 1) / j / niceNumber),
190
+ );
191
+ exponent < infinity;
192
+ exponent++
193
+ ) {
194
+ const step = j * niceNumber * mathPow(10, exponent);
195
+ if (
196
+ WEIGHTS[0] * simplicityMax +
197
+ WEIGHTS[1] *
198
+ (step * (tickCount - 1) <= max - min
199
+ ? 1
200
+ : 1 -
201
+ mathPow((step * (tickCount - 1) - (max - min)) / 2, 2) /
202
+ mathPow(0.1 * (max - min), 2)) +
203
+ WEIGHTS[2] * densityMax +
204
+ WEIGHTS[3] <
205
+ bestScore
206
+ ) {
207
+ break;
208
+ }
209
+ const minStart = mathFloor(max / step) * j - (tickCount - 1) * j;
210
+ const maxStart = mathCeil(min / step) * j;
211
+ if (minStart <= maxStart) {
212
+ arrayForEach(
213
+ arrayNew(maxStart - minStart + 1, (index) => minStart + index),
214
+ (start) => {
215
+ const tickMin = start * (step / j);
216
+ const tickMax = tickMin + step * (tickCount - 1);
217
+ const density = (tickCount - 1) / (tickMax - tickMin);
218
+ const targetDensity =
219
+ (targetTickCount - 1) /
220
+ (mathMax(tickMax, max) - mathMin(min, tickMin));
221
+ const spacing = axisSize / (tickCount - 1);
222
+ const score =
223
+ WEIGHTS[0] *
224
+ (1 -
225
+ arrayIndexOf(NICE_NUMBERS, niceNumber) /
226
+ mathMax(size(NICE_NUMBERS) - 1, 1) -
227
+ j +
228
+ (mathAbs(tickMin / step - mathRound(tickMin / step)) <
229
+ epsilon * 100 &&
230
+ tickMin <= 0 &&
231
+ tickMax >= 0
232
+ ? 1
233
+ : 0)) +
234
+ WEIGHTS[1] *
235
+ (1 -
236
+ (mathPow(max - tickMax, 2) + mathPow(min - tickMin, 2)) /
237
+ (2 * mathPow(0.1 * (max - min), 2))) +
238
+ WEIGHTS[2] *
239
+ (2 -
240
+ mathMax(
241
+ density / targetDensity,
242
+ targetDensity / density,
243
+ )) +
244
+ WEIGHTS[3] *
245
+ (spacing < labelSize * 1.2
246
+ ? -infinity
247
+ : mathMin(spacing, 1)) +
248
+ (integerTicks &&
249
+ (mathAbs(step - mathRound(step)) > epsilon * 100 ||
250
+ mathAbs(tickMin - mathRound(tickMin)) > epsilon * 100)
251
+ ? -1
252
+ : 0);
253
+ if (score > bestScore) {
254
+ bestTicks = arrayNew(
255
+ mathFloor((tickMax - tickMin) / step + 0.5) + 1,
256
+ (index) => mathRound((tickMin + index * step) * 1e6) / 1e6,
257
+ );
258
+ bestScore = score;
259
+ }
260
+ },
261
+ );
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+ return bestTicks;
268
+ };
269
+
270
+ const TARGET_TICKS = 10;
271
+ const getDataPoints = (rowIds, getPoint) =>
272
+ arrayFilter(arrayMap(rowIds, getPoint), (point) => !isUndefined(point));
273
+ const getDataPoint = (rowId, xCell, yCell) => {
274
+ const xValue = getXValue(xCell);
275
+ const yValue = getYValue(yCell);
276
+ return isUndefined(xValue) || isUndefined(yValue)
277
+ ? void 0
278
+ : [rowId, xValue, yValue];
279
+ };
280
+ const getScaledPoints = (
281
+ kind,
282
+ points,
283
+ [xMin, xMax, yMin, yMax],
284
+ [width, height],
285
+ ) => {
286
+ const numericX =
287
+ kind == 'line' &&
288
+ arrayIsEmpty(arrayFilter(points, ([, xValue]) => !isNumber(xValue)));
289
+ const xDomain = numericX ? [xMin, xMax] : [0, 0];
290
+ const yDomain = [yMin ?? 0, yMax ?? 0];
291
+ const xCategories = /* @__PURE__ */ new Map();
292
+ arrayForEach(points, ([, xValue]) => {
293
+ if (!xCategories.has(xValue)) {
294
+ xCategories.set(xValue, collSize(xCategories));
295
+ }
296
+ });
297
+ return arrayMap(points, ([rowId, xValue, yValue]) => [
298
+ rowId,
299
+ xValue,
300
+ yValue,
301
+ getX(xValue, numericX, xDomain, xCategories, width, kind),
302
+ getY(yValue, yDomain, height),
303
+ ]);
304
+ };
305
+ const getX = (xValue, numericX, [xMin, xMax], xCategories, width, kind) =>
306
+ numericX
307
+ ? getScale(xValue, xMin, xMax, width)
308
+ : kind == 'bar'
309
+ ? (width * ((xCategories.get(xValue) ?? 0) + 0.5)) / collSize(xCategories)
310
+ : getScale(
311
+ xCategories.get(xValue) ?? 0,
312
+ 0,
313
+ collSize(xCategories) - 1,
314
+ width,
315
+ );
316
+ const getY = (yValue, [yMin, yMax], height) =>
317
+ height - getScale(yValue, yMin, yMax, height);
318
+ const getScale = (value, min, max, size2) =>
319
+ min == max ? size2 / 2 : getRounded((size2 * (value - min)) / (max - min));
320
+ const getBounds = (kind, points) => {
321
+ if (arrayIsEmpty(points)) {
322
+ return [];
323
+ }
324
+ const [yMin, yMax] = getYDomain(points, kind);
325
+ if (arrayIsEmpty(arrayFilter(points, ([, xValue]) => !isNumber(xValue)))) {
326
+ const [xMin, xMax] = getDomain(arrayMap(points, ([, xValue]) => xValue));
327
+ return [xMin, xMax, yMin, yMax];
328
+ }
329
+ return [points[0]?.[1], points[size(points) - 1]?.[1], yMin, yMax];
330
+ };
331
+ const getYTicks = ([, , yMin, yMax], [, height], labelSize) => {
332
+ if (isUndefined(yMin) || isUndefined(yMax)) {
333
+ return [];
334
+ }
335
+ if (yMin == yMax) {
336
+ return [yMin];
337
+ }
338
+ return getTicks(
339
+ yMin,
340
+ yMax,
341
+ TARGET_TICKS,
342
+ labelSize,
343
+ height,
344
+ isInteger(yMin) && isInteger(yMax),
345
+ );
346
+ };
347
+ const getXTicks = (kind, [xMin, xMax], [width], labelSize) =>
348
+ kind == 'line' && isNumber(xMin) && isNumber(xMax) && xMin != xMax
349
+ ? getTicks(
350
+ xMin,
351
+ xMax,
352
+ TARGET_TICKS,
353
+ labelSize,
354
+ width,
355
+ isInteger(xMin) && isInteger(xMax),
356
+ )
357
+ : [];
358
+ const getTickBounds = ([xMin, xMax, yMin, yMax], xTicks, yTicks) => [
359
+ arrayIsEmpty(xTicks) ? xMin : mathMin(xMin, xTicks[0]),
360
+ arrayIsEmpty(xTicks) ? xMax : mathMax(xMax, xTicks[size(xTicks) - 1]),
361
+ arrayIsEmpty(yTicks) ? yMin : mathMin(yMin ?? infinity, yTicks[0]),
362
+ arrayIsEmpty(yTicks)
363
+ ? yMax
364
+ : mathMax(yMax ?? -infinity, yTicks[size(yTicks) - 1]),
365
+ ];
366
+ const getYDomain = (points, kind = 'bar') =>
367
+ getDomain([
368
+ ...(kind == 'bar' ? [0] : []),
369
+ ...arrayMap(points, ([, , yValue]) => yValue),
370
+ ]);
371
+ const getDomain = (values) => {
372
+ const min = mathMin(...values);
373
+ return min == infinity ? [0, 0] : [min, mathMax(...values)];
374
+ };
375
+ const getRounded = (value) => mathRound(value * 1e6) / 1e6;
376
+ const getXValue = (cell) =>
377
+ isNumber(cell)
378
+ ? isFiniteNumber(cell)
379
+ ? cell
380
+ : void 0
381
+ : isString(cell)
382
+ ? cell
383
+ : void 0;
384
+ const getYValue = (cell) =>
385
+ isNumber(cell) && isFiniteNumber(cell) ? cell : void 0;
386
+
387
+ const XAxis = ({
388
+ points,
389
+ xTicks,
390
+ xMin,
391
+ xMax,
392
+ xTitle,
393
+ plotFrame,
394
+ tickSize,
395
+ tickGap,
396
+ axisHeight,
397
+ fontSize,
398
+ }) => {
399
+ const [plotX, plotY, plotWidth, plotHeight] = plotFrame;
400
+ const titleGap = mathMax(axisHeight - tickSize - tickGap - 2 * fontSize, 0);
401
+ return /* @__PURE__ */ jsxs('g', {
402
+ className: 'x',
403
+ dominantBaseline: 'hanging',
404
+ textAnchor: 'middle',
405
+ children: [
406
+ /* @__PURE__ */ jsx('path', {
407
+ className: 'line',
408
+ d: `M${plotX},${plotY + plotHeight}h${plotWidth}`,
409
+ fill: 'none',
410
+ stroke: CURRENT_COLOR,
411
+ strokeOpacity: 0.5,
412
+ strokeWidth: 1,
413
+ }),
414
+ /* @__PURE__ */ jsx('g', {
415
+ className: 'ticks',
416
+ children:
417
+ arrayIsEmpty(xTicks) || !isNumber(xMin) || !isNumber(xMax)
418
+ ? arrayMap(points, ([rowId, xValue, , x]) =>
419
+ /* @__PURE__ */ jsx(
420
+ 'text',
421
+ {
422
+ x: plotX + x,
423
+ y: plotY + plotHeight + tickSize + tickGap,
424
+ children: xValue,
425
+ },
426
+ rowId,
427
+ ),
428
+ )
429
+ : arrayMap(xTicks, (tick) => {
430
+ const x = getScale(tick, xMin, xMax, plotWidth);
431
+ return /* @__PURE__ */ jsx(
432
+ 'text',
433
+ {
434
+ x: plotX + x,
435
+ y: plotY + plotHeight + tickSize + tickGap,
436
+ children: tick,
437
+ },
438
+ tick,
439
+ );
440
+ }),
441
+ }),
442
+ /* @__PURE__ */ jsx('text', {
443
+ className: 'title',
444
+ x: plotX + plotWidth / 2,
445
+ y: plotY + plotHeight + tickSize + tickGap + fontSize + titleGap,
446
+ children: xTitle,
447
+ }),
448
+ ],
449
+ });
450
+ };
451
+
452
+ const YAxis = ({
453
+ yTicks,
454
+ yMin,
455
+ yMax,
456
+ yTitle,
457
+ plotFrame,
458
+ tickSize,
459
+ tickGap,
460
+ axisWidth,
461
+ }) => {
462
+ const [plotX, plotY, , plotHeight] = plotFrame;
463
+ return isNullish(yMin) || isNullish(yMax)
464
+ ? null
465
+ : /* @__PURE__ */ jsxs('g', {
466
+ className: 'y',
467
+ children: [
468
+ /* @__PURE__ */ jsx('path', {
469
+ className: 'line',
470
+ d: `M${plotX},${plotY}v${plotHeight}`,
471
+ fill: 'none',
472
+ stroke: CURRENT_COLOR,
473
+ strokeOpacity: 0.5,
474
+ strokeWidth: 1,
475
+ }),
476
+ /* @__PURE__ */ jsx('g', {
477
+ className: 'ticks',
478
+ dominantBaseline: 'middle',
479
+ textAnchor: 'end',
480
+ children: arrayMap(yTicks, (tick) => {
481
+ const y = plotHeight - getScale(tick, yMin, yMax, plotHeight);
482
+ return /* @__PURE__ */ jsx(
483
+ 'text',
484
+ {x: plotX - tickSize - tickGap, y: plotY + y, children: tick},
485
+ tick,
486
+ );
487
+ }),
488
+ }),
489
+ /* @__PURE__ */ jsx('text', {
490
+ className: 'title',
491
+ dominantBaseline: 'text-before-edge',
492
+ textAnchor: 'middle',
493
+ transform: `translate(${plotX - axisWidth} ${plotFrame[1] + plotFrame[3] / 2}) rotate(-90)`,
494
+ children: yTitle,
495
+ }),
496
+ ],
497
+ });
498
+ };
499
+
500
+ const Axes = ({
501
+ points,
502
+ xTicks,
503
+ yTicks,
504
+ bounds: [xMin, xMax, yMin, yMax],
505
+ titles: [xTitle, yTitle],
506
+ xAxisHeight,
507
+ yAxisWidth,
508
+ fontSize,
509
+ ...sharedProps
510
+ }) => {
511
+ return /* @__PURE__ */ jsxs('g', {
512
+ className: 'axes',
513
+ fill: CURRENT_COLOR,
514
+ fillOpacity: 0.75,
515
+ children: [
516
+ /* @__PURE__ */ jsx(YAxis, {
517
+ ...sharedProps,
518
+ yTicks,
519
+ yMin,
520
+ yMax,
521
+ yTitle,
522
+ axisWidth: yAxisWidth,
523
+ }),
524
+ /* @__PURE__ */ jsx(XAxis, {
525
+ ...sharedProps,
526
+ points,
527
+ xTicks,
528
+ xMin,
529
+ xMax,
530
+ xTitle,
531
+ axisHeight: xAxisHeight,
532
+ fontSize,
533
+ }),
534
+ ],
535
+ });
536
+ };
537
+
538
+ const Grid = ({
539
+ points,
540
+ xTicks,
541
+ yTicks,
542
+ bounds: [xMin, xMax, yMin, yMax],
543
+ plotFrame,
544
+ tickSize,
545
+ }) => {
546
+ const [plotX, plotY, width, height] = plotFrame;
547
+ return /* @__PURE__ */ jsxs('g', {
548
+ className: 'grid',
549
+ stroke: CURRENT_COLOR,
550
+ strokeOpacity: 0.75,
551
+ strokeWidth: 0.5,
552
+ children: [
553
+ isNullish(yMin) || isNullish(yMax)
554
+ ? null
555
+ : /* @__PURE__ */ jsx('path', {
556
+ className: 'y',
557
+ d: arrayJoin(
558
+ arrayMap(
559
+ arrayFilter(
560
+ yTicks,
561
+ (tick) => getScale(tick, yMin, yMax, height) != 0,
562
+ ),
563
+ (tick) =>
564
+ `M${plotX - tickSize},${plotY + height - getScale(tick, yMin, yMax, height)}h${width + tickSize}`,
565
+ ),
566
+ ' ',
567
+ ),
568
+ }),
569
+ arrayIsEmpty(xTicks) || !isNumber(xMin) || !isNumber(xMax)
570
+ ? /* @__PURE__ */ jsx('path', {
571
+ className: 'x',
572
+ d: arrayJoin(
573
+ arrayMap(
574
+ arrayFilter(points, ([, , , x]) => x != 0),
575
+ ([, , , x]) => `M${plotX + x},${plotY}v${height + tickSize}`,
576
+ ),
577
+ ' ',
578
+ ),
579
+ })
580
+ : /* @__PURE__ */ jsx('path', {
581
+ className: 'x',
582
+ d: arrayJoin(
583
+ arrayMap(
584
+ arrayFilter(
585
+ xTicks,
586
+ (tick) => getScale(tick, xMin, xMax, width) != 0,
587
+ ),
588
+ (tick) =>
589
+ `M${plotX + getScale(tick, xMin, xMax, width)},${plotY}v${height + tickSize}`,
590
+ ),
591
+ ' ',
592
+ ),
593
+ }),
594
+ ],
595
+ });
596
+ };
597
+
598
+ const Marks = ({getMark, points, setTooltipPoint}) =>
599
+ arrayMap(points, (point, index) => {
600
+ const [rowId] = point;
601
+ return /* @__PURE__ */ jsx(
602
+ 'g',
603
+ {
604
+ onPointerEnter: () => setTooltipPoint(point),
605
+ onPointerLeave: () => setTooltipPoint(void 0),
606
+ children: getMark(point, index),
607
+ },
608
+ rowId,
609
+ );
610
+ });
611
+
612
+ const Bars = ({
613
+ points,
614
+ plotFrame,
615
+ barGap,
616
+ setTooltipPoint,
617
+ yMin = 0,
618
+ yMax = 0,
619
+ }) => {
620
+ const [plotX, plotY, width, height] = plotFrame;
621
+ const baselineY = height - getScale(0, yMin, yMax, height);
622
+ const pointsSize = size(points);
623
+ const fullBarWidth = arrayIsEmpty(points) ? 0 : width / pointsSize;
624
+ const barWidth = arrayIsEmpty(points) ? 0 : mathMax(fullBarWidth - barGap, 0);
625
+ return /* @__PURE__ */ jsx(Marks, {
626
+ points,
627
+ getMark: ([, , , x, pointY]) => {
628
+ const y = mathMin(pointY, baselineY);
629
+ return /* @__PURE__ */ jsx('rect', {
630
+ className: 'bar',
631
+ fill: CURRENT_COLOR,
632
+ x: plotX + x - barWidth / 2,
633
+ y: plotY + y,
634
+ width: barWidth,
635
+ height: mathAbs(baselineY - pointY),
636
+ });
637
+ },
638
+ setTooltipPoint,
639
+ });
640
+ };
641
+
642
+ const Line = ({plotFrame, points, setTooltipPoint}) => {
643
+ const [plotX, plotY, , height] = plotFrame;
644
+ return /* @__PURE__ */ jsxs(Fragment, {
645
+ children: [
646
+ /* @__PURE__ */ jsx('path', {
647
+ className: 'area',
648
+ d: getAreaPath(points, plotX, plotY, height),
649
+ fill: CURRENT_COLOR,
650
+ fillOpacity: 0.25,
651
+ stroke: 'none',
652
+ }),
653
+ /* @__PURE__ */ jsx('path', {
654
+ className: 'line',
655
+ d: getLinePath(points, plotX, plotY),
656
+ fill: 'none',
657
+ stroke: CURRENT_COLOR,
658
+ strokeOpacity: 0.75,
659
+ strokeWidth: 2,
660
+ }),
661
+ /* @__PURE__ */ jsx('g', {
662
+ className: 'points',
663
+ fill: CURRENT_COLOR,
664
+ children: arrayMap(points, (point) => {
665
+ const [rowId, , , x, y] = point;
666
+ return /* @__PURE__ */ jsx(
667
+ 'circle',
668
+ {
669
+ cx: plotX + x,
670
+ cy: plotY + y,
671
+ onPointerEnter: () => setTooltipPoint(point),
672
+ onPointerLeave: () => setTooltipPoint(void 0),
673
+ r: 5,
674
+ },
675
+ rowId,
676
+ );
677
+ }),
678
+ }),
679
+ ],
680
+ });
681
+ };
682
+ const getLinePath = (points, plotX, plotY) =>
683
+ arrayJoin(
684
+ arrayMap(
685
+ points,
686
+ ([, , , x, y], index) =>
687
+ `${index == 0 ? 'M' : 'L'}${plotX + x},${plotY + y}`,
688
+ ),
689
+ ' ',
690
+ );
691
+ const getAreaPath = (points, plotX, plotY, height) =>
692
+ arrayIsEmpty(points)
693
+ ? ''
694
+ : `${getLinePath(points, plotX, plotY)} L${plotX + points[size(points) - 1][3]},${plotY + height} L${plotX + points[0][3]},${plotY + height} Z`;
695
+
696
+ const Plot = ({
697
+ kind,
698
+ points,
699
+ plotFrame,
700
+ barGap,
701
+ setTooltipPoint,
702
+ bounds: [, , yMin, yMax],
703
+ }) => {
704
+ const sharedProps = {points, setTooltipPoint};
705
+ return /* @__PURE__ */ jsx('g', {
706
+ className: 'plot',
707
+ children:
708
+ kind == 'line'
709
+ ? /* @__PURE__ */ jsx(Line, {...sharedProps, plotFrame})
710
+ : /* @__PURE__ */ jsx(Bars, {
711
+ ...sharedProps,
712
+ plotFrame,
713
+ barGap,
714
+ yMin,
715
+ yMax,
716
+ }),
717
+ });
718
+ };
719
+
720
+ const TOOLTIP_WIDTH = 160;
721
+ const TOOLTIP_HEIGHT = 60;
722
+ const TOOLTIP_GAP = 12;
723
+ const TOOLTIP_PADDING = 12;
724
+ const Tooltip = ({
725
+ point,
726
+ width,
727
+ height,
728
+ plotFrame,
729
+ titles: [xTitle, yTitle],
730
+ }) => {
731
+ if (isNullish(point)) {
732
+ return null;
733
+ }
734
+ const [, xValue, yValue, x, y] = point;
735
+ const [plotX, plotY] = plotFrame;
736
+ const tooltipX =
737
+ x + TOOLTIP_GAP + TOOLTIP_WIDTH > width
738
+ ? x - TOOLTIP_GAP - TOOLTIP_WIDTH
739
+ : x + TOOLTIP_GAP;
740
+ const tooltipY = mathMax(
741
+ mathMin(y - TOOLTIP_GAP - TOOLTIP_HEIGHT, height - TOOLTIP_HEIGHT),
742
+ 0,
743
+ );
744
+ return /* @__PURE__ */ jsxs(Fragment, {
745
+ children: [
746
+ /* @__PURE__ */ jsx('path', {
747
+ className: 'tooltip-lines',
748
+ pointerEvents: 'none',
749
+ stroke: CURRENT_COLOR,
750
+ strokeOpacity: 0.25,
751
+ strokeWidth: 1,
752
+ d: `M${plotX + x},${plotY}v${height}M${plotX},${plotY + y}h${width}`,
753
+ }),
754
+ /* @__PURE__ */ jsxs('g', {
755
+ className: 'tooltip',
756
+ transform: `translate(${plotX + tooltipX} ${plotY + tooltipY})`,
757
+ fill: CURRENT_COLOR,
758
+ children: [
759
+ /* @__PURE__ */ jsx('rect', {
760
+ fillOpacity: 0.25,
761
+ width: TOOLTIP_WIDTH,
762
+ height: TOOLTIP_HEIGHT,
763
+ rx: 4,
764
+ }),
765
+ /* @__PURE__ */ jsxs('text', {
766
+ x: TOOLTIP_PADDING,
767
+ y: 22,
768
+ children: [xTitle, ': ', xValue],
769
+ }),
770
+ /* @__PURE__ */ jsxs('text', {
771
+ x: TOOLTIP_PADDING,
772
+ y: 46,
773
+ children: [yTitle, ': ', yValue],
774
+ }),
775
+ ],
776
+ }),
777
+ ],
778
+ });
779
+ };
780
+
781
+ const Layout = ({
782
+ className,
783
+ kind,
784
+ titles,
785
+ layout: [svgRef, chartSize, chartStyle],
786
+ ...sharedProps
787
+ }) => {
788
+ const [width, height] = chartSize;
789
+ const plotFrame = getPlotFrame(chartSize, chartStyle);
790
+ const [, , plotWidth, plotHeight] = plotFrame;
791
+ const [tickSize, tickGap, barGap, xAxisHeight, yAxisWidth, , fontSize] =
792
+ chartStyle;
793
+ const [tooltipPoint, setTooltipPoint] = useState();
794
+ const chartProps = {...sharedProps, plotFrame};
795
+ return /* @__PURE__ */ jsxs('svg', {
796
+ className,
797
+ preserveAspectRatio: 'none',
798
+ ref: svgRef,
799
+ viewBox: `0 0 ${width} ${height}`,
800
+ children: [
801
+ /* @__PURE__ */ jsx(Grid, {...chartProps, tickSize}),
802
+ /* @__PURE__ */ jsx(Axes, {
803
+ ...chartProps,
804
+ titles,
805
+ tickSize,
806
+ tickGap,
807
+ xAxisHeight,
808
+ yAxisWidth,
809
+ fontSize,
810
+ }),
811
+ /* @__PURE__ */ jsx(Plot, {
812
+ ...chartProps,
813
+ kind,
814
+ barGap,
815
+ setTooltipPoint,
816
+ }),
817
+ /* @__PURE__ */ jsx(Tooltip, {
818
+ point: tooltipPoint,
819
+ width: plotWidth,
820
+ height: plotHeight,
821
+ plotFrame,
822
+ titles,
823
+ }),
824
+ ],
825
+ });
826
+ };
827
+
828
+ const EmptyChart = ({className, kind, xCellId, yCellId}) => {
829
+ const layout = useLayout();
830
+ return /* @__PURE__ */ jsx(Layout, {
831
+ className,
832
+ kind,
833
+ points: [],
834
+ bounds: [],
835
+ titles: [xCellId, yCellId],
836
+ xTicks: [],
837
+ yTicks: [],
838
+ layout,
839
+ });
840
+ };
841
+
842
+ const object = Object;
843
+ const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
844
+ const objEntries = object.entries;
845
+ const isObject = (obj) =>
846
+ !isNullish(obj) &&
847
+ ifNotNullish(
848
+ getPrototypeOf(obj),
849
+ (objPrototype) =>
850
+ objPrototype == object.prototype ||
851
+ isNullish(getPrototypeOf(objPrototype)),
852
+
853
+ /* istanbul ignore next */
854
+ () => true,
855
+ );
856
+ const objIds = object.keys;
857
+ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
858
+ const objSize = (obj) => size(objIds(obj));
859
+
860
+ /* istanbul ignore next */
861
+ const objIsEqual = (
862
+ obj1,
863
+ obj2,
864
+ isEqual = (value1, value2) => value1 === value2,
865
+ ) => {
866
+ const entries1 = objEntries(obj1);
867
+ return (
868
+ size(entries1) === objSize(obj2) &&
869
+ arrayEvery(entries1, ([index, value1]) =>
870
+ isObject(value1)
871
+ ? /* istanbul ignore next */
872
+ isObject(obj2[index])
873
+ ? objIsEqual(obj2[index], value1, isEqual)
874
+ : false
875
+ : isEqual(value1, obj2[index]),
876
+ )
877
+ );
878
+ };
879
+
880
+ const jsonString = JSON.stringify;
881
+
882
+ const TINYBASE_CONTEXT = TINYBASE + '_uirc';
883
+ const Context = GLOBAL[TINYBASE_CONTEXT]
884
+ ? /* istanbul ignore next */
885
+ GLOBAL[TINYBASE_CONTEXT]
886
+ : (GLOBAL[TINYBASE_CONTEXT] = createContext([]));
887
+ const useThing = (id, offset) => {
888
+ const contextValue = useContext(Context);
889
+ return isUndefined(id)
890
+ ? contextValue[offset * 2]
891
+ : isString(id)
892
+ ? objGet(contextValue[offset * 2 + 1], id)
893
+ : id;
894
+ };
895
+ const useThingOrThingById = (thingOrThingId, offset) => {
896
+ const thing = useThing(thingOrThingId, offset);
897
+ return isUndefined(thingOrThingId) || isString(thingOrThingId)
898
+ ? thing
899
+ : thingOrThingId;
900
+ };
901
+
902
+ const OFFSET_STORE = 0;
903
+ const OFFSET_QUERIES = 4;
904
+
905
+ const EMPTY_ARRAY = [];
906
+ const DEFAULTS = [
907
+ {},
908
+ [],
909
+ [EMPTY_ARRAY, void 0, EMPTY_ARRAY],
910
+ {},
911
+ void 0,
912
+ void 0,
913
+ false,
914
+ 0,
915
+ ];
916
+ const cellOrValueEqual = (thing1, thing2) =>
917
+ thing1 === thing2 ||
918
+ ((isObject(thing1) || isArray(thing1)) &&
919
+ jsonString(thing1) === jsonString(thing2));
920
+ const IS_EQUALS = [
921
+ (obj1, obj2) => objIsEqual(obj1, obj2, cellOrValueEqual),
922
+ arrayIsEqual,
923
+ (
924
+ [backwardIds1, currentId1, forwardIds1],
925
+ [backwardIds2, currentId2, forwardIds2],
926
+ ) =>
927
+ currentId1 === currentId2 &&
928
+ arrayIsEqual(backwardIds1, backwardIds2) &&
929
+ arrayIsEqual(forwardIds1, forwardIds2),
930
+ (paramValues1, paramValues2) =>
931
+ objIsEqual(paramValues1, paramValues2, arrayOrValueEqual),
932
+ arrayOrValueEqual,
933
+ cellOrValueEqual,
934
+ ];
935
+ const isEqual = (thing1, thing2) => thing1 === thing2;
936
+ const addAndDelListener = (thing, listenable, ...args) => {
937
+ const listenerId = thing?.[ADD + listenable + LISTENER]?.(...args);
938
+ return () => thing?.delListener?.(listenerId);
939
+ };
940
+ const useListenable = (listenable, thing, returnType, args = EMPTY_ARRAY) => {
941
+ const lastResultRef = useRef(DEFAULTS[returnType]);
942
+ const getResult = useCallback(
943
+ () => {
944
+ const nextResult =
945
+ thing?.[GET + listenable]?.(...args) ?? DEFAULTS[returnType];
946
+ return !(IS_EQUALS[returnType] ?? isEqual)(
947
+ nextResult,
948
+ lastResultRef.current,
949
+ )
950
+ ? (lastResultRef.current = nextResult)
951
+ : lastResultRef.current;
952
+ },
953
+ /* eslint-disable-next-line react-hooks/exhaustive-deps */
954
+ [thing, returnType, listenable, ...args],
955
+ );
956
+ const subscribe = useCallback(
957
+ (listener) =>
958
+ addAndDelListener(thing, EMPTY_STRING + listenable, ...args, listener),
959
+ /* eslint-disable-next-line react-hooks/exhaustive-deps */
960
+ [thing, returnType, listenable, ...args],
961
+ );
962
+ return useSyncExternalStore(subscribe, getResult, getResult);
963
+ };
964
+ const useListener = (
965
+ listenable,
966
+ thing,
967
+ listener,
968
+ listenerDeps = EMPTY_ARRAY,
969
+ preArgs = EMPTY_ARRAY,
970
+ ...postArgs
971
+ ) =>
972
+ useLayoutEffect(
973
+ () =>
974
+ addAndDelListener(thing, listenable, ...preArgs, listener, ...postArgs),
975
+ // eslint-disable-next-line react-hooks/exhaustive-deps
976
+ [thing, listenable, ...preArgs, ...listenerDeps, ...postArgs],
977
+ );
978
+ const useSortedRowIdsImpl = (
979
+ tableId,
980
+ cellId,
981
+ descending,
982
+ offset,
983
+ limit,
984
+ storeOrStoreId,
985
+ ) =>
986
+ useListenable(
987
+ SORTED_ROW_IDS,
988
+ useStoreOrStoreById(storeOrStoreId),
989
+ 1 /* Array */,
990
+ [tableId, cellId, descending, offset, limit],
991
+ );
992
+ const useStoreOrStoreById = (storeOrStoreId) =>
993
+ useThingOrThingById(storeOrStoreId, OFFSET_STORE);
994
+ const useSortedRowIds = (
995
+ tableIdOrArgs,
996
+ cellIdOrStoreOrStoreId,
997
+ descending,
998
+ offset,
999
+ limit,
1000
+ storeOrStoreId,
1001
+ ) =>
1002
+ useSortedRowIdsImpl(
1003
+ ...(isObject(tableIdOrArgs)
1004
+ ? [
1005
+ tableIdOrArgs.tableId,
1006
+ tableIdOrArgs.cellId,
1007
+ tableIdOrArgs.descending ?? false,
1008
+ tableIdOrArgs.offset ?? 0,
1009
+ tableIdOrArgs.limit,
1010
+ cellIdOrStoreOrStoreId,
1011
+ ]
1012
+ : [
1013
+ tableIdOrArgs,
1014
+ cellIdOrStoreOrStoreId,
1015
+ descending,
1016
+ offset,
1017
+ limit,
1018
+ storeOrStoreId,
1019
+ ]),
1020
+ );
1021
+ const useCellListener = (
1022
+ tableId,
1023
+ rowId,
1024
+ cellId,
1025
+ listener,
1026
+ listenerDeps,
1027
+ mutator,
1028
+ storeOrStoreId,
1029
+ ) =>
1030
+ useListener(
1031
+ CELL,
1032
+ useStoreOrStoreById(storeOrStoreId),
1033
+ listener,
1034
+ listenerDeps,
1035
+ [tableId, rowId, cellId],
1036
+ mutator,
1037
+ );
1038
+ const useQueriesOrQueriesById = (queriesOrQueriesId) =>
1039
+ useThingOrThingById(queriesOrQueriesId, OFFSET_QUERIES);
1040
+ const useResultSortedRowIds = (
1041
+ queryId,
1042
+ cellId,
1043
+ descending,
1044
+ offset = 0,
1045
+ limit,
1046
+ queriesOrQueriesId,
1047
+ ) =>
1048
+ useListenable(
1049
+ RESULT + SORTED_ROW_IDS,
1050
+ useQueriesOrQueriesById(queriesOrQueriesId),
1051
+ 1 /* Array */,
1052
+ [queryId, cellId, descending, offset, limit],
1053
+ );
1054
+ const useResultCellListener = (
1055
+ queryId,
1056
+ rowId,
1057
+ cellId,
1058
+ listener,
1059
+ listenerDeps,
1060
+ queriesOrQueriesId,
1061
+ ) =>
1062
+ useListener(
1063
+ RESULT + CELL,
1064
+ useQueriesOrQueriesById(queriesOrQueriesId),
1065
+ listener,
1066
+ listenerDeps,
1067
+ [queryId, rowId, cellId],
1068
+ );
1069
+
1070
+ const useData = (kind, rowIds, chartSize, labelSize, getXCell, getYCell) => {
1071
+ const [, rerender] = useState();
1072
+ const handleChange = useCallback(() => rerender([]), [rerender]);
1073
+ const points = getDataPoints(rowIds, (rowId) =>
1074
+ getDataPoint(rowId, getXCell(rowId), getYCell(rowId)),
1075
+ );
1076
+ const dataBounds = getBounds(kind, points);
1077
+ const xTicks = getXTicks(kind, dataBounds, chartSize, labelSize);
1078
+ const yTicks = getYTicks(dataBounds, chartSize, labelSize);
1079
+ const bounds = getTickBounds(dataBounds, xTicks, yTicks);
1080
+ return [
1081
+ handleChange,
1082
+ getScaledPoints(kind, points, bounds, chartSize),
1083
+ bounds,
1084
+ xTicks,
1085
+ yTicks,
1086
+ ];
1087
+ };
1088
+
1089
+ const QueryChart = ({
1090
+ descending,
1091
+ className,
1092
+ kind,
1093
+ limit,
1094
+ offset,
1095
+ queriesOrQueriesId,
1096
+ queryId,
1097
+ sortCellId,
1098
+ xCellId,
1099
+ yCellId,
1100
+ }) => {
1101
+ const layout = useLayout();
1102
+ const queries = useQueriesOrQueriesById(queriesOrQueriesId);
1103
+ const rowIds = useResultSortedRowIds(
1104
+ queryId,
1105
+ sortCellId ?? xCellId,
1106
+ descending,
1107
+ offset,
1108
+ limit,
1109
+ queriesOrQueriesId,
1110
+ );
1111
+ const [handleChange, points, bounds, xTicks, yTicks] = useData(
1112
+ kind,
1113
+ rowIds,
1114
+ getPlotSize(layout),
1115
+ getLabelSize(layout),
1116
+ (rowId) => queries?.getResultCell(queryId, rowId, xCellId),
1117
+ (rowId) => queries?.getResultCell(queryId, rowId, yCellId),
1118
+ );
1119
+ useResultCellListener(
1120
+ queryId,
1121
+ null,
1122
+ xCellId,
1123
+ handleChange,
1124
+ [handleChange],
1125
+ queries,
1126
+ );
1127
+ useResultCellListener(
1128
+ queryId,
1129
+ null,
1130
+ yCellId,
1131
+ handleChange,
1132
+ [handleChange],
1133
+ queries,
1134
+ );
1135
+ return /* @__PURE__ */ jsx(Layout, {
1136
+ className,
1137
+ kind,
1138
+ points,
1139
+ bounds,
1140
+ titles: [xCellId, yCellId],
1141
+ xTicks,
1142
+ yTicks,
1143
+ layout,
1144
+ });
1145
+ };
1146
+
1147
+ const TableChart = ({
1148
+ descending,
1149
+ className,
1150
+ kind,
1151
+ limit,
1152
+ offset,
1153
+ sortCellId,
1154
+ storeOrStoreId,
1155
+ tableId,
1156
+ xCellId,
1157
+ yCellId,
1158
+ }) => {
1159
+ const layout = useLayout();
1160
+ const store = useStoreOrStoreById(storeOrStoreId);
1161
+ const rowIds = useSortedRowIds(
1162
+ tableId,
1163
+ sortCellId ?? xCellId,
1164
+ descending,
1165
+ offset,
1166
+ limit,
1167
+ storeOrStoreId,
1168
+ );
1169
+ const [handleChange, points, bounds, xTicks, yTicks] = useData(
1170
+ kind,
1171
+ rowIds,
1172
+ getPlotSize(layout),
1173
+ getLabelSize(layout),
1174
+ (rowId) => store?.getCell(tableId, rowId, xCellId),
1175
+ (rowId) => store?.getCell(tableId, rowId, yCellId),
1176
+ );
1177
+ useCellListener(
1178
+ tableId,
1179
+ null,
1180
+ xCellId,
1181
+ handleChange,
1182
+ [handleChange],
1183
+ false,
1184
+ storeOrStoreId,
1185
+ );
1186
+ useCellListener(
1187
+ tableId,
1188
+ null,
1189
+ yCellId,
1190
+ handleChange,
1191
+ [handleChange],
1192
+ false,
1193
+ storeOrStoreId,
1194
+ );
1195
+ return /* @__PURE__ */ jsx(Layout, {
1196
+ className,
1197
+ kind,
1198
+ points,
1199
+ bounds,
1200
+ titles: [xCellId, yCellId],
1201
+ xTicks,
1202
+ yTicks,
1203
+ layout,
1204
+ });
1205
+ };
1206
+
1207
+ const Chart = ({className, store, tableId, queries, queryId, ...props}) =>
1208
+ isUndefined(tableId)
1209
+ ? isUndefined(queryId)
1210
+ ? /* @__PURE__ */ jsx(EmptyChart, {...props, className})
1211
+ : /* @__PURE__ */ jsx(QueryChart, {
1212
+ ...props,
1213
+ className,
1214
+ queriesOrQueriesId: queries,
1215
+ queryId,
1216
+ })
1217
+ : /* @__PURE__ */ jsx(TableChart, {
1218
+ ...props,
1219
+ className,
1220
+ storeOrStoreId: store,
1221
+ tableId,
1222
+ });
1223
+
1224
+ const BarChart = (props) => /* @__PURE__ */ jsx(Chart, {...props, kind: 'bar'});
1225
+
1226
+ const LineChart = (props) =>
1227
+ /* @__PURE__ */ jsx(Chart, {...props, kind: 'line'});
1228
+
1229
+ export {BarChart, LineChart};