@xylabs/sdk-react 2.8.4 → 2.9.3

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 (107) hide show
  1. package/dist/components/BasePage/BasePage.js +2 -2
  2. package/dist/components/BasePage/BasePage.js.map +1 -1
  3. package/dist/components/BasePage/BasePage.stories.js +4 -0
  4. package/dist/components/BasePage/BasePage.stories.js.map +1 -1
  5. package/dist/components/BasePage/BasePageProps.d.ts +2 -0
  6. package/dist/components/Experiments/Experiment.d.ts +1 -0
  7. package/dist/components/Experiments/Experiment.js.map +1 -1
  8. package/dist/components/Experiments/Experiments.d.ts +3 -8
  9. package/dist/components/Experiments/Experiments.js +18 -2
  10. package/dist/components/Experiments/Experiments.js.map +1 -1
  11. package/dist/components/Experiments/Experiments.stories.d.ts +6 -0
  12. package/dist/components/Experiments/Experiments.stories.js +27 -0
  13. package/dist/components/Experiments/Experiments.stories.js.map +1 -0
  14. package/dist/components/Experiments/ExperimentsDebugger.d.ts +3 -0
  15. package/dist/components/Experiments/ExperimentsDebugger.js +37 -0
  16. package/dist/components/Experiments/ExperimentsDebugger.js.map +1 -0
  17. package/dist/components/Experiments/ExperimentsDebugger.stories.d.ts +6 -0
  18. package/dist/components/Experiments/ExperimentsDebugger.stories.js +20 -0
  19. package/dist/components/Experiments/ExperimentsDebugger.stories.js.map +1 -0
  20. package/dist/components/Experiments/ExperimentsProps.d.ts +7 -0
  21. package/dist/components/Experiments/ExperimentsProps.js +2 -0
  22. package/dist/components/Experiments/ExperimentsProps.js.map +1 -0
  23. package/dist/components/Experiments/index.d.ts +2 -1
  24. package/dist/components/Experiments/index.js +2 -1
  25. package/dist/components/Experiments/index.js.map +1 -1
  26. package/dist/components/Experiments/models/index.d.ts +12 -0
  27. package/dist/components/Experiments/models/index.js +3 -0
  28. package/dist/components/Experiments/models/index.js.map +1 -0
  29. package/dist/components/dialogs/ErrorDialog.d.ts +1 -1
  30. package/dist/components/dialogs/ErrorDialog.js.map +1 -1
  31. package/dist/esm2017/components/BasePage/BasePageProps.d.ts +2 -0
  32. package/dist/esm2017/components/Experiments/Experiment.d.ts +1 -0
  33. package/dist/esm2017/components/Experiments/Experiments.d.ts +3 -8
  34. package/dist/esm2017/components/Experiments/Experiments.stories.d.ts +6 -0
  35. package/dist/esm2017/components/Experiments/ExperimentsDebugger.d.ts +3 -0
  36. package/dist/esm2017/components/Experiments/ExperimentsDebugger.stories.d.ts +6 -0
  37. package/dist/esm2017/components/Experiments/ExperimentsProps.d.ts +7 -0
  38. package/dist/esm2017/components/Experiments/index.d.ts +2 -1
  39. package/dist/esm2017/components/Experiments/models/index.d.ts +12 -0
  40. package/dist/esm2017/components/dialogs/ErrorDialog.d.ts +1 -1
  41. package/dist/esm2017/hooks/index.d.ts +1 -0
  42. package/dist/esm2017/hooks/useLocalStorage.d.ts +1 -0
  43. package/dist/esm2017/index.js +84 -6
  44. package/dist/esm2017/index.js.map +1 -1
  45. package/dist/esm5/components/BasePage/BasePageProps.d.ts +2 -0
  46. package/dist/esm5/components/Experiments/Experiment.d.ts +1 -0
  47. package/dist/esm5/components/Experiments/Experiments.d.ts +3 -8
  48. package/dist/esm5/components/Experiments/Experiments.stories.d.ts +6 -0
  49. package/dist/esm5/components/Experiments/ExperimentsDebugger.d.ts +3 -0
  50. package/dist/esm5/components/Experiments/ExperimentsDebugger.stories.d.ts +6 -0
  51. package/dist/esm5/components/Experiments/ExperimentsProps.d.ts +7 -0
  52. package/dist/esm5/components/Experiments/index.d.ts +2 -1
  53. package/dist/esm5/components/Experiments/models/index.d.ts +12 -0
  54. package/dist/esm5/components/dialogs/ErrorDialog.d.ts +1 -1
  55. package/dist/esm5/hooks/index.d.ts +1 -0
  56. package/dist/esm5/hooks/useLocalStorage.d.ts +1 -0
  57. package/dist/esm5/index.js +84 -6
  58. package/dist/esm5/index.js.map +1 -1
  59. package/dist/hooks/index.d.ts +1 -0
  60. package/dist/hooks/index.js +1 -0
  61. package/dist/hooks/index.js.map +1 -1
  62. package/dist/hooks/useLocalStorage.d.ts +1 -0
  63. package/dist/hooks/useLocalStorage.js +23 -0
  64. package/dist/hooks/useLocalStorage.js.map +1 -0
  65. package/dist/node/components/BasePage/BasePageProps.d.ts +2 -0
  66. package/dist/node/components/Experiments/Experiment.d.ts +1 -0
  67. package/dist/node/components/Experiments/Experiments.d.ts +3 -8
  68. package/dist/node/components/Experiments/Experiments.stories.d.ts +6 -0
  69. package/dist/node/components/Experiments/ExperimentsDebugger.d.ts +3 -0
  70. package/dist/node/components/Experiments/ExperimentsDebugger.stories.d.ts +6 -0
  71. package/dist/node/components/Experiments/ExperimentsProps.d.ts +7 -0
  72. package/dist/node/components/Experiments/index.d.ts +2 -1
  73. package/dist/node/components/Experiments/models/index.d.ts +12 -0
  74. package/dist/node/components/dialogs/ErrorDialog.d.ts +1 -1
  75. package/dist/node/hooks/index.d.ts +1 -0
  76. package/dist/node/hooks/useLocalStorage.d.ts +1 -0
  77. package/dist/node/index.js +84 -4
  78. package/dist/node/index.js.map +1 -1
  79. package/dist/node-esm/components/BasePage/BasePageProps.d.ts +2 -0
  80. package/dist/node-esm/components/Experiments/Experiment.d.ts +1 -0
  81. package/dist/node-esm/components/Experiments/Experiments.d.ts +3 -8
  82. package/dist/node-esm/components/Experiments/Experiments.stories.d.ts +6 -0
  83. package/dist/node-esm/components/Experiments/ExperimentsDebugger.d.ts +3 -0
  84. package/dist/node-esm/components/Experiments/ExperimentsDebugger.stories.d.ts +6 -0
  85. package/dist/node-esm/components/Experiments/ExperimentsProps.d.ts +7 -0
  86. package/dist/node-esm/components/Experiments/index.d.ts +2 -1
  87. package/dist/node-esm/components/Experiments/models/index.d.ts +12 -0
  88. package/dist/node-esm/components/dialogs/ErrorDialog.d.ts +1 -1
  89. package/dist/node-esm/hooks/index.d.ts +1 -0
  90. package/dist/node-esm/hooks/useLocalStorage.d.ts +1 -0
  91. package/dist/node-esm/index.js +84 -6
  92. package/dist/node-esm/index.js.map +1 -1
  93. package/package.json +12 -13
  94. package/src/components/BasePage/BasePage.stories.tsx +5 -0
  95. package/src/components/BasePage/BasePage.tsx +3 -0
  96. package/src/components/BasePage/BasePageProps.ts +2 -0
  97. package/src/components/Experiments/Experiment.tsx +1 -0
  98. package/src/components/Experiments/Experiments.stories.tsx +35 -0
  99. package/src/components/Experiments/Experiments.tsx +21 -10
  100. package/src/components/Experiments/ExperimentsDebugger.stories.tsx +24 -0
  101. package/src/components/Experiments/ExperimentsDebugger.tsx +71 -0
  102. package/src/components/Experiments/ExperimentsProps.ts +9 -0
  103. package/src/components/Experiments/index.tsx +2 -1
  104. package/src/components/Experiments/models/index.ts +8 -0
  105. package/src/components/dialogs/ErrorDialog.tsx +0 -1
  106. package/src/hooks/index.ts +1 -0
  107. package/src/hooks/useLocalStorage.ts +24 -0
@@ -0,0 +1,35 @@
1
+ import { ComponentMeta, ComponentStory } from '@storybook/react'
2
+
3
+ import { Experiment } from './Experiment'
4
+ import { Experiments } from './Experiments'
5
+
6
+ const StorybookEntry = {
7
+ argTypes: {},
8
+ component: Experiments,
9
+ parameters: {
10
+ docs: {
11
+ page: null,
12
+ },
13
+ },
14
+ title: 'Components/Experiments',
15
+ } as ComponentMeta<typeof Experiments>
16
+
17
+ const Template: ComponentStory<typeof Experiments> = (args) => <Experiments {...args}></Experiments>
18
+
19
+ const Default = Template.bind({})
20
+ Default.args = {
21
+ children: [
22
+ <Experiment weight={50} key={'true'}>
23
+ True
24
+ </Experiment>,
25
+ <Experiment weight={50} key={'false'}>
26
+ False
27
+ </Experiment>,
28
+ ],
29
+ name: 'StorybookAB',
30
+ }
31
+
32
+ export { Default }
33
+
34
+ // eslint-disable-next-line import/no-default-export
35
+ export default StorybookEntry
@@ -4,18 +4,20 @@ import React, { ReactElement, useContext } from 'react'
4
4
  import { UserEventsContext } from '../../contexts'
5
5
  import { getLocalStorageObject, setLocalStorageObject } from '../../lib'
6
6
  import { ExperimentProps } from './Experiment'
7
+ import { ExperimentsProps } from './ExperimentsProps'
8
+ import { ExperimentsData, ExperimentsLocalStorageKey, OutcomesData, OutcomesLocalStorageKey } from './models'
7
9
 
8
10
  const defaultLocalStorageKey = 'testData'
9
11
 
10
12
  const experimentsTestData: { [index: string]: string } = {}
11
- let outcomes: { [index: string]: number } = {} //prevent multi-outcome
13
+ let outcomes: OutcomesData = {} //prevent multi-outcome
12
14
 
13
15
  const saveOutcomes = () => {
14
- setLocalStorageObject('outcomes', outcomes)
16
+ setLocalStorageObject(OutcomesLocalStorageKey, outcomes)
15
17
  }
16
18
 
17
19
  const loadOutcomes = () => {
18
- outcomes = getLocalStorageObject('outcomes')
20
+ outcomes = getLocalStorageObject(OutcomesLocalStorageKey)
19
21
  }
20
22
 
21
23
  const mergeData = (data: { [index: string]: string }, log?: Log) => {
@@ -27,12 +29,6 @@ const mergeData = (data: { [index: string]: string }, log?: Log) => {
27
29
  return dataArray.join('|')
28
30
  }
29
31
 
30
- type Props = {
31
- children: ReactElement<ExperimentProps>[] | ReactElement<ExperimentProps>
32
- localStorageProp?: string | boolean
33
- name: string
34
- }
35
-
36
32
  const missingKeyError = new Error('Experiment Elements must have Keys')
37
33
 
38
34
  const makeChildrenArray = (children: ReactElement<ExperimentProps>[] | ReactElement<ExperimentProps>) => {
@@ -59,7 +55,19 @@ const calcTotalWeight = (childList: ReactElement<ExperimentProps>[]) => {
59
55
  return totalWeight
60
56
  }
61
57
 
62
- const Experiments: React.FC<Props> = (props) => {
58
+ const saveExperimentDebugRanges = (name: string, totalWeight: number, childList: ReactElement<ExperimentProps>[]) => {
59
+ const experiments = getLocalStorageObject<ExperimentsData>(ExperimentsLocalStorageKey) || {}
60
+ experiments[name] = {
61
+ totalWeight,
62
+ variants: childList.map((child) => ({
63
+ name: child.key?.toString(),
64
+ weight: child.props.weight,
65
+ })),
66
+ }
67
+ setLocalStorageObject(ExperimentsLocalStorageKey, experiments)
68
+ }
69
+
70
+ const Experiments: React.FC<ExperimentsProps> = (props) => {
63
71
  const { name, children, localStorageProp = true } = props
64
72
  const userEventsContext = useContext(UserEventsContext)
65
73
  const { userEvents } = userEventsContext
@@ -71,10 +79,13 @@ const Experiments: React.FC<Props> = (props) => {
71
79
 
72
80
  const totalWeight = calcTotalWeight(childList)
73
81
 
82
+ saveExperimentDebugRanges(name, totalWeight, childList)
83
+
74
84
  const firstTime = outcomes[name] === undefined
75
85
  let targetWeight = outcomes[name] ?? Math.random() * totalWeight
76
86
  outcomes[name] = targetWeight
77
87
  saveOutcomes()
88
+
78
89
  for (const child of childList) {
79
90
  targetWeight -= child.props.weight
80
91
  if (targetWeight > 0) continue
@@ -0,0 +1,24 @@
1
+ import { ComponentMeta, ComponentStory } from '@storybook/react'
2
+
3
+ import { ExperimentsDebugger } from './index'
4
+
5
+ const StorybookEntry = {
6
+ argTypes: {},
7
+ component: ExperimentsDebugger,
8
+ parameters: {
9
+ docs: {
10
+ page: null,
11
+ },
12
+ },
13
+ title: 'Components/ExperimentsDebugger',
14
+ } as ComponentMeta<typeof ExperimentsDebugger>
15
+
16
+ const Template: ComponentStory<typeof ExperimentsDebugger> = (args) => <ExperimentsDebugger {...args} />
17
+
18
+ const Default = Template.bind({})
19
+ Default.args = {}
20
+
21
+ export { Default }
22
+
23
+ // eslint-disable-next-line import/no-default-export
24
+ export default StorybookEntry
@@ -0,0 +1,71 @@
1
+ import { Slider, Typography } from '@mui/material'
2
+ import React from 'react'
3
+
4
+ import { useLocalStorage } from '../../hooks'
5
+ import { FlexCol, FlexRow } from '../FlexBox'
6
+ import {
7
+ ExperimentsData,
8
+ ExperimentsLocalStorageKey,
9
+ OutcomesData,
10
+ OutcomesLocalStorageKey,
11
+ VariantData,
12
+ } from './models'
13
+
14
+ const ExperimentsDebugger: React.FC = ({ ...props }) => {
15
+ const [experiments] = useLocalStorage<ExperimentsData>(ExperimentsLocalStorageKey, {})
16
+ const [outcomes, setOutcomes] = useLocalStorage<OutcomesData>(OutcomesLocalStorageKey, {})
17
+
18
+ const sumUpVariants = (items: VariantData[]) => items.reduce((acc, curr) => acc + curr.weight, 0)
19
+ const experimentEntries = Object.entries(experiments)
20
+
21
+ if (!experiments || !experimentEntries.length) {
22
+ return (
23
+ <FlexCol alignItems="stretch" {...props}>
24
+ <Typography variant="subtitle1">No Experiments loaded</Typography>
25
+ <Typography variant="subtitle2">Visit a page with an experiment to load the data</Typography>
26
+ </FlexCol>
27
+ )
28
+ }
29
+
30
+ return (
31
+ <FlexCol alignItems="stretch" {...props}>
32
+ {Object.entries(experiments).map((data) => {
33
+ const [name, experiment] = data
34
+ const outcome = (outcomes[name] || 0) as number
35
+
36
+ const marks = [
37
+ { label: `${experiment.variants[0].name} | ${experiment.variants[0].weight}`, value: 0 },
38
+ ...experiment.variants.map(({ weight }, index) => ({
39
+ label:
40
+ index === experiment.variants.length - 1 ? 'End' : `${experiment.variants[index + 1].name} | ${weight}`,
41
+ value: index === 0 ? weight : sumUpVariants(experiment.variants.slice(0, index + 1)),
42
+ })),
43
+ ]
44
+
45
+ return (
46
+ <FlexCol key={`experiment-${name}`} alignItems="stretch" paddingX={4} marginBottom={4} {...props}>
47
+ <FlexRow>
48
+ {name}:&nbsp;{outcome}
49
+ </FlexRow>
50
+ <FlexRow>
51
+ <Slider
52
+ aria-label={`Experiment ${name}`}
53
+ defaultValue={outcome}
54
+ value={outcome}
55
+ marks={marks}
56
+ onChange={(e, value) => {
57
+ const truncated = Number((Array.isArray(value) ? value[0] : value).toFixed(2))
58
+ outcomes[name] = truncated
59
+ // Spread operator triggers rerender
60
+ setOutcomes({ ...outcomes })
61
+ }}
62
+ />
63
+ </FlexRow>
64
+ </FlexCol>
65
+ )
66
+ })}
67
+ </FlexCol>
68
+ )
69
+ }
70
+
71
+ export { ExperimentsDebugger }
@@ -0,0 +1,9 @@
1
+ import { ReactElement } from 'react'
2
+
3
+ import { ExperimentProps } from './Experiment'
4
+
5
+ export type ExperimentsProps = {
6
+ children: ReactElement<ExperimentProps>[] | ReactElement<ExperimentProps>
7
+ localStorageProp?: string | boolean
8
+ name: string
9
+ }
@@ -1,4 +1,5 @@
1
1
  import { Experiment } from './Experiment'
2
2
  import { Experiments } from './Experiments'
3
+ import { ExperimentsDebugger } from './ExperimentsDebugger'
3
4
 
4
- export { Experiment, Experiments }
5
+ export { Experiment, Experiments, ExperimentsDebugger }
@@ -0,0 +1,8 @@
1
+ export const OutcomesLocalStorageKey = 'outcomes'
2
+ export const ExperimentsLocalStorageKey = 'experiments'
3
+
4
+ export type OutcomesData = Record<string, number>
5
+
6
+ export type ExperimentsData = Record<string, ExperimentData>
7
+ export type ExperimentData = { totalWeight: number; variants: VariantData[] }
8
+ export type VariantData = { weight: number; name?: string }
@@ -1,6 +1,5 @@
1
1
  import { Dialog, DialogActions, DialogContent, DialogProps, DialogTitle, Typography } from '@mui/material'
2
2
  import { AxiosError } from 'axios'
3
- import React from 'react'
4
3
 
5
4
  import { ButtonEx } from '../ButtonEx'
6
5
  import { FlexRow } from '../FlexBox'
@@ -1,4 +1,5 @@
1
1
  export * from './useBreakpoint'
2
+ export * from './useLocalStorage'
2
3
  export * from './useMediaQuery'
3
4
  export * from './useMounted'
4
5
  export * from './useNavigateToEthAddress'
@@ -0,0 +1,24 @@
1
+ import { useState } from 'react'
2
+
3
+ import { getLocalStorageObject, setLocalStorageObject } from '../lib'
4
+
5
+ export const useLocalStorage = <T>(key: string, defaultValue: T): [T, (value: T) => void] => {
6
+ const [storedValue, setStoredValue] = useState<T>(() => {
7
+ try {
8
+ const item = getLocalStorageObject<T>(key)
9
+ return item || defaultValue
10
+ } catch (ex) {
11
+ //Error is already logged
12
+ return defaultValue
13
+ }
14
+ })
15
+
16
+ const setValue = (value: T) => {
17
+ console.log('setValue', value)
18
+ setStoredValue(value)
19
+ setLocalStorageObject(key, value)
20
+ console.log('getValue from ls', getLocalStorageObject(key))
21
+ }
22
+
23
+ return [storedValue, setValue]
24
+ }