@xyo-network/react-price-forecast-plugin 7.5.8 → 7.5.12

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.
@@ -1,13 +1,20 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
-
4
1
  // src/components/DetailsBox.tsx
5
2
  import "chartjs-adapter-luxon";
6
3
  import { useTheme } from "@mui/material";
7
4
  import { useAsyncEffect } from "@xylabs/react-async-effect";
8
5
  import { FlexCol } from "@xylabs/react-flexbox";
9
- import { CategoryScale, Chart as ChartJS, Legend, LinearScale, LineElement, PointElement, TimeScale, Title, Tooltip } from "chart.js";
10
- import React, { useState } from "react";
6
+ import {
7
+ CategoryScale,
8
+ Chart as ChartJS,
9
+ Legend,
10
+ LinearScale,
11
+ LineElement,
12
+ PointElement,
13
+ TimeScale,
14
+ Title,
15
+ Tooltip
16
+ } from "chart.js";
17
+ import { useState } from "react";
11
18
  import { Line } from "react-chartjs-2";
12
19
 
13
20
  // src/lib/ForecastLineChartConfigBuilder.ts
@@ -15,23 +22,23 @@ import { useIsDark } from "@xylabs/react-theme";
15
22
 
16
23
  // src/lib/DataLineStyles.ts
17
24
  import { alphaCss } from "@xylabs/react-theme";
18
- var DataLineStyles = /* @__PURE__ */ __name((color) => ({
25
+ var DataLineStyles = (color) => ({
19
26
  backgroundColor: color ? alphaCss(color, 0.5) : void 0,
20
27
  borderColor: color
21
- }), "DataLineStyles");
28
+ });
22
29
 
23
30
  // src/lib/DataPointStyles.ts
24
- var DataPointStyles = /* @__PURE__ */ __name((pointHoverBackgroundColor) => ({
31
+ var DataPointStyles = (pointHoverBackgroundColor) => ({
25
32
  pointHitRadius: 20,
26
33
  pointHoverBackgroundColor,
27
34
  pointHoverRadius: 10,
28
35
  pointRadius: 5,
29
36
  pointStyle: "circle"
30
- }), "DataPointStyles");
37
+ });
31
38
 
32
39
  // src/lib/MockSourcePayloads.ts
33
40
  import { asSchema } from "@xyo-network/payload-model";
34
- var MockSourcePayloads = /* @__PURE__ */ __name(() => {
41
+ var MockSourcePayloads = () => {
35
42
  const tenMin = 6e5;
36
43
  return [
37
44
  {
@@ -69,13 +76,10 @@ var MockSourcePayloads = /* @__PURE__ */ __name(() => {
69
76
  timestamp: Date.now()
70
77
  }
71
78
  ];
72
- }, "MockSourcePayloads");
79
+ };
73
80
 
74
81
  // src/lib/SourcePayloads.ts
75
82
  var SourcePayloads = class {
76
- static {
77
- __name(this, "SourcePayloads");
78
- }
79
83
  sourcePayloads;
80
84
  sourcePrices = [];
81
85
  constructor(sourcePayloads) {
@@ -89,10 +93,7 @@ var SourcePayloads = class {
89
93
  const instance = new this(sourcePayloads);
90
94
  const paths = jsonPath.split(".");
91
95
  instance.sourcePrices = sourcePayloads.map((payload) => {
92
- return {
93
- x: payload.timestamp,
94
- y: instance.jsonPathTraverser(payload, paths)
95
- };
96
+ return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) };
96
97
  });
97
98
  return instance;
98
99
  }
@@ -117,21 +118,12 @@ var SourcePayloads = class {
117
118
  };
118
119
 
119
120
  // src/lib/ForecastLineChartConfigBuilder.ts
120
- var defaultOptions = /* @__PURE__ */ __name(() => ({
121
- plugins: {
122
- legend: {
123
- position: "top"
124
- }
125
- },
121
+ var defaultOptions = () => ({
122
+ plugins: { legend: { position: "top" } },
126
123
  responsive: true
127
- }), "defaultOptions");
124
+ });
128
125
  var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
129
- static {
130
- __name(this, "ForecastLineChartConfigBuilder");
131
- }
132
- data = {
133
- datasets: []
134
- };
126
+ data = { datasets: [] };
135
127
  options = defaultOptions();
136
128
  themeColors;
137
129
  payload;
@@ -159,18 +151,14 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
159
151
  }
160
152
  async buildData(includeSources) {
161
153
  const forecastData = this.generateDataSetForecastData();
162
- const datasets = [
163
- forecastData
164
- ];
154
+ const datasets = [forecastData];
165
155
  if (includeSources) {
166
156
  const sourceData = await this.generateDataSetSourcePayloads();
167
157
  datasets.unshift(sourceData);
168
158
  const lastSourceDataItem = sourceData.data.at(-1);
169
159
  forecastData.data.unshift(lastSourceDataItem);
170
160
  }
171
- this.data = {
172
- datasets
173
- };
161
+ this.data = { datasets };
174
162
  return this;
175
163
  }
176
164
  buildOptions() {
@@ -182,12 +170,8 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
182
170
  return this;
183
171
  }
184
172
  refreshValues() {
185
- this.data = {
186
- ...this.data
187
- };
188
- this.options = {
189
- ...this.options
190
- };
173
+ this.data = { ...this.data };
174
+ this.options = { ...this.options };
191
175
  }
192
176
  generateLegend() {
193
177
  return {
@@ -200,19 +184,11 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
200
184
  generateScales() {
201
185
  return {
202
186
  x: {
203
- grid: {
204
- color: this.themeColors?.gridColor
205
- },
206
- time: {
207
- unit: "minute"
208
- },
187
+ grid: { color: this.themeColors?.gridColor },
188
+ time: { unit: "minute" },
209
189
  type: "time"
210
190
  },
211
- y: {
212
- grid: {
213
- color: this.themeColors?.gridColor
214
- }
215
- }
191
+ y: { grid: { color: this.themeColors?.gridColor } }
216
192
  };
217
193
  }
218
194
  generateTitle() {
@@ -231,14 +207,9 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
231
207
  }
232
208
  generateDataSetForecastData() {
233
209
  return {
234
- borderDash: [
235
- 5
236
- ],
210
+ borderDash: [5],
237
211
  borderDashOffset: 0.5,
238
- data: this.forecastPayload.values.map((price) => ({
239
- x: price.timestamp ?? 0,
240
- y: price.value
241
- })),
212
+ data: this.forecastPayload.values.map((price) => ({ x: price.timestamp ?? 0, y: price.value })),
242
213
  label: "Forecast Price",
243
214
  ...DataPointStyles(this.themeColors?.dataSetColorPrimary),
244
215
  ...DataLineStyles(this.themeColors?.dataSetColorPrimary)
@@ -256,46 +227,32 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
256
227
  };
257
228
 
258
229
  // src/components/DetailsBox.tsx
230
+ import { jsx } from "react/jsx-runtime";
259
231
  ChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend);
260
- var PriceForecastDetailsBox = /* @__PURE__ */ __name(({ payload, ...props }) => {
232
+ var PriceForecastDetailsBox = ({ payload, ...props }) => {
261
233
  const priceForecastPayload = payload;
262
234
  const theme = useTheme();
263
- const [data, setData] = useState({
264
- datasets: []
265
- });
235
+ const [data, setData] = useState({ datasets: [] });
266
236
  const [options, setOptions] = useState({});
267
- useAsyncEffect(async (mounted) => {
268
- const { data: data2, options: options2 } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, {
269
- fetch: true
270
- });
271
- if (mounted()) {
272
- setData(data2);
273
- setOptions(options2);
274
- }
275
- }, [
276
- priceForecastPayload,
277
- theme
278
- ]);
279
- return /* @__PURE__ */ React.createElement(FlexCol, {
280
- ...props,
281
- busy: priceForecastPayload === void 0,
282
- minHeight: "25vh"
283
- }, priceForecastPayload ? /* @__PURE__ */ React.createElement(Line, {
284
- options,
285
- data
286
- }) : null);
287
- }, "PriceForecastDetailsBox");
237
+ useAsyncEffect(
238
+ async (mounted) => {
239
+ const { data: data2, options: options2 } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true });
240
+ if (mounted()) {
241
+ setData(data2);
242
+ setOptions(options2);
243
+ }
244
+ },
245
+ [priceForecastPayload, theme]
246
+ );
247
+ return /* @__PURE__ */ jsx(FlexCol, { ...props, busy: priceForecastPayload === void 0, minHeight: "25vh", children: priceForecastPayload ? /* @__PURE__ */ jsx(Line, { options, data }) : null });
248
+ };
288
249
 
289
250
  // src/Plugin.ts
290
251
  import { createPayloadRenderPlugin } from "@xyo-network/react-payload-plugin";
291
252
  var PriceForecastRenderPlugin = {
292
253
  ...createPayloadRenderPlugin({
293
- canRender: /* @__PURE__ */ __name(() => true, "canRender"),
294
- components: {
295
- box: {
296
- detailsBox: PriceForecastDetailsBox
297
- }
298
- },
254
+ canRender: () => true,
255
+ components: { box: { detailsBox: PriceForecastDetailsBox } },
299
256
  name: "PriceForecast"
300
257
  })
301
258
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/DetailsBox.tsx","../../src/lib/ForecastLineChartConfigBuilder.ts","../../src/lib/DataLineStyles.ts","../../src/lib/DataPointStyles.ts","../../src/lib/MockSourcePayloads.ts","../../src/lib/SourcePayloads.ts","../../src/Plugin.ts"],"sourcesContent":["import 'chartjs-adapter-luxon'\n\nimport { useTheme } from '@mui/material'\nimport { useAsyncEffect } from '@xylabs/react-async-effect'\nimport type { FlexBoxProps } from '@xylabs/react-flexbox'\nimport { FlexCol } from '@xylabs/react-flexbox'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type { Payload } from '@xyo-network/payload-model'\nimport type {\n ChartData,\n ChartOptions,\n} from 'chart.js'\nimport {\n CategoryScale,\n Chart as ChartJS,\n Legend,\n LinearScale,\n LineElement,\n PointElement,\n TimeScale,\n Title,\n Tooltip,\n} from 'chart.js'\nimport React, { useState } from 'react'\nimport { Line } from 'react-chartjs-2'\n\nimport { ForecastLineChartConfigBuilder } from '../lib/index.ts'\n\nChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend)\n\nexport interface PriceForecastDetailsBoxProps extends FlexBoxProps {\n payload?: Payload\n}\n\nexport const PriceForecastDetailsBox: React.FC<PriceForecastDetailsBoxProps> = ({ payload, ...props }) => {\n const priceForecastPayload = payload as ForecastPayload | undefined\n const theme = useTheme()\n const [data, setData] = useState<ChartData<'line'>>({ datasets: [] })\n const [options, setOptions] = useState<ChartOptions<'line'>>({})\n\n useAsyncEffect(\n\n async (mounted) => {\n const { data, options } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true })\n if (mounted()) {\n setData(data)\n setOptions(options)\n }\n },\n [priceForecastPayload, theme],\n )\n\n return (\n <FlexCol {...props} busy={priceForecastPayload === undefined} minHeight=\"25vh\">\n {priceForecastPayload\n ? <Line options={options} data={data} />\n : null}\n </FlexCol>\n )\n}\n","import type { Theme } from '@mui/material'\nimport { useIsDark } from '@xylabs/react-theme'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type {\n ChartData, ChartDataset, ChartOptions, LegendOptions, Point, ScaleChartOptions,\n} from 'chart.js'\n\nimport { DataLineStyles } from './DataLineStyles.ts'\nimport { DataPointStyles } from './DataPointStyles.ts'\nimport { SourcePayloads } from './SourcePayloads.ts'\n\ninterface SourcePayloadConfig {\n fetch: boolean\n sampleSize?: number\n}\n\ninterface ThemeColors {\n dataSetColorPrimary: string\n dataSetColorSecondary: string\n gridColor: string\n}\n\nconst defaultOptions: () => ChartOptions<'line'> = () => ({\n plugins: { legend: { position: 'top' as const } },\n responsive: true,\n})\n\nexport class ForecastLineChartConfigBuilder {\n data: ChartData<'line'> = { datasets: [] }\n\n options: ChartOptions<'line'> = defaultOptions()\n themeColors: ThemeColors | undefined\n\n private payload?: ForecastPayload\n\n constructor(\n theme: Theme,\n payload?: ForecastPayload,\n ) {\n this.payload = payload\n this.themeColors = this.parseTheme(theme)\n }\n\n get forecastPayload() {\n if (this.payload) {\n return this.payload\n } else {\n throw new Error('ForecastPayload was not defined')\n }\n }\n\n static async create(theme: Theme, payload?: ForecastPayload, sourcePayloadConfig?: SourcePayloadConfig) {\n const instance = new ForecastLineChartConfigBuilder(theme, payload)\n\n await instance.build(sourcePayloadConfig?.fetch)\n\n instance.refreshValues()\n\n return instance\n }\n\n async build(includeSources?: boolean) {\n this.buildOptions()\n await this.buildData(includeSources)\n return this\n }\n\n async buildData(includeSources?: boolean) {\n const forecastData = this.generateDataSetForecastData()\n\n const datasets: ChartDataset<'line'>[] = [forecastData]\n\n if (includeSources) {\n // build data from sources in forecastPayload\n const sourceData = await this.generateDataSetSourcePayloads()\n datasets.unshift(sourceData)\n\n // add last source point as first item in prediction to connect the lines\n const lastSourceDataItem = sourceData.data.at(-1) as Point\n forecastData.data.unshift(lastSourceDataItem)\n }\n\n this.data = { datasets }\n\n return this\n }\n\n buildOptions() {\n if (this.options.plugins) {\n this.options.plugins.title = this.generateTitle()\n this.options.plugins.legend = this.generateLegend()\n }\n this.options.scales = this.generateScales()\n\n return this\n }\n\n refreshValues() {\n this.data = { ...this.data }\n this.options = { ...this.options }\n }\n\n protected generateLegend() {\n return {\n labels: {\n pointStyle: 'circle',\n usePointStyle: true,\n },\n } as LegendOptions<'line'>\n }\n\n protected generateScales() {\n return {\n x: {\n grid: { color: this.themeColors?.gridColor },\n time: { unit: 'minute' },\n type: 'time',\n },\n y: { grid: { color: this.themeColors?.gridColor } },\n } as unknown as ScaleChartOptions<'line'>['scales']\n }\n\n protected generateTitle() {\n return {\n display: true,\n text: `Gas Price Forecaster (GWEI over time from ${\n this.forecastPayload?.values[0].timestamp ? new Date(this.forecastPayload.values[0].timestamp).toLocaleDateString() : ''\n })`,\n }\n }\n\n protected parseTheme(theme: Theme) {\n // eslint-disable-next-line react-x/rules-of-hooks, react-hooks/rules-of-hooks\n const dark = useIsDark()\n return {\n dataSetColorPrimary: theme.vars.palette.primary.light,\n dataSetColorSecondary: theme.vars.palette.secondary.light,\n gridColor: dark ? theme.vars.palette.grey[800] : theme.vars.palette.grey[300],\n }\n }\n\n private generateDataSetForecastData(): ChartDataset<'line'> {\n return {\n borderDash: [5],\n borderDashOffset: 0.5,\n data: this.forecastPayload.values.map(price => ({ x: price.timestamp ?? 0, y: price.value })),\n label: 'Forecast Price',\n ...DataPointStyles(this.themeColors?.dataSetColorPrimary),\n ...DataLineStyles(this.themeColors?.dataSetColorPrimary),\n }\n }\n\n private async generateDataSetSourcePayloads(): Promise<ChartDataset<'line'>> {\n const { sourcePrices } = await SourcePayloads.build('feePerGas.medium')\n return {\n data: sourcePrices,\n label: 'Source Prices',\n ...DataLineStyles(this.themeColors?.dataSetColorSecondary),\n ...DataPointStyles(this.themeColors?.dataSetColorSecondary),\n }\n }\n}\n","import { alphaCss } from '@xylabs/react-theme'\n\nexport const DataLineStyles = (color?: string) => ({\n backgroundColor: color ? alphaCss(color, 0.5) : undefined,\n borderColor: color,\n})\n","export const DataPointStyles = (pointHoverBackgroundColor?: string) => ({\n pointHitRadius: 20,\n pointHoverBackgroundColor,\n pointHoverRadius: 10,\n pointRadius: 5,\n pointStyle: 'circle',\n})\n","import { asSchema } from '@xyo-network/payload-model'\n\nexport const MockSourcePayloads = () => {\n const tenMin = 600_000\n return [\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 39.306_868_093, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now() - tenMin,\n },\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 100, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now(),\n },\n ]\n}\n","import type { Payload } from '@xyo-network/payload-model'\nimport type { Point } from 'chart.js'\n\nimport { MockSourcePayloads } from './MockSourcePayloads.ts'\n\nexport class SourcePayloads {\n sourcePayloads: Payload[]\n sourcePrices: Point[] = []\n\n constructor(sourcePayloads: Payload[]) {\n this.sourcePayloads = sourcePayloads\n }\n\n get payloads() {\n return this.sourcePayloads\n }\n\n static async build(jsonPath: string) {\n const sourcePayloads = await this.fetchSourcePayloads()\n const instance = new this(sourcePayloads)\n\n const paths = jsonPath.split('.')\n instance.sourcePrices = sourcePayloads.map((payload) => {\n return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) }\n })\n return instance\n }\n\n // TODO - fetch from archivist\n static async fetchSourcePayloads() {\n const payloads = await Promise.resolve(MockSourcePayloads())\n return payloads\n }\n\n jsonPathTraverser(obj: Payload, path: string[]) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let result: any = obj\n for (const key of path) {\n if (key in result) {\n const foundKey = key as keyof typeof result\n result = result[foundKey]\n } else {\n result = undefined\n break\n }\n }\n\n return result\n }\n}\n","import type { PayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\nimport { createPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\n\nimport { PriceForecastDetailsBox } from './components/index.ts'\n\nexport const PriceForecastRenderPlugin: PayloadRenderPlugin = {\n ...createPayloadRenderPlugin({\n canRender: () => true,\n components: { box: { detailsBox: PriceForecastDetailsBox } },\n name: 'PriceForecast',\n }),\n}\n"],"mappings":"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","names":["useTheme","useAsyncEffect","FlexCol","CategoryScale","Chart","ChartJS","Legend","LinearScale","LineElement","PointElement","TimeScale","Title","Tooltip","React","useState","Line","useIsDark","alphaCss","DataLineStyles","color","backgroundColor","alphaCss","undefined","borderColor","DataPointStyles","pointHoverBackgroundColor","pointHitRadius","pointHoverRadius","pointRadius","pointStyle","asSchema","MockSourcePayloads","tenMin","baseFee","feePerGas","high","low","medium","veryHigh","priorityFeePerGas","schema","asSchema","timestamp","Date","now","SourcePayloads","sourcePayloads","sourcePrices","payloads","build","jsonPath","fetchSourcePayloads","instance","paths","split","map","payload","x","timestamp","y","jsonPathTraverser","Promise","resolve","MockSourcePayloads","obj","path","result","key","foundKey","undefined","defaultOptions","plugins","legend","position","responsive","ForecastLineChartConfigBuilder","data","datasets","options","themeColors","payload","theme","parseTheme","forecastPayload","Error","create","sourcePayloadConfig","instance","build","fetch","refreshValues","includeSources","buildOptions","buildData","forecastData","generateDataSetForecastData","sourceData","generateDataSetSourcePayloads","unshift","lastSourceDataItem","at","title","generateTitle","generateLegend","scales","generateScales","labels","pointStyle","usePointStyle","x","grid","color","gridColor","time","unit","type","y","display","text","values","timestamp","Date","toLocaleDateString","dark","useIsDark","dataSetColorPrimary","vars","palette","primary","light","dataSetColorSecondary","secondary","grey","borderDash","borderDashOffset","map","price","value","label","DataPointStyles","DataLineStyles","sourcePrices","SourcePayloads","ChartJS","register","CategoryScale","TimeScale","PointElement","LineElement","LinearScale","Title","Tooltip","Legend","PriceForecastDetailsBox","payload","props","priceForecastPayload","theme","useTheme","data","setData","useState","datasets","options","setOptions","useAsyncEffect","mounted","ForecastLineChartConfigBuilder","create","fetch","FlexCol","busy","undefined","minHeight","Line","createPayloadRenderPlugin","PriceForecastRenderPlugin","createPayloadRenderPlugin","canRender","components","box","detailsBox","PriceForecastDetailsBox","name"]}
1
+ {"version":3,"sources":["../../src/components/DetailsBox.tsx","../../src/lib/ForecastLineChartConfigBuilder.ts","../../src/lib/DataLineStyles.ts","../../src/lib/DataPointStyles.ts","../../src/lib/MockSourcePayloads.ts","../../src/lib/SourcePayloads.ts","../../src/Plugin.ts"],"sourcesContent":["import 'chartjs-adapter-luxon'\n\nimport { useTheme } from '@mui/material'\nimport { useAsyncEffect } from '@xylabs/react-async-effect'\nimport type { FlexBoxProps } from '@xylabs/react-flexbox'\nimport { FlexCol } from '@xylabs/react-flexbox'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type { Payload } from '@xyo-network/payload-model'\nimport type {\n ChartData,\n ChartOptions,\n} from 'chart.js'\nimport {\n CategoryScale,\n Chart as ChartJS,\n Legend,\n LinearScale,\n LineElement,\n PointElement,\n TimeScale,\n Title,\n Tooltip,\n} from 'chart.js'\nimport React, { useState } from 'react'\nimport { Line } from 'react-chartjs-2'\n\nimport { ForecastLineChartConfigBuilder } from '../lib/index.ts'\n\nChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend)\n\nexport interface PriceForecastDetailsBoxProps extends FlexBoxProps {\n payload?: Payload\n}\n\nexport const PriceForecastDetailsBox: React.FC<PriceForecastDetailsBoxProps> = ({ payload, ...props }) => {\n const priceForecastPayload = payload as ForecastPayload | undefined\n const theme = useTheme()\n const [data, setData] = useState<ChartData<'line'>>({ datasets: [] })\n const [options, setOptions] = useState<ChartOptions<'line'>>({})\n\n useAsyncEffect(\n\n async (mounted) => {\n const { data, options } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true })\n if (mounted()) {\n setData(data)\n setOptions(options)\n }\n },\n [priceForecastPayload, theme],\n )\n\n return (\n <FlexCol {...props} busy={priceForecastPayload === undefined} minHeight=\"25vh\">\n {priceForecastPayload\n ? <Line options={options} data={data} />\n : null}\n </FlexCol>\n )\n}\n","import type { Theme } from '@mui/material'\nimport { useIsDark } from '@xylabs/react-theme'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type {\n ChartData, ChartDataset, ChartOptions, LegendOptions, Point, ScaleChartOptions,\n} from 'chart.js'\n\nimport { DataLineStyles } from './DataLineStyles.ts'\nimport { DataPointStyles } from './DataPointStyles.ts'\nimport { SourcePayloads } from './SourcePayloads.ts'\n\ninterface SourcePayloadConfig {\n fetch: boolean\n sampleSize?: number\n}\n\ninterface ThemeColors {\n dataSetColorPrimary: string\n dataSetColorSecondary: string\n gridColor: string\n}\n\nconst defaultOptions: () => ChartOptions<'line'> = () => ({\n plugins: { legend: { position: 'top' as const } },\n responsive: true,\n})\n\nexport class ForecastLineChartConfigBuilder {\n data: ChartData<'line'> = { datasets: [] }\n\n options: ChartOptions<'line'> = defaultOptions()\n themeColors: ThemeColors | undefined\n\n private payload?: ForecastPayload\n\n constructor(\n theme: Theme,\n payload?: ForecastPayload,\n ) {\n this.payload = payload\n this.themeColors = this.parseTheme(theme)\n }\n\n get forecastPayload() {\n if (this.payload) {\n return this.payload\n } else {\n throw new Error('ForecastPayload was not defined')\n }\n }\n\n static async create(theme: Theme, payload?: ForecastPayload, sourcePayloadConfig?: SourcePayloadConfig) {\n const instance = new ForecastLineChartConfigBuilder(theme, payload)\n\n await instance.build(sourcePayloadConfig?.fetch)\n\n instance.refreshValues()\n\n return instance\n }\n\n async build(includeSources?: boolean) {\n this.buildOptions()\n await this.buildData(includeSources)\n return this\n }\n\n async buildData(includeSources?: boolean) {\n const forecastData = this.generateDataSetForecastData()\n\n const datasets: ChartDataset<'line'>[] = [forecastData]\n\n if (includeSources) {\n // build data from sources in forecastPayload\n const sourceData = await this.generateDataSetSourcePayloads()\n datasets.unshift(sourceData)\n\n // add last source point as first item in prediction to connect the lines\n const lastSourceDataItem = sourceData.data.at(-1) as Point\n forecastData.data.unshift(lastSourceDataItem)\n }\n\n this.data = { datasets }\n\n return this\n }\n\n buildOptions() {\n if (this.options.plugins) {\n this.options.plugins.title = this.generateTitle()\n this.options.plugins.legend = this.generateLegend()\n }\n this.options.scales = this.generateScales()\n\n return this\n }\n\n refreshValues() {\n this.data = { ...this.data }\n this.options = { ...this.options }\n }\n\n protected generateLegend() {\n return {\n labels: {\n pointStyle: 'circle',\n usePointStyle: true,\n },\n } as LegendOptions<'line'>\n }\n\n protected generateScales() {\n return {\n x: {\n grid: { color: this.themeColors?.gridColor },\n time: { unit: 'minute' },\n type: 'time',\n },\n y: { grid: { color: this.themeColors?.gridColor } },\n } as unknown as ScaleChartOptions<'line'>['scales']\n }\n\n protected generateTitle() {\n return {\n display: true,\n text: `Gas Price Forecaster (GWEI over time from ${\n this.forecastPayload?.values[0].timestamp ? new Date(this.forecastPayload.values[0].timestamp).toLocaleDateString() : ''\n })`,\n }\n }\n\n protected parseTheme(theme: Theme) {\n // eslint-disable-next-line react-x/rules-of-hooks, react-hooks/rules-of-hooks\n const dark = useIsDark()\n return {\n dataSetColorPrimary: theme.vars.palette.primary.light,\n dataSetColorSecondary: theme.vars.palette.secondary.light,\n gridColor: dark ? theme.vars.palette.grey[800] : theme.vars.palette.grey[300],\n }\n }\n\n private generateDataSetForecastData(): ChartDataset<'line'> {\n return {\n borderDash: [5],\n borderDashOffset: 0.5,\n data: this.forecastPayload.values.map(price => ({ x: price.timestamp ?? 0, y: price.value })),\n label: 'Forecast Price',\n ...DataPointStyles(this.themeColors?.dataSetColorPrimary),\n ...DataLineStyles(this.themeColors?.dataSetColorPrimary),\n }\n }\n\n private async generateDataSetSourcePayloads(): Promise<ChartDataset<'line'>> {\n const { sourcePrices } = await SourcePayloads.build('feePerGas.medium')\n return {\n data: sourcePrices,\n label: 'Source Prices',\n ...DataLineStyles(this.themeColors?.dataSetColorSecondary),\n ...DataPointStyles(this.themeColors?.dataSetColorSecondary),\n }\n }\n}\n","import { alphaCss } from '@xylabs/react-theme'\n\nexport const DataLineStyles = (color?: string) => ({\n backgroundColor: color ? alphaCss(color, 0.5) : undefined,\n borderColor: color,\n})\n","export const DataPointStyles = (pointHoverBackgroundColor?: string) => ({\n pointHitRadius: 20,\n pointHoverBackgroundColor,\n pointHoverRadius: 10,\n pointRadius: 5,\n pointStyle: 'circle',\n})\n","import { asSchema } from '@xyo-network/payload-model'\n\nexport const MockSourcePayloads = () => {\n const tenMin = 600_000\n return [\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 39.306_868_093, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now() - tenMin,\n },\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 100, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now(),\n },\n ]\n}\n","import type { Payload } from '@xyo-network/payload-model'\nimport type { Point } from 'chart.js'\n\nimport { MockSourcePayloads } from './MockSourcePayloads.ts'\n\nexport class SourcePayloads {\n sourcePayloads: Payload[]\n sourcePrices: Point[] = []\n\n constructor(sourcePayloads: Payload[]) {\n this.sourcePayloads = sourcePayloads\n }\n\n get payloads() {\n return this.sourcePayloads\n }\n\n static async build(jsonPath: string) {\n const sourcePayloads = await this.fetchSourcePayloads()\n const instance = new this(sourcePayloads)\n\n const paths = jsonPath.split('.')\n instance.sourcePrices = sourcePayloads.map((payload) => {\n return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) }\n })\n return instance\n }\n\n // TODO - fetch from archivist\n static async fetchSourcePayloads() {\n const payloads = await Promise.resolve(MockSourcePayloads())\n return payloads\n }\n\n jsonPathTraverser(obj: Payload, path: string[]) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let result: any = obj\n for (const key of path) {\n if (key in result) {\n const foundKey = key as keyof typeof result\n result = result[foundKey]\n } else {\n result = undefined\n break\n }\n }\n\n return result\n }\n}\n","import type { PayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\nimport { createPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\n\nimport { PriceForecastDetailsBox } from './components/index.ts'\n\nexport const PriceForecastRenderPlugin: PayloadRenderPlugin = {\n ...createPayloadRenderPlugin({\n canRender: () => true,\n components: { box: { detailsBox: PriceForecastDetailsBox } },\n name: 'PriceForecast',\n }),\n}\n"],"mappings":"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","names":["data","options"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/react-price-forecast-plugin",
3
- "version": "7.5.8",
3
+ "version": "7.5.12",
4
4
  "description": "Common React library for all XYO projects that use React",
5
5
  "keywords": [
6
6
  "xyo",
@@ -36,55 +36,179 @@
36
36
  },
37
37
  "./package.json": "./package.json"
38
38
  },
39
- "module": "dist/browser/index.mjs",
40
- "types": "dist/browser/index.d.ts",
41
39
  "files": [
42
40
  "dist",
43
- "src"
41
+ "README.md"
44
42
  ],
45
43
  "dependencies": {
46
- "@xylabs/react-async-effect": "~7.1.17",
47
- "@xylabs/react-flexbox": "~7.1.17",
48
- "@xylabs/react-theme": "~7.1.17",
49
- "@xyo-network/diviner-forecasting-model": "~5.3.17",
50
- "@xyo-network/payload-model": "~5.3.17",
51
- "@xyo-network/react-payload-plugin": "7.5.8",
52
- "chart.js": "~4.5.1",
53
- "chartjs-adapter-luxon": "~1.3.1",
54
- "react-chartjs-2": "~5.3.1"
44
+ "@xyo-network/react-payload-plugin": "~7.5.12"
55
45
  },
56
46
  "devDependencies": {
57
- "@emotion/react": "~11.14.0",
58
- "@emotion/styled": "~11.14.1",
59
- "@mui/icons-material": "~7.3.9",
60
- "@mui/material": "~7.3.9",
61
- "@storybook/react-vite": "~10.3.3",
47
+ "@bitauth/libauth": "~3.0.0",
48
+ "@emotion/react": "^11.14.0",
49
+ "@emotion/styled": "^11.14.1",
50
+ "@mui/icons-material": "^7.3.10",
51
+ "@mui/material": "^7.3.10",
52
+ "@mui/system": "^7.3.10",
53
+ "@mui/x-tree-view": "~8.27.2",
54
+ "@opentelemetry/api": "^1.9.1",
55
+ "@opentelemetry/sdk-trace-base": "^2.7.0",
56
+ "@scure/base": "~2.2.0",
57
+ "@storybook/react-vite": "~10.3.5",
58
+ "@textea/json-viewer": "~4.0.1",
59
+ "@types/node": "~25.6.0",
62
60
  "@types/react": "^19.2.14",
63
- "@xylabs/ts-scripts-common": "~7.5.6",
64
- "@xylabs/ts-scripts-yarn3": "~7.5.6",
65
- "@xylabs/tsconfig": "~7.5.6",
66
- "@xylabs/tsconfig-dom": "~7.5.6",
67
- "@xylabs/tsconfig-react": "~7.5.6",
61
+ "@xylabs/react-async-effect": "~7.1.20",
62
+ "@xylabs/react-button": "~7.1.20",
63
+ "@xylabs/react-dialogs": "~7.1.20",
64
+ "@xylabs/react-flexbox": "~7.1.20",
65
+ "@xylabs/react-hooks": "~7.1.20",
66
+ "@xylabs/react-identicon": "~7.1.20",
67
+ "@xylabs/react-link": "~7.1.20",
68
+ "@xylabs/react-promise": "~7.1.20",
69
+ "@xylabs/react-quick-tip-button": "~7.1.20",
70
+ "@xylabs/react-select": "~7.1.20",
71
+ "@xylabs/react-shared": "~7.1.20",
72
+ "@xylabs/react-theme": "~7.1.20",
73
+ "@xylabs/sdk-js": "^5.0.100",
74
+ "@xylabs/threads": "~5.0.100",
75
+ "@xylabs/toolchain": "~7.11.9",
76
+ "@xylabs/tsconfig": "^7.11.9",
77
+ "@xylabs/tsconfig-dom": "^7.11.9",
78
+ "@xylabs/tsconfig-react": "~7.11.9",
79
+ "@xylabs/zod": "~5.0.100",
80
+ "@xyo-network/account": "~5.5.1",
81
+ "@xyo-network/account-model": "^5.5.1",
82
+ "@xyo-network/boundwitness-builder": "^5.5.1",
83
+ "@xyo-network/boundwitness-model": "^5.5.1",
84
+ "@xyo-network/boundwitness-validator": "^5.5.1",
85
+ "@xyo-network/boundwitness-wrapper": "~5.5.1",
86
+ "@xyo-network/config-payload-plugin": "~5.5.1",
87
+ "@xyo-network/diviner-forecasting-model": "~5.5.5",
88
+ "@xyo-network/diviner-model": "^5.5.5",
89
+ "@xyo-network/diviner-schema-list": "~5.5.5",
90
+ "@xyo-network/diviner-schema-stats": "~5.5.2",
91
+ "@xyo-network/manifest-model": "~5.5.1",
92
+ "@xyo-network/module-abstract": "^5.5.5",
93
+ "@xyo-network/module-model": "^5.5.5",
94
+ "@xyo-network/node-core-types": "~4.1.10",
95
+ "@xyo-network/node-memory": "~5.5.5",
96
+ "@xyo-network/node-model": "^5.5.5",
97
+ "@xyo-network/payload-builder": "^5.5.1",
98
+ "@xyo-network/payload-model": "^5.5.1",
99
+ "@xyo-network/payload-validator": "^5.5.1",
100
+ "@xyo-network/query-payload-plugin": "~5.5.1",
101
+ "@xyo-network/schema-cache": "~5.5.1",
102
+ "@xyo-network/schema-payload-plugin": "~5.5.1",
103
+ "@xyo-network/typeof": "~5.3.30",
104
+ "@xyo-network/wallet-model": "^5.5.1",
105
+ "ajv": "^8.18.0",
106
+ "async-mutex": "^0.5.0",
107
+ "axios": "^1.15.2",
108
+ "bn.js": "^5.2.3",
109
+ "bowser": "^2.14.1",
110
+ "buffer": "^6.0.3",
111
+ "chalk": "^5.6.2",
112
+ "chart.js": "^4.5.1",
113
+ "chartjs-adapter-luxon": "~1.3.1",
114
+ "debug": "~4.4.3",
115
+ "esbuild": "~0.28.0",
116
+ "eslint": "^10.2.1",
117
+ "ethers": "^6.16.0",
118
+ "fast-deep-equal": "~3.1.3",
119
+ "hash-wasm": "~4.12.0",
120
+ "js-cookie": "~3.0.5",
121
+ "lru-cache": "^11.3.5",
68
122
  "luxon": "^3.7.2",
69
- "react": "^19.2.4",
70
- "react-dom": "^19.2.4",
71
- "react-router-dom": "^7.13.2",
72
- "storybook": "~10.3.3",
123
+ "observable-fns": "~0.6.1",
124
+ "pako": "^2.1.0",
125
+ "react": "^19.2.5",
126
+ "react-chartjs-2": "~5.3.1",
127
+ "react-dom": "^19.2.5",
128
+ "react-router-dom": "^7.14.2",
129
+ "spark-md5": "~3.0.2",
130
+ "storybook": "^10.3.5",
73
131
  "typescript": "^5.9.3",
74
- "vite": "~8.0.3",
132
+ "vite": "^8.0.10",
133
+ "wasm-feature-detect": "~1.8.0",
75
134
  "zod": "^4.3.6"
76
135
  },
77
136
  "peerDependencies": {
78
- "@mui/icons-material": ">=6 <8",
79
- "@mui/material": ">=6 <8",
80
- "luxon": "~3.7.1",
81
- "react": "^19",
82
- "react-dom": "^19",
83
- "react-router-dom": "^7",
84
- "zod": "^4"
137
+ "@emotion/react": "^11.14.0",
138
+ "@emotion/styled": "^11.14.1",
139
+ "@mui/icons-material": "^7.3.10",
140
+ "@mui/material": "^7.3.10",
141
+ "@mui/system": "^7.3.10",
142
+ "@mui/x-tree-view": "~8.27.2",
143
+ "@opentelemetry/api": "^1.9.1",
144
+ "@opentelemetry/sdk-trace-base": "^2.7.0",
145
+ "@scure/base": "~2.2.0",
146
+ "@textea/json-viewer": "~4.0.1",
147
+ "@xylabs/react-async-effect": "~7.1.20",
148
+ "@xylabs/react-button": "~7.1.20",
149
+ "@xylabs/react-dialogs": "~7.1.20",
150
+ "@xylabs/react-flexbox": "~7.1.20",
151
+ "@xylabs/react-hooks": "~7.1.20",
152
+ "@xylabs/react-identicon": "~7.1.20",
153
+ "@xylabs/react-link": "~7.1.20",
154
+ "@xylabs/react-promise": "~7.1.20",
155
+ "@xylabs/react-quick-tip-button": "~7.1.20",
156
+ "@xylabs/react-select": "~7.1.20",
157
+ "@xylabs/react-shared": "~7.1.20",
158
+ "@xylabs/react-theme": "~7.1.20",
159
+ "@xylabs/sdk-js": "^5.0.100",
160
+ "@xylabs/tsconfig": "^7.11.9",
161
+ "@xylabs/tsconfig-dom": "^7.11.9",
162
+ "@xylabs/zod": "~5.0.100",
163
+ "@xyo-network/account": "~5.5.1",
164
+ "@xyo-network/account-model": "^5.5.1",
165
+ "@xyo-network/boundwitness-builder": "^5.5.1",
166
+ "@xyo-network/boundwitness-model": "^5.5.1",
167
+ "@xyo-network/boundwitness-validator": "^5.5.1",
168
+ "@xyo-network/boundwitness-wrapper": "~5.5.1",
169
+ "@xyo-network/config-payload-plugin": "~5.5.1",
170
+ "@xyo-network/diviner-forecasting-model": "~5.5.5",
171
+ "@xyo-network/diviner-model": "^5.5.5",
172
+ "@xyo-network/diviner-schema-list": "~5.5.5",
173
+ "@xyo-network/diviner-schema-stats": "~5.5.2",
174
+ "@xyo-network/manifest-model": "~5.5.1",
175
+ "@xyo-network/module-abstract": "^5.5.5",
176
+ "@xyo-network/module-model": "^5.5.5",
177
+ "@xyo-network/node-core-types": "~4.1.10",
178
+ "@xyo-network/node-memory": "~5.5.5",
179
+ "@xyo-network/node-model": "^5.5.5",
180
+ "@xyo-network/payload-builder": "^5.5.1",
181
+ "@xyo-network/payload-model": "^5.5.1",
182
+ "@xyo-network/payload-validator": "^5.5.1",
183
+ "@xyo-network/query-payload-plugin": "~5.5.1",
184
+ "@xyo-network/schema-cache": "~5.5.1",
185
+ "@xyo-network/schema-payload-plugin": "~5.5.1",
186
+ "@xyo-network/typeof": "~5.3.30",
187
+ "@xyo-network/wallet-model": "^5.5.1",
188
+ "ajv": "^8.18.0",
189
+ "async-mutex": "^0.5.0",
190
+ "axios": "^1.15.2",
191
+ "bn.js": "^5.2.3",
192
+ "bowser": "^2.14.1",
193
+ "buffer": "^6.0.3",
194
+ "chalk": "^5.6.2",
195
+ "chart.js": "^4.5.1",
196
+ "chartjs-adapter-luxon": "~1.3.1",
197
+ "ethers": "^6.16.0",
198
+ "fast-deep-equal": "~3.1.3",
199
+ "js-cookie": "~3.0.5",
200
+ "lru-cache": "^11.3.5",
201
+ "luxon": "^3.7.2",
202
+ "pako": "^2.1.0",
203
+ "react": "^19.2.5",
204
+ "react-chartjs-2": "~5.3.1",
205
+ "react-dom": "^19.2.5",
206
+ "react-router-dom": "^7.14.2",
207
+ "spark-md5": "~3.0.2",
208
+ "zod": "^4.3.6"
85
209
  },
86
210
  "publishConfig": {
87
211
  "access": "public"
88
212
  },
89
213
  "docs": "dist/docs.json"
90
- }
214
+ }
package/src/Plugin.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { PayloadRenderPlugin } from '@xyo-network/react-payload-plugin'
2
- import { createPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'
3
-
4
- import { PriceForecastDetailsBox } from './components/index.ts'
5
-
6
- export const PriceForecastRenderPlugin: PayloadRenderPlugin = {
7
- ...createPayloadRenderPlugin({
8
- canRender: () => true,
9
- components: { box: { detailsBox: PriceForecastDetailsBox } },
10
- name: 'PriceForecast',
11
- }),
12
- }
@@ -1,78 +0,0 @@
1
- import {
2
- Button, ButtonGroup, Typography,
3
- } from '@mui/material'
4
- import type { Meta, StoryFn } from '@storybook/react-vite'
5
- import { FlexCol } from '@xylabs/react-flexbox'
6
- import { ForecastPayloadSchema } from '@xyo-network/diviner-forecasting-model'
7
- import type { RefObject } from 'react'
8
- import React, { useRef, useState } from 'react'
9
-
10
- import { MockSourcePayloads } from '../lib/index.ts'
11
- import { PriceForecastDetailsBox } from './DetailsBox.tsx'
12
-
13
- const tenMin = 600_000
14
-
15
- const ForecastingDivinerPayload = {
16
- schema: ForecastPayloadSchema,
17
- values: [1, 2, 3, 4, 5, 6, 7, 8].map(item => ({
18
- error: 0,
19
- timestamp: Date.now() + tenMin * item,
20
- value: 100 * item,
21
- })),
22
- }
23
-
24
- const StorybookEntry = {
25
- argTypes: {},
26
- component: PriceForecastDetailsBox,
27
- parameters: { docs: { page: null } },
28
- title: 'plugin/price-forecast/DetailsBox',
29
- } as Meta<typeof PriceForecastDetailsBox>
30
-
31
- const Template: StoryFn<typeof PriceForecastDetailsBox> = ({ payload, ...args }) => {
32
- const [showPayloads, setShowPayloads] = useState(false)
33
- const forecastPayloadRef = useRef<HTMLParagraphElement>(null)
34
- const sourcePayloadsRef = useRef<HTMLParagraphElement>(null)
35
- const handleClick = (ref: RefObject<HTMLParagraphElement | null>) => {
36
- setShowPayloads(!showPayloads)
37
- if (ref.current) ref.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
38
- }
39
- return (
40
- <>
41
- <PriceForecastDetailsBox mb={3} payload={payload} {...args} />
42
- <FlexCol>
43
- <ButtonGroup>
44
- <Button variant="contained" onClick={() => handleClick(forecastPayloadRef)}>
45
- Forecast Payload
46
- </Button>
47
- <Button variant="contained" onClick={() => handleClick(sourcePayloadsRef)}>
48
- Source Payloads
49
- </Button>
50
- </ButtonGroup>
51
- </FlexCol>
52
- <pre>
53
- <Typography ref={forecastPayloadRef}>
54
- ForecastPayload:
55
- {' '}
56
- <code>{JSON.stringify(payload, null, 2)}</code>
57
- </Typography>
58
- </pre>
59
- <pre>
60
- <Typography ref={sourcePayloadsRef}>
61
- SourcePayloads:
62
- {' '}
63
- <pre>{JSON.stringify(MockSourcePayloads(), null, 2)}</pre>
64
- </Typography>
65
- </pre>
66
- </>
67
- )
68
- }
69
-
70
- const Default = Template.bind({})
71
- Default.args = {}
72
-
73
- const WithData = Template.bind({})
74
- WithData.args = { payload: ForecastingDivinerPayload }
75
-
76
- export { Default, WithData }
77
-
78
- export default StorybookEntry
@@ -1,60 +0,0 @@
1
- import 'chartjs-adapter-luxon'
2
-
3
- import { useTheme } from '@mui/material'
4
- import { useAsyncEffect } from '@xylabs/react-async-effect'
5
- import type { FlexBoxProps } from '@xylabs/react-flexbox'
6
- import { FlexCol } from '@xylabs/react-flexbox'
7
- import type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'
8
- import type { Payload } from '@xyo-network/payload-model'
9
- import type {
10
- ChartData,
11
- ChartOptions,
12
- } from 'chart.js'
13
- import {
14
- CategoryScale,
15
- Chart as ChartJS,
16
- Legend,
17
- LinearScale,
18
- LineElement,
19
- PointElement,
20
- TimeScale,
21
- Title,
22
- Tooltip,
23
- } from 'chart.js'
24
- import React, { useState } from 'react'
25
- import { Line } from 'react-chartjs-2'
26
-
27
- import { ForecastLineChartConfigBuilder } from '../lib/index.ts'
28
-
29
- ChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend)
30
-
31
- export interface PriceForecastDetailsBoxProps extends FlexBoxProps {
32
- payload?: Payload
33
- }
34
-
35
- export const PriceForecastDetailsBox: React.FC<PriceForecastDetailsBoxProps> = ({ payload, ...props }) => {
36
- const priceForecastPayload = payload as ForecastPayload | undefined
37
- const theme = useTheme()
38
- const [data, setData] = useState<ChartData<'line'>>({ datasets: [] })
39
- const [options, setOptions] = useState<ChartOptions<'line'>>({})
40
-
41
- useAsyncEffect(
42
-
43
- async (mounted) => {
44
- const { data, options } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true })
45
- if (mounted()) {
46
- setData(data)
47
- setOptions(options)
48
- }
49
- },
50
- [priceForecastPayload, theme],
51
- )
52
-
53
- return (
54
- <FlexCol {...props} busy={priceForecastPayload === undefined} minHeight="25vh">
55
- {priceForecastPayload
56
- ? <Line options={options} data={data} />
57
- : null}
58
- </FlexCol>
59
- )
60
- }
@@ -1 +0,0 @@
1
- export * from './DetailsBox.tsx'
package/src/global.d.ts DELETED
@@ -1 +0,0 @@
1
- import '@mui/material/themeCssVarsAugmentation'
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './components/index.ts'
2
- export * from './Plugin.ts'
@@ -1,6 +0,0 @@
1
- import { alphaCss } from '@xylabs/react-theme'
2
-
3
- export const DataLineStyles = (color?: string) => ({
4
- backgroundColor: color ? alphaCss(color, 0.5) : undefined,
5
- borderColor: color,
6
- })
@@ -1,7 +0,0 @@
1
- export const DataPointStyles = (pointHoverBackgroundColor?: string) => ({
2
- pointHitRadius: 20,
3
- pointHoverBackgroundColor,
4
- pointHoverRadius: 10,
5
- pointRadius: 5,
6
- pointStyle: 'circle',
7
- })
@@ -1,162 +0,0 @@
1
- import type { Theme } from '@mui/material'
2
- import { useIsDark } from '@xylabs/react-theme'
3
- import type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'
4
- import type {
5
- ChartData, ChartDataset, ChartOptions, LegendOptions, Point, ScaleChartOptions,
6
- } from 'chart.js'
7
-
8
- import { DataLineStyles } from './DataLineStyles.ts'
9
- import { DataPointStyles } from './DataPointStyles.ts'
10
- import { SourcePayloads } from './SourcePayloads.ts'
11
-
12
- interface SourcePayloadConfig {
13
- fetch: boolean
14
- sampleSize?: number
15
- }
16
-
17
- interface ThemeColors {
18
- dataSetColorPrimary: string
19
- dataSetColorSecondary: string
20
- gridColor: string
21
- }
22
-
23
- const defaultOptions: () => ChartOptions<'line'> = () => ({
24
- plugins: { legend: { position: 'top' as const } },
25
- responsive: true,
26
- })
27
-
28
- export class ForecastLineChartConfigBuilder {
29
- data: ChartData<'line'> = { datasets: [] }
30
-
31
- options: ChartOptions<'line'> = defaultOptions()
32
- themeColors: ThemeColors | undefined
33
-
34
- private payload?: ForecastPayload
35
-
36
- constructor(
37
- theme: Theme,
38
- payload?: ForecastPayload,
39
- ) {
40
- this.payload = payload
41
- this.themeColors = this.parseTheme(theme)
42
- }
43
-
44
- get forecastPayload() {
45
- if (this.payload) {
46
- return this.payload
47
- } else {
48
- throw new Error('ForecastPayload was not defined')
49
- }
50
- }
51
-
52
- static async create(theme: Theme, payload?: ForecastPayload, sourcePayloadConfig?: SourcePayloadConfig) {
53
- const instance = new ForecastLineChartConfigBuilder(theme, payload)
54
-
55
- await instance.build(sourcePayloadConfig?.fetch)
56
-
57
- instance.refreshValues()
58
-
59
- return instance
60
- }
61
-
62
- async build(includeSources?: boolean) {
63
- this.buildOptions()
64
- await this.buildData(includeSources)
65
- return this
66
- }
67
-
68
- async buildData(includeSources?: boolean) {
69
- const forecastData = this.generateDataSetForecastData()
70
-
71
- const datasets: ChartDataset<'line'>[] = [forecastData]
72
-
73
- if (includeSources) {
74
- // build data from sources in forecastPayload
75
- const sourceData = await this.generateDataSetSourcePayloads()
76
- datasets.unshift(sourceData)
77
-
78
- // add last source point as first item in prediction to connect the lines
79
- const lastSourceDataItem = sourceData.data.at(-1) as Point
80
- forecastData.data.unshift(lastSourceDataItem)
81
- }
82
-
83
- this.data = { datasets }
84
-
85
- return this
86
- }
87
-
88
- buildOptions() {
89
- if (this.options.plugins) {
90
- this.options.plugins.title = this.generateTitle()
91
- this.options.plugins.legend = this.generateLegend()
92
- }
93
- this.options.scales = this.generateScales()
94
-
95
- return this
96
- }
97
-
98
- refreshValues() {
99
- this.data = { ...this.data }
100
- this.options = { ...this.options }
101
- }
102
-
103
- protected generateLegend() {
104
- return {
105
- labels: {
106
- pointStyle: 'circle',
107
- usePointStyle: true,
108
- },
109
- } as LegendOptions<'line'>
110
- }
111
-
112
- protected generateScales() {
113
- return {
114
- x: {
115
- grid: { color: this.themeColors?.gridColor },
116
- time: { unit: 'minute' },
117
- type: 'time',
118
- },
119
- y: { grid: { color: this.themeColors?.gridColor } },
120
- } as unknown as ScaleChartOptions<'line'>['scales']
121
- }
122
-
123
- protected generateTitle() {
124
- return {
125
- display: true,
126
- text: `Gas Price Forecaster (GWEI over time from ${
127
- this.forecastPayload?.values[0].timestamp ? new Date(this.forecastPayload.values[0].timestamp).toLocaleDateString() : ''
128
- })`,
129
- }
130
- }
131
-
132
- protected parseTheme(theme: Theme) {
133
- // eslint-disable-next-line react-x/rules-of-hooks, react-hooks/rules-of-hooks
134
- const dark = useIsDark()
135
- return {
136
- dataSetColorPrimary: theme.vars.palette.primary.light,
137
- dataSetColorSecondary: theme.vars.palette.secondary.light,
138
- gridColor: dark ? theme.vars.palette.grey[800] : theme.vars.palette.grey[300],
139
- }
140
- }
141
-
142
- private generateDataSetForecastData(): ChartDataset<'line'> {
143
- return {
144
- borderDash: [5],
145
- borderDashOffset: 0.5,
146
- data: this.forecastPayload.values.map(price => ({ x: price.timestamp ?? 0, y: price.value })),
147
- label: 'Forecast Price',
148
- ...DataPointStyles(this.themeColors?.dataSetColorPrimary),
149
- ...DataLineStyles(this.themeColors?.dataSetColorPrimary),
150
- }
151
- }
152
-
153
- private async generateDataSetSourcePayloads(): Promise<ChartDataset<'line'>> {
154
- const { sourcePrices } = await SourcePayloads.build('feePerGas.medium')
155
- return {
156
- data: sourcePrices,
157
- label: 'Source Prices',
158
- ...DataLineStyles(this.themeColors?.dataSetColorSecondary),
159
- ...DataPointStyles(this.themeColors?.dataSetColorSecondary),
160
- }
161
- }
162
- }
@@ -1,29 +0,0 @@
1
- import { asSchema } from '@xyo-network/payload-model'
2
-
3
- export const MockSourcePayloads = () => {
4
- const tenMin = 600_000
5
- return [
6
- {
7
- baseFee: 38.901_553_878_25,
8
- feePerGas: {
9
- high: 47.994_586_439_6, low: 39.006_868_093, medium: 39.306_868_093, veryHigh: 44.453_843_805_25,
10
- },
11
- priorityFeePerGas: {
12
- high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,
13
- },
14
- schema: asSchema('network.xyo.blockchain.ethereum.gas', true),
15
- timestamp: Date.now() - tenMin,
16
- },
17
- {
18
- baseFee: 38.901_553_878_25,
19
- feePerGas: {
20
- high: 47.994_586_439_6, low: 39.006_868_093, medium: 100, veryHigh: 44.453_843_805_25,
21
- },
22
- priorityFeePerGas: {
23
- high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,
24
- },
25
- schema: asSchema('network.xyo.blockchain.ethereum.gas', true),
26
- timestamp: Date.now(),
27
- },
28
- ]
29
- }
@@ -1,50 +0,0 @@
1
- import type { Payload } from '@xyo-network/payload-model'
2
- import type { Point } from 'chart.js'
3
-
4
- import { MockSourcePayloads } from './MockSourcePayloads.ts'
5
-
6
- export class SourcePayloads {
7
- sourcePayloads: Payload[]
8
- sourcePrices: Point[] = []
9
-
10
- constructor(sourcePayloads: Payload[]) {
11
- this.sourcePayloads = sourcePayloads
12
- }
13
-
14
- get payloads() {
15
- return this.sourcePayloads
16
- }
17
-
18
- static async build(jsonPath: string) {
19
- const sourcePayloads = await this.fetchSourcePayloads()
20
- const instance = new this(sourcePayloads)
21
-
22
- const paths = jsonPath.split('.')
23
- instance.sourcePrices = sourcePayloads.map((payload) => {
24
- return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) }
25
- })
26
- return instance
27
- }
28
-
29
- // TODO - fetch from archivist
30
- static async fetchSourcePayloads() {
31
- const payloads = await Promise.resolve(MockSourcePayloads())
32
- return payloads
33
- }
34
-
35
- jsonPathTraverser(obj: Payload, path: string[]) {
36
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
- let result: any = obj
38
- for (const key of path) {
39
- if (key in result) {
40
- const foundKey = key as keyof typeof result
41
- result = result[foundKey]
42
- } else {
43
- result = undefined
44
- break
45
- }
46
- }
47
-
48
- return result
49
- }
50
- }
package/src/lib/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './ForecastLineChartConfigBuilder.ts'
2
- export * from './MockSourcePayloads.ts'
3
- export * from './SourcePayloads.ts'