@graphenedata/cli 0.0.3 → 0.0.5

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 (69) hide show
  1. package/cli.ts +7 -43
  2. package/dist/cli/cli.js +509 -277
  3. package/dist/docs/graphene.md +924 -63
  4. package/dist/ui/component-utilities/echarts.js +3 -1
  5. package/dist/ui/component-utilities/themeStores.ts +35 -7
  6. package/dist/ui/components/AreaChart.svelte +2 -1
  7. package/dist/ui/components/BarChart.svelte +2 -1
  8. package/dist/ui/components/BigValue.svelte +1 -1
  9. package/dist/ui/components/Chart.svelte +10 -1
  10. package/dist/ui/components/ECharts.svelte +2 -0
  11. package/dist/ui/components/LineChart.svelte +2 -1
  12. package/dist/ui/components/PieChart.svelte +1 -1
  13. package/dist/ui/components/QueryLoad.svelte +5 -6
  14. package/dist/ui/components/TableRow.svelte +1 -1
  15. package/dist/ui/components/_Table.svelte +2 -0
  16. package/dist/ui/internal/queryEngine.ts +16 -13
  17. package/dist/ui/internal/telemetry.ts +5 -3
  18. package/dist/ui/web.js +26 -11
  19. package/package.json +2 -1
  20. package/dist/docs/data_apps/components/charts/annotations.md +0 -673
  21. package/dist/docs/data_apps/components/charts/area-chart.md +0 -202
  22. package/dist/docs/data_apps/components/charts/bar-chart.md +0 -317
  23. package/dist/docs/data_apps/components/charts/box-plot.md +0 -190
  24. package/dist/docs/data_apps/components/charts/bubble-chart.md +0 -151
  25. package/dist/docs/data_apps/components/charts/calendar-heatmap.md +0 -112
  26. package/dist/docs/data_apps/components/charts/custom-echarts.md +0 -308
  27. package/dist/docs/data_apps/components/charts/echarts-options.md +0 -217
  28. package/dist/docs/data_apps/components/charts/funnel-chart.md +0 -106
  29. package/dist/docs/data_apps/components/charts/heatmap.md +0 -180
  30. package/dist/docs/data_apps/components/charts/histogram.md +0 -107
  31. package/dist/docs/data_apps/components/charts/line-chart.md +0 -265
  32. package/dist/docs/data_apps/components/charts/mixed-type-charts.md +0 -240
  33. package/dist/docs/data_apps/components/charts/sankey-diagram.md +0 -301
  34. package/dist/docs/data_apps/components/charts/scatter-plot.md +0 -134
  35. package/dist/docs/data_apps/components/charts/sparkline.md +0 -68
  36. package/dist/docs/data_apps/components/data/big-value.md +0 -153
  37. package/dist/docs/data_apps/components/data/delta.md +0 -89
  38. package/dist/docs/data_apps/components/data/table.md +0 -470
  39. package/dist/docs/data_apps/components/data/value.md +0 -97
  40. package/dist/docs/data_apps/components/inputs/button-group.md +0 -154
  41. package/dist/docs/data_apps/components/inputs/checkbox.md +0 -52
  42. package/dist/docs/data_apps/components/inputs/date-input.md +0 -131
  43. package/dist/docs/data_apps/components/inputs/date-range.md +0 -124
  44. package/dist/docs/data_apps/components/inputs/dimension-grid.md +0 -67
  45. package/dist/docs/data_apps/components/inputs/dropdown.md +0 -199
  46. package/dist/docs/data_apps/components/inputs/index.md +0 -3
  47. package/dist/docs/data_apps/components/inputs/slider.md +0 -126
  48. package/dist/docs/data_apps/components/inputs/text-input.md +0 -86
  49. package/dist/docs/data_apps/components/maps/area-map.md +0 -397
  50. package/dist/docs/data_apps/components/maps/base-map.md +0 -269
  51. package/dist/docs/data_apps/components/maps/bubble-map.md +0 -361
  52. package/dist/docs/data_apps/components/maps/point-map.md +0 -326
  53. package/dist/docs/data_apps/components/maps/us-map.md +0 -167
  54. package/dist/docs/data_apps/components/ui/accordion.md +0 -116
  55. package/dist/docs/data_apps/components/ui/alert.md +0 -37
  56. package/dist/docs/data_apps/components/ui/big-link.md +0 -19
  57. package/dist/docs/data_apps/components/ui/details.md +0 -58
  58. package/dist/docs/data_apps/components/ui/download-data.md +0 -41
  59. package/dist/docs/data_apps/components/ui/embed.md +0 -47
  60. package/dist/docs/data_apps/components/ui/grid.md +0 -45
  61. package/dist/docs/data_apps/components/ui/image.md +0 -61
  62. package/dist/docs/data_apps/components/ui/info.md +0 -47
  63. package/dist/docs/data_apps/components/ui/last-refreshed.md +0 -28
  64. package/dist/docs/data_apps/components/ui/link-button.md +0 -20
  65. package/dist/docs/data_apps/components/ui/link.md +0 -40
  66. package/dist/docs/data_apps/components/ui/modal.md +0 -57
  67. package/dist/docs/data_apps/components/ui/note.md +0 -32
  68. package/dist/docs/data_apps/components/ui/print-format-components.md +0 -85
  69. package/dist/docs/data_apps/components/ui/tabs.md +0 -122
@@ -12,7 +12,7 @@ import * as chartWindowDebug from './chartWindowDebug'
12
12
  * } EChartsActionOptions
13
13
  */
14
14
 
15
- const ANIMATION_DURATION = 500
15
+ const ANIMATION_DURATION = 0
16
16
  const pendingChartsKey = Symbol.for('graphene.pendingCharts')
17
17
 
18
18
  /** @returns {Set<number> | null} */
@@ -139,6 +139,7 @@ const echartsAction = (node, options) => {
139
139
  // Initial options set:
140
140
  chart.setOption({
141
141
  ...options.config,
142
+ animation: false,
142
143
  animationDuration: ANIMATION_DURATION,
143
144
  animationDurationUpdate: ANIMATION_DURATION,
144
145
  })
@@ -219,6 +220,7 @@ const echartsAction = (node, options) => {
219
220
  chart.setOption(
220
221
  {
221
222
  ...options.config,
223
+ animation: false,
222
224
  animationDuration: ANIMATION_DURATION,
223
225
  animationDurationUpdate: ANIMATION_DURATION,
224
226
  },
@@ -12,7 +12,7 @@ type ThemeStores = {
12
12
  activeAppearance: Readable<Appearance>
13
13
  theme: Readable<Theme>
14
14
  resolveColor: <T>(input: T) => Readable<T | string | undefined>
15
- resolveColorsObject: (input: Record<string, unknown> | undefined) => Readable<Record<string, string | undefined> | undefined>
15
+ resolveColorsObject: (input: Record<string, unknown> | string | undefined) => Readable<Record<string, string | undefined> | undefined>
16
16
  resolveColorPalette: (input: unknown) => Readable<string[] | undefined>
17
17
  }
18
18
 
@@ -55,6 +55,14 @@ const isReadable = <T>(value: unknown): value is Readable<T> => {
55
55
  return Boolean(value && typeof value === 'object' && 'subscribe' in (value as any))
56
56
  }
57
57
 
58
+ const parseJson = (value: string): unknown => {
59
+ try {
60
+ return JSON.parse(value)
61
+ } catch {
62
+ return undefined
63
+ }
64
+ }
65
+
58
66
  const normalizeColor = (value: unknown): string | undefined => {
59
67
  if (value == null) return undefined
60
68
  if (Array.isArray(value)) return normalizeColor(value[0])
@@ -64,25 +72,38 @@ const normalizeColor = (value: unknown): string | undefined => {
64
72
  if (!trimmed) return undefined
65
73
  if (trimmed === 'true' || trimmed === 'false') return trimmed
66
74
  if (DEFAULT_THEME.colors[trimmed]) return DEFAULT_THEME.colors[trimmed]
67
- if (trimmed.startsWith('#') || trimmed.startsWith('rgb') || trimmed.startsWith('hsl') || trimmed.startsWith('var(')) return trimmed
68
- if (/^[a-zA-Z0-9_-]+$/.test(trimmed)) return `var(--color-${trimmed})`
75
+ let lower = trimmed.toLowerCase()
76
+ if (trimmed.startsWith('#')) return trimmed
77
+ if (lower.startsWith('rgb') || lower.startsWith('hsl')) return trimmed
69
78
  return trimmed
70
79
  }
71
80
 
72
- const resolveColor = <T>(input: T): Readable<T | string | undefined> => {
81
+ export const resolveColor = <T>(input: T): Readable<T | string | undefined> => {
73
82
  if (isReadable<T | string | undefined>(input)) return input
74
83
  return readable(normalizeColor(input) as T | string | undefined)
75
84
  }
76
85
 
77
- const resolveColorsObject = (input: Record<string, unknown> | undefined): Readable<Record<string, string | undefined> | undefined> => {
86
+ export const resolveColorsObject = (input: Record<string, unknown> | string | undefined): Readable<Record<string, string | undefined> | undefined> => {
78
87
  if (isReadable<Record<string, string | undefined> | undefined>(input)) return input
79
88
  if (!input) return readable(undefined)
80
89
 
81
- let entries = Object.entries(input).map(([key, value]) => [key, normalizeColor(value)] as const)
90
+ let record: Record<string, unknown> | undefined = input as Record<string, unknown>
91
+ if (typeof input === 'string') {
92
+ let parsed = parseJson(input.trim())
93
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
94
+ record = parsed as Record<string, unknown>
95
+ } else {
96
+ return readable(undefined)
97
+ }
98
+ }
99
+
100
+ if (!record) return readable(undefined)
101
+
102
+ let entries = Object.entries(record).map(([key, value]) => [key, normalizeColor(value)] as const)
82
103
  return readable(Object.fromEntries(entries))
83
104
  }
84
105
 
85
- const resolveColorPalette = (input: unknown): Readable<string[] | undefined> => {
106
+ export const resolveColorPalette = (input: unknown): Readable<string[] | undefined> => {
86
107
  if (isReadable<string[] | undefined>(input)) return input
87
108
  if (input == null) return readable(DEFAULT_PALETTE)
88
109
 
@@ -90,6 +111,13 @@ const resolveColorPalette = (input: unknown): Readable<string[] | undefined> =>
90
111
  let key = input.trim()
91
112
  if (!key || key === 'default') return readable(DEFAULT_PALETTE)
92
113
  if (DEFAULT_THEME.colorPalettes[key]) return readable(DEFAULT_THEME.colorPalettes[key])
114
+ if (key.startsWith('[')) {
115
+ let parsed = parseJson(key)
116
+ if (Array.isArray(parsed)) {
117
+ let values = parsed.map(item => normalizeColor(item)).filter(Boolean) as string[]
118
+ return readable(values.length ? values : DEFAULT_PALETTE)
119
+ }
120
+ }
93
121
  if (key.includes(',')) {
94
122
  let values = key.split(',').map(part => normalizeColor(part)).filter(Boolean) as string[]
95
123
  return readable(values.length ? values : DEFAULT_PALETTE)
@@ -83,9 +83,10 @@
83
83
  export let xLabelWrap = undefined
84
84
  </script>
85
85
 
86
- <QueryLoad data={data} fields={[x, y, series]} let:loaded>
86
+ <QueryLoad data={data} fields={{x, y, series}} let:loaded>
87
87
  <Chart
88
88
  data={loaded}
89
+ chartContext={{data, x, y, series}}
89
90
  {x}
90
91
  {y}
91
92
  {xFmt}
@@ -114,9 +114,10 @@
114
114
  export let xLabelWrap = undefined
115
115
  </script>
116
116
 
117
- <QueryLoad data={data} fields={[x, y, y2, series]} let:loaded>
117
+ <QueryLoad data={data} fields={{x, y, y2, series}} let:loaded>
118
118
  <Chart
119
119
  data={loaded}
120
+ chartContext={{data, x, y, y2, series}}
120
121
  {x}
121
122
  {y}
122
123
  {y2}
@@ -34,7 +34,7 @@
34
34
  }
35
35
  </script>
36
36
 
37
- <QueryLoad {data} fields={[value]} let:loaded>
37
+ <QueryLoad {data} fields={{value}} let:loaded>
38
38
  <div class="big-value">
39
39
  {#if title}<div class="big-value__title">{title}</div>{/if}
40
40
  {#if subtitle}<div class="big-value__subtitle">{subtitle}</div>{/if}
@@ -23,6 +23,7 @@
23
23
  import checkInputs from '../component-utilities/checkInputs.js'
24
24
  import {getThemeStores} from '../component-utilities/themeStores'
25
25
  import {toBoolean} from '../component-utilities/convert'
26
+ import {logError} from '../internal/telemetry.ts'
26
27
 
27
28
  const {theme, resolveColor, resolveColorsObject, resolveColorPalette} = getThemeStores()
28
29
 
@@ -31,6 +32,7 @@
31
32
  // ---------------------------------------------------------------------------------------
32
33
  // Data and columns:
33
34
  export let data = undefined
35
+ export let chartContext = undefined
34
36
  export let queryID = undefined
35
37
  export let x = undefined
36
38
  export let y = undefined
@@ -1044,6 +1046,12 @@
1044
1046
  error = e.message
1045
1047
  let setTextRed = '\x1b[31m%s\x1b[0m'
1046
1048
  console.error(setTextRed, `Error in ${chartType}: ${e.message}`)
1049
+
1050
+ // Make an "id" for the chart so its clear to users/agents exactly which caused an error.
1051
+ let fieldStr = Object.entries(chartContext || {}).filter(([_, val]) => !!val).map(([name, val]) => `${name}="${val}"`)
1052
+ let id = `${title || chartType} (${fieldStr.join(' ')})`
1053
+ logError(e, {id})
1054
+
1047
1055
  props.update((d) => {
1048
1056
  return {...d, error}
1049
1057
  })
@@ -1059,11 +1067,12 @@
1059
1067
  {width}
1060
1068
  {data}
1061
1069
  {queryID}
1070
+ chartTitle={title}
1062
1071
  {echartsOptions}
1063
1072
  {seriesOptions}
1064
1073
  {connectGroup}
1065
1074
  {xAxisLabelOverflow}
1066
- seriesColors={seriesColorsStore}
1075
+ seriesColors={$seriesColorsStore}
1067
1076
  />
1068
1077
  {:else}
1069
1078
  <ErrorChart {error} title={chartType} />
@@ -16,6 +16,7 @@
16
16
  export let seriesColors: any = undefined
17
17
  export let connectGroup: string | undefined = undefined
18
18
  export let xAxisLabelOverflow: 'truncate' | 'break' | undefined = undefined
19
+ export let chartTitle: string | undefined = undefined
19
20
 
20
21
  const dispatch = createEventDispatcher()
21
22
  const isBrowser = typeof window !== 'undefined'
@@ -33,6 +34,7 @@
33
34
  {:else}
34
35
  <div
35
36
  class="echarts-chart"
37
+ data-chart-title={chartTitle ?? undefined}
36
38
  data-query-id={queryID}
37
39
  style={`height:${toDimension(height, '240px')};width:${toDimension(width, '100%')}`}
38
40
  use:echarts={{
@@ -99,9 +99,10 @@
99
99
  </script>
100
100
 
101
101
 
102
- <QueryLoad data={data} fields={[x, y, y2, series]} let:loaded>
102
+ <QueryLoad data={data} fields={{x, y, y2, series}} let:loaded>
103
103
  <Chart
104
104
  data={loaded}
105
+ chartContext={{data, x, y, y2, series}}
105
106
  {x}
106
107
  {y}
107
108
  {y2}
@@ -16,7 +16,7 @@
16
16
 
17
17
  <style></style>
18
18
 
19
- <QueryLoad data={data} fields={[category, value]} let:loaded>
19
+ <QueryLoad data={data} fields={{category, value}} let:loaded>
20
20
  <ECharts data={loaded} {echartsOptions} {seriesOptions} {seriesColors} config={{
21
21
  title: {
22
22
  text: title,
@@ -4,22 +4,21 @@
4
4
 
5
5
  export let data: string | {rows?: any[]}
6
6
  export let height = 200
7
- export let fields: string[] = []
7
+ export let fields: Record<string, string> = {}
8
8
 
9
9
  let errors: Error[] | null = null
10
10
  let loaded: any[] | null = null
11
11
 
12
- let handleResults = (data) => {
13
- errors = data.errors
14
- loaded = data.rows
12
+ let handleResults = (result) => {
13
+ errors = result.errors || null
14
+ loaded = result.rows
15
15
  }
16
16
 
17
17
  onMount(() => {
18
18
  if (typeof data !== 'string') {
19
19
  loaded = data.rows
20
20
  } else {
21
- let usedFields = fields.filter(f => !!f)
22
- if (usedFields.length == 0) usedFields = ['*']
21
+ let usedFields = Object.fromEntries(Object.entries(fields).filter(e => !!e[1]))
23
22
  window.$GRAPHENE.query(data, usedFields, handleResults)
24
23
  }
25
24
  })
@@ -251,7 +251,7 @@
251
251
  background: rgba(229, 231, 235, 0.6);
252
252
  }
253
253
 
254
- :global(.table-row--lined) td {
254
+ .table-row--lined :global(td) {
255
255
  border-bottom: 1px solid rgba(107, 114, 128, 0.2);
256
256
  }
257
257
 
@@ -15,6 +15,7 @@
15
15
  import {getFinalColumnOrder} from '../component-utilities/tableUtils'
16
16
  import {getThemeStores} from '../component-utilities/themeStores'
17
17
  import {toBoolean} from '../component-utilities/convert'
18
+ import {logError} from '../internal/telemetry.js'
18
19
 
19
20
  const {resolveColor} = getThemeStores()
20
21
 
@@ -141,6 +142,7 @@
141
142
  }
142
143
  } catch (thrown) {
143
144
  let message = thrown instanceof Error ? thrown.message : 'Unable to prepare dataset'
145
+ logError(thrown, {id: 'DataTable'})
144
146
  error = message
145
147
  if (strictBuild) throw thrown
146
148
  }
@@ -4,12 +4,6 @@
4
4
  import {cacheRead, cacheWrite, getHashes} from './clientCache'
5
5
  import {errorProvider} from './telemetry.ts'
6
6
 
7
- interface QueryError {
8
- file: string
9
- message: string
10
- from: {lineText: string}
11
- }
12
-
13
7
  interface QueryResult {
14
8
  rows?: any[]
15
9
  errors?: Error[]
@@ -25,10 +19,11 @@ type ResultHandler = (res: QueryResult) => void
25
19
 
26
20
  interface QueryNode {
27
21
  name?: string
22
+ source?: string
28
23
  contents: string
29
24
  callback?: ResultHandler
30
25
  loading: boolean
31
- fields: string[]
26
+ fields: Map<string, string>
32
27
  errors: Error[]
33
28
  }
34
29
 
@@ -38,7 +33,7 @@ let queries = [] as QueryNode[]
38
33
 
39
34
  function registerQuery (name: string, contents: string) {
40
35
  queries = queries.filter(q => q.name !== name)
41
- queries.push({name, contents, loading: false, fields: [], errors: []})
36
+ queries.push({name, contents, loading: false, fields: new Map(), errors: []})
42
37
  }
43
38
 
44
39
  function updateParam (name: string, value: any) {
@@ -46,9 +41,12 @@ function updateParam (name: string, value: any) {
46
41
  runAll() // for now, do the easy thing and reload it all
47
42
  }
48
43
 
49
- function query (source: string, fields: string[], callback: ResultHandler) {
50
- let contents = `from ${source} select ${fields.join(', ')}`
51
- queries.push({contents, callback, loading: false, fields, errors: []})
44
+ function query (source: string, fields: Record<string, string>, callback: ResultHandler) {
45
+ // using Map here because it preserves the order in which we add fields to the select, which we use when we get the result.
46
+ let map = new Map(Object.entries(fields))
47
+ let exprs = map.size > 0 ? Array.from(map.values()) : ['*']
48
+ let contents = `from ${source} select ${exprs.join(', ')}`
49
+ queries.push({contents, callback, loading: false, fields: map, errors: [], source})
52
50
  runAll()
53
51
  }
54
52
 
@@ -87,7 +85,11 @@ async function runNode (n: QueryNode) {
87
85
  } else { // request failed. Record it
88
86
  let isJson = response.headers.get('Content-Type') === 'application/json'
89
87
  let body = isJson ? await response.json() : await response.text()
90
- n.errors = Array.isArray(body) ? body : [body]
88
+ n.errors = Array.isArray(body) ? body : [{message: body}]
89
+
90
+ let fieldIds = Array.from(n.fields.entries()).map(([name, val]) => `${name}="${val}"`)
91
+ let idStr = `Query (data="${n.source}" ` + fieldIds.join(' ') + ')'
92
+ n.errors.forEach(e => e.id = idStr)
91
93
  n.callback({errors: n.errors})
92
94
  }
93
95
  } catch (e) {
@@ -113,13 +115,14 @@ function translateData (data: any, node: QueryNode) {
113
115
  let rows = data.rows || []
114
116
  rows.dataLoaded = true // evidence components need this to be set
115
117
  rows._evidenceColumnTypes = []
118
+ let requestFields = Array.from(node.fields.values())
116
119
 
117
120
  data.fields.forEach((field, index) => {
118
121
  let name = field.name
119
122
 
120
123
  // server gives names like `col_1` to unnamed expressions but we translate it back into the original expression like `avg(price)`
121
124
  if (field.name.match(/col_\d+/)) {
122
- name = node.fields[index]
125
+ name = requestFields[index]
123
126
  rows.forEach(r => {
124
127
  r[name] = r[field.name]
125
128
  delete r[field.name]
@@ -12,7 +12,9 @@ window.addEventListener('unhandledrejection', (event) => {
12
12
  staticErrors.push(event.reason)
13
13
  })
14
14
 
15
- export function error (e: Error, ctx?: any) {
15
+ export function logError (e: Error | string, ctx?: any) {
16
+ if (typeof e === 'string') e = new Error(e)
17
+ if (ctx) Object.assign(e, ctx)
16
18
  staticErrors.push(e)
17
19
  }
18
20
 
@@ -21,6 +23,6 @@ export function errorProvider (key:string, fn: ErrorProvider) {
21
23
  }
22
24
 
23
25
  export function getErrors (): Error[] {
24
- return staticErrors.concat(Object.values(errorProviders)
25
- .flatMap(p => p()))
26
+ let provided = Object.values(errorProviders).flatMap(p => p())
27
+ return staticErrors.concat(provided)
26
28
  }
package/dist/ui/web.js CHANGED
@@ -69,25 +69,41 @@ let socket = null
69
69
 
70
70
  connectWebSocket()
71
71
 
72
- async function takeScreenshot (chartName = null) {
72
+ async function captureChart (chartTitle) {
73
+ await waitForQueriesToFinish()
74
+ let errors = getErrors()
75
+ let escaped = window.CSS.escape(chartTitle)
76
+ let canvas = document.querySelector(`[data-chart-title="${escaped}"] canvas`)
77
+
78
+ if (!canvas) {
79
+ errors.push({message: `Could not find chart titled "${chartTitle}"`})
80
+ return {stillLoading: isLoading(), screenshot: null, errors}
81
+ }
82
+
83
+ return {stillLoading: isLoading(), screenshot: canvas.toDataURL('image/png'), errors}
84
+ }
85
+
86
+ async function takeScreenshot () {
87
+ await waitForQueriesToFinish()
73
88
  if (!window.html2canvas) {
74
89
  let html2canvas = await import('html2canvas')
75
90
  window.html2canvas = html2canvas.default
76
91
  }
92
+ let canvas = await window.html2canvas(document.body, {useCORS: true, allowTaint: true, scale: 1})
93
+ let errors = getErrors().map(e => ({message: e.message, id: e.id}))
94
+ return {stillLoading: isLoading(), screenshot: canvas?.toDataURL('image/png'), errors}
95
+ }
77
96
 
78
- // wait some time for queries to finish loading
97
+ async function waitForQueriesToFinish () {
79
98
  let startTime = Date.now()
80
99
  while (isLoading() && Date.now() - startTime < 20_000) {
81
100
  await new Promise(resolve => setTimeout(resolve, 100))
82
101
  }
83
-
84
- let targetElement = chartName ? document.querySelector(`[name="${chartName}"]`) : document.body
85
- let canvas = targetElement && await window.html2canvas(targetElement, {useCORS: true, allowTaint: true, scale: 1})
86
- return {stillLoading: isLoading(), screenshot: canvas?.toDataURL('image/png')}
87
102
  }
88
103
 
89
104
  function connectWebSocket () {
90
- socket = new WebSocket(`ws://${window.location.host}/graphene-ws`)
105
+ let wsUrl = `ws://${window.location.host}/_api/ws`
106
+ socket = new WebSocket(wsUrl)
91
107
  socket.onclose = () => setTimeout(connectWebSocket, 2000)
92
108
 
93
109
  socket.onopen = () => {
@@ -95,12 +111,11 @@ function connectWebSocket () {
95
111
  }
96
112
 
97
113
  socket.onmessage = async (event) => {
98
- console.log('Got message', event.data)
99
114
  let {type, requestId, chart} = JSON.parse(event.data)
100
115
 
101
- if (type === 'view') {
102
- let {screenshot, stillLoading} = await takeScreenshot(chart)
103
- socket.send(JSON.stringify({type: 'viewResponse', requestId, screenshot, stillLoading, errors: getErrors()}))
116
+ if (type === 'check') {
117
+ let result = chart ? await captureChart(chart) : await takeScreenshot()
118
+ socket.send(JSON.stringify({type: 'checkResponse', requestId, ...result}))
104
119
  }
105
120
  }
106
121
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "main": "cli.ts",
4
4
  "type": "module",
5
5
  "author": "Graphene Systems Inc",
6
- "version": "0.0.3",
6
+ "version": "0.0.5",
7
7
  "license": "Elastic-2.0",
8
8
  "engines": {
9
9
  "node": ">=16"
@@ -44,6 +44,7 @@
44
44
  "mdsvex": "^0.12.6",
45
45
  "nanoid": "3.3.8",
46
46
  "sanitize-html": "^2.17.0",
47
+ "snowflake-sdk": "^2.3.1",
47
48
  "ssf": "^0.11.2",
48
49
  "svelte": "4.2.19",
49
50
  "unist-util-visit": "4.1.2",