Skip to content

Commit f28ed9a

Browse files
committed
fix: limit auto data tables to tables of col < 100
1 parent 311b410 commit f28ed9a

File tree

3 files changed

+71
-51
lines changed

3 files changed

+71
-51
lines changed

frontend/src/lib/components/DisplayResult.svelte

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import Tooltip from './Tooltip.svelte'
3737
import HighlightTheme from './HighlightTheme.svelte'
3838
import type { DisplayResultUi } from './custom_ui'
39-
import { getContext, hasContext, createEventDispatcher, onDestroy } from 'svelte'
39+
import { getContext, hasContext, createEventDispatcher, onDestroy, untrack } from 'svelte'
4040
import { toJsonStr } from '$lib/utils'
4141
import { userStore } from '$lib/stores'
4242
import ResultStreamDisplay from './ResultStreamDisplay.svelte'
@@ -139,24 +139,25 @@
139139
140140
function isTableRowObject(json) {
141141
// check array of objects (with possible a first row of headers)
142+
return (
143+
isTableRowObjectWithoutHeaders(json, true) ||
144+
(Array.isArray(json[0]) &&
145+
json[0].length > 0 &&
146+
json[0].length <= 100 &&
147+
json[0].every((item) => typeof item === 'string') &&
148+
isTableRowObjectWithoutHeaders(json.slice(1), false))
149+
)
150+
}
151+
152+
function isTableRowObjectWithoutHeaders(json: any, checkFirst) {
142153
return (
143154
Array.isArray(json) &&
144155
json.length > 0 &&
145-
(json.every(
146-
(item) =>
147-
item && typeof item === 'object' && Object.keys(item).length > 0 && !Array.isArray(item)
148-
) ||
149-
(Array.isArray(json[0]) &&
150-
json[0].every((item) => typeof item === 'string') &&
151-
json
152-
.slice(1)
153-
.every(
154-
(item) =>
155-
item &&
156-
typeof item === 'object' &&
157-
Object.keys(item).length > 0 &&
158-
!Array.isArray(item)
159-
)))
156+
(!checkFirst ||
157+
(json[0] && typeof json[0] === 'object' && Object.keys(json[0]).length <= 100)) &&
158+
json.every((item) => {
159+
return typeof item === 'object' && Object.keys(item).length > 0 && !Array.isArray(item)
160+
})
160161
)
161162
}
162163
@@ -200,6 +201,7 @@
200201
}
201202
202203
let size = roughSizeOfObject(result)
204+
console.debug('size of object', size)
203205
// Otherwise, check if the result is too large (10kb) for json
204206
205207
if (size > TABLE_MAX_SIZE) {
@@ -479,7 +481,9 @@
479481
480482
$effect(() => {
481483
;[result]
482-
resultKind = inferResultKind(result)
484+
untrack(() => {
485+
resultKind = inferResultKind(result)
486+
})
483487
})
484488
$effect(() => {
485489
chooseToolbarLocation(

frontend/src/lib/components/table/Cell.svelte

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,42 @@
33
import { twMerge } from 'tailwind-merge'
44
import type { DatatableContext } from './DataTable.svelte'
55
6-
export let first: boolean = false
7-
export let last: boolean = false
8-
export let numeric: boolean = false
9-
export let head: boolean = false
10-
export let shouldStopPropagation: boolean = false
11-
export let selected = false
12-
export let sticky: boolean = false
13-
export let wrap: boolean = false
6+
interface Props {
7+
first?: boolean
8+
last?: boolean
9+
numeric?: boolean
10+
head?: boolean
11+
shouldStopPropagation?: boolean
12+
selected?: boolean
13+
sticky?: boolean
14+
wrap?: boolean
15+
children?: import('svelte').Snippet
16+
[key: string]: any
17+
}
18+
19+
let {
20+
first = false,
21+
last = false,
22+
numeric = false,
23+
head = false,
24+
shouldStopPropagation = false,
25+
selected = false,
26+
sticky = false,
27+
wrap = false,
28+
children,
29+
...rest
30+
}: Props = $props()
1431
1532
let Tag = head ? 'th' : 'td'
1633
1734
const { size } = getContext<DatatableContext>('datatable')
1835
</script>
1936

20-
<!-- svelte-ignore a11y-no-static-element-interactions -->
37+
<!-- svelte-ignore a11y_no_static_element_interactions -->
2138
<svelte:element
2239
this={Tag}
23-
{...$$restProps}
24-
on:click={(e) => {
40+
{...rest}
41+
onclick={(e) => {
2542
if (shouldStopPropagation) e.stopPropagation()
2643
}}
2744
class={twMerge(
@@ -41,14 +58,14 @@
4158
size === 'xs' ? 'px-1 py-1.5' : '',
4259
selected ? 'bg-blue-50 dark:bg-blue-900/50' : '',
4360
'transition-all',
44-
$$restProps.class
61+
rest.class
4562
)}
4663
>
4764
{#if sticky}
4865
<div class={twMerge(first ? 'border-r' : ' border-l ')}>
49-
<slot />
66+
{@render children?.()}
5067
</div>
5168
{:else}
52-
<slot />
69+
{@render children?.()}
5370
{/if}
5471
</svelte:element>

frontend/src/lib/utils.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ export function displayDate(
172172
}
173173
const dateChoices: Intl.DateTimeFormatOptions = displayDate
174174
? {
175-
day: 'numeric',
176-
month: 'numeric'
177-
}
175+
day: 'numeric',
176+
month: 'numeric'
177+
}
178178
: {}
179179
return date.toLocaleString(undefined, {
180180
...timeChoices,
@@ -1065,38 +1065,37 @@ export async function tryEvery({
10651065
try {
10661066
await tryCode()
10671067
break
1068-
} catch (err) {}
1068+
} catch (err) { }
10691069
i++
10701070
}
10711071
if (i >= times) {
10721072
timeoutCode()
10731073
}
10741074
}
1075-
1076-
export function roughSizeOfObject(object: object | string) {
1077-
if (typeof object == 'string') {
1075+
export function roughSizeOfObject(object: object | string | any) {
1076+
if (typeof object === 'string') {
10781077
return object.length * 2
10791078
}
10801079

1081-
var objectList: any[] = []
1082-
var stack = [object]
1083-
var bytes = 0
1080+
const visited = new Set<object>()
1081+
const stack = [object]
1082+
let bytes = 0
10841083

10851084
while (stack.length) {
1086-
let value: any = stack.pop()
1085+
const value = stack.pop()
10871086

10881087
if (typeof value === 'boolean') {
10891088
bytes += 4
10901089
} else if (typeof value === 'string') {
10911090
bytes += value.length * 2
10921091
} else if (typeof value === 'number') {
10931092
bytes += 8
1094-
} else if (typeof value === 'object' && objectList.indexOf(value) === -1) {
1095-
objectList.push(value)
1093+
} else if (typeof value === 'object' && value !== null && !visited.has(value)) {
1094+
visited.add(value)
10961095

1097-
for (var i in value) {
1098-
bytes += 2 * i.length
1099-
stack.push(value[i])
1096+
for (const key in value) {
1097+
bytes += 2 * key.length
1098+
stack.push(value[key])
11001099
}
11011100
}
11021101
}
@@ -1332,7 +1331,7 @@ export function conditionalMelt(node: HTMLElement, meltItem: AnyMeltElement | un
13321331
if (meltItem) {
13331332
return meltItem(node)
13341333
}
1335-
return { destroy: () => {} }
1334+
return { destroy: () => { } }
13361335
}
13371336

13381337
export type Item = {
@@ -1538,9 +1537,9 @@ export type S3Uri = `s3://${string}/${string}`
15381537
export type S3Object =
15391538
| S3Uri
15401539
| {
1541-
s3: string
1542-
storage?: string
1543-
}
1540+
s3: string
1541+
storage?: string
1542+
}
15441543

15451544
export function parseS3Object(s3Object: S3Object): { s3: string; storage?: string } {
15461545
if (typeof s3Object === 'object') return s3Object

0 commit comments

Comments
 (0)