Skip to content

Commit d38c515

Browse files
committed
feat(improvements)
1 parent 8f97414 commit d38c515

38 files changed

+2856
-4196
lines changed

biome.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
3+
"organizeImports": {
4+
"enabled": true
5+
},
6+
"formatter": {
7+
"enabled": true,
8+
"ignore": [
9+
"node_modules/**/*",
10+
"dist/**/*",
11+
".sst/**/*",
12+
"pnpm-lock.yaml"
13+
]
14+
},
15+
"linter": {
16+
"enabled": true,
17+
"rules": {
18+
"recommended": true
19+
},
20+
"ignore": [
21+
"node_modules/**/*",
22+
"dist/**/*",
23+
".sst/**/*",
24+
"pnpm-lock.yaml"
25+
]
26+
}
27+
}

bookmarks.md

+22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Bookmarks of ideas / inspiration
22

3+
## Urgent
4+
5+
- [Vega / Apache](https://observablehq.com/@vega/vega-lite-and-apache-arrow-no-plugin)
6+
- [DeepHaven](https://github.com/deephaven/web-client-ui/blob/e1c1585f688f9a5f805347fff5b1d95eaf75d065/packages/dashboard-core-plugins/src/panels/NotebookPanel.tsx#L6)
7+
- [Monaco](https://github.com/deephaven/web-client-ui/blob/0a2f054591d04dd32c4919ce90fd538638e0b563/packages/console/src/monaco/MonacoProviders.tsx#L139)
8+
- [SqlMesh](https://github.com/TobikoData/sqlmesh/blob/main/web/client/src/context/editor.ts)
9+
- [Tailwind background](https://bg.ibelick.com/?utm_source=tailkits&utm_medium=referral&utm_campaign=components)
10+
311
## Code Patterns
412

513
- [VsCode Async](https://github.com/microsoft/vscode/blob/main/src/vs/base/common/async.ts#L24)
@@ -39,6 +47,7 @@
3947
- [Inline completions](https://github.com/microsoft/vscode-extension-samples/blob/main/inline-completions/src/extension.ts)
4048
- [Semantic tokens](https://github.com/microsoft/vscode-extension-samples/tree/main/semantic-tokens-sample)
4149
- can use serialize_auto_json in DuckDB to get semantic tokens.xw
50+
- [TypeCell](https://github.com/TypeCellOS/TypeCell/blob/staging/packages/frame/src/MonacoElement.tsx)
4251

4352
## Autocompletion
4453

@@ -56,6 +65,7 @@
5665
- has syntax
5766
- [Grafana](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/src/components/Monaco/suggestions.ts)
5867
- [SQLPad](https://github.com/DiscoverForever/monaco-sqlpad/blob/master/src/core/snippets.js)
68+
- [CodeMirror](https://github.com/sekuel/codemirror-sql-duckdb)
5969

6070
- snippet ideas
6171

@@ -68,6 +78,12 @@
6878
- [DuckDB Wasm Kit](https://github.com/holdenmatt/duckdb-wasm-kit/blob/main/src/files/exportFile.ts)
6979
- useful utilities
7080
- [Falcon vis](https://github.com/cmudig/falcon-vis/blob/main/falcon-vis/src/db/arrow.ts)
81+
- [Observable data tools](https://github.com/RandomFractals/observable-data-tools/blob/main/notebooks/observable/duckdb-data-tables.omd)
82+
- [DuckDB Proxy](https://www.goblgobl.com/docs/duckdb-proxy/)
83+
84+
## Charting
85+
86+
- [Excalichart](https://github.com/excalichart/excalichart/blob/main/src/lib/io/FileStreamer.ts)
7187

7288
## Other bookmarks I made a long time ago
7389

@@ -102,6 +118,12 @@
102118
- [react-duckdb-table](https://github.com/shaunstoltz/duckdb-wasm/tree/master/packages/react-duckdb-table/src)
103119
- [pyodide](https://github.com/letterfowl/Platyrhynchos/blob/main/app/src/index.js)
104120
- [SimpleDB](https://github.com/nshiab/simple-data-analysis/blob/main/src/class/SimpleDB.ts)
121+
- [percival](https://github.com/ekzhang/percival/blob/main/src/lib/notebook.ts)
122+
- [SqlEditor](https://github.com/tabixio/tabix/blob/54198f2b081a11034f34f5ca469e17168159ab06/app/src/components/Dashboard/EditorTabPage/SqlEditor/SimpleEditor.tsx)
123+
- [egret](https://github.com/egret-labs/egret-ui-editor-opensource/blob/b36ec6a7490d5e086e72143e005f48450a1b72ce/src/vs/base/common/actions.ts)
124+
- [SQLens](https://github.com/oslabs-beta/SQLens)
125+
- [DBGate](https://github.com/dbgate/dbgate/blob/master/packages/web/src/query/SqlEditor.svelte)
126+
- [legend-studio](https://github.com/finos/legend-studio/blob/master/packages/legend-query-builder/src/components/explorer/QueryBuilderMilestoningEditor.tsx)
105127

106128
## Useful snippets
107129

lefthook.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pre-commit:
2+
commands:
3+
check:
4+
glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
5+
run: npx biome check --no-errors-on-unmatched --files-ignore-unknown=true {staged_files}

package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
"deploy-prod": "NODE_ENV=production sst deploy --stage production --profile quackdb"
2424
},
2525
"devDependencies": {
26-
"sst": "2.40.3",
26+
"@biomejs/biome": "^1.5.3",
27+
"@tsconfig/node20": "^20.1.2",
2728
"aws-cdk-lib": "2.124.0",
2829
"constructs": "10.3.0",
29-
"typescript": "^5.3.3",
30-
"@tsconfig/node20": "^20.1.2"
30+
"lefthook": "^1.6.1",
31+
"sst": "2.40.3",
32+
"typescript": "^5.3.3"
3133
},
3234
"workspaces": [
3335
"packages/*",

packages/web/.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
dist
33
./src/routeTree.gen.ts
4+
./src/components/monaco/syntax/index.ts

packages/web/biome.json

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
"organizeImports": {
44
"enabled": true
55
},
6+
"formatter": {
7+
"enabled": true,
8+
"ignore": [
9+
"./src/routeTree.gen.ts",
10+
"src/components/monaco/syntax/index.ts",
11+
"node_modules",
12+
"dist",
13+
"build",
14+
"pnpm-lock.yaml",
15+
"yarn.lock",
16+
"package-lock.json"
17+
]
18+
},
619
"linter": {
720
"enabled": true,
821
"rules": {
@@ -13,6 +26,14 @@
1326
"complexity": {
1427
"noForEach": "off"
1528
}
16-
}
29+
},
30+
"ignore": [
31+
"node_modules",
32+
"dist",
33+
"build",
34+
"pnpm-lock.yaml",
35+
"yarn.lock",
36+
"package-lock.json"
37+
]
1738
}
1839
}

packages/web/index.html

+5-7
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
<meta charset="UTF-8" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<meta name="theme-color" content="#0a0a0a" />
8-
<meta name="description" content="A local first DuckDB playground" />
9-
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
10-
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
11-
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
12-
<link rel="manifest" href="/site.webmanifest">
8+
<meta name="description" content="QuackDB is an online DuckDB SQL playground" />
9+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
10+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
11+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
12+
<link rel="manifest" href="/site.webmanifest" />
1313
<title>QuackDB</title>
14-
15-
1614
</head>
1715

1816
<body>

packages/web/package.json

+9-12
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212
"scripts": {
1313
"dev": "sst bind 'vite'",
1414
"build": "sst bind 'vite build'",
15+
"type-check": "tsc --noEmit",
1516
"fix": "biome check . --apply",
16-
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
1717
"preview": "sst bind 'vite preview'",
18-
"set-node-v": "pnpm env use --global 20"
18+
"set-node-v": "pnpm env use --global 20",
19+
"knip": "knip"
1920
},
2021
"dependencies": {
2122
"@apache-arrow/esnext-esm": "^15.0.0",
2223
"@duckdb/duckdb-wasm": "1.28.1-dev127.0",
2324
"@hookform/resolvers": "^3.3.4",
2425
"@monaco-editor/react": "^4.6.0",
2526
"@observablehq/plot": "^0.6.13",
26-
"@paralleldrive/cuid2": "^2.2.2",
2727
"@radix-ui/react-accordion": "^1.1.2",
2828
"@radix-ui/react-alert-dialog": "^1.0.5",
2929
"@radix-ui/react-aspect-ratio": "^1.0.3",
@@ -58,7 +58,7 @@
5858
"@tailwindcss/typography": "^0.5.10",
5959
"@tanstack/react-router": "^1.16.6",
6060
"@tanstack/react-table": "^8.12.0",
61-
"@tanstack/react-virtual": "^3.1.1",
61+
"@tanstack/react-virtual": "^3.1.2",
6262
"@tanstack/router-devtools": "^1.16.6",
6363
"@uidotdev/usehooks": "^2.4.1",
6464
"@xenova/transformers": "^2.15.0",
@@ -77,19 +77,17 @@
7777
"match-sorter": "^6.3.4",
7878
"monaco-editor": "0.46.0",
7979
"nprogress": "^0.2.0",
80-
"radix-icons": "^1.0.0",
8180
"react": "18.3.0-canary-f0e808e5b-20240214",
8281
"react-day-picker": "^8.10.0",
8382
"react-dom": "18.3.0-canary-f0e808e5b-20240214",
8483
"react-hook-form": "^7.50.1",
8584
"react-hotkeys-hook": "^4.5.0",
8685
"react-resizable-panels": "^2.0.9",
87-
"react-syntax-highlighter": "^15.5.0",
86+
"shiki": "^1.1.6",
8887
"sonner": "^1.4.0",
8988
"spin-delay": "^1.2.0",
9089
"tailwind-merge": "^2.2.1",
9190
"tailwindcss-animate": "^1.0.7",
92-
"tiny-invariant": "^1.3.1",
9391
"vaul": "^0.9.0",
9492
"zod": "^3.22.4",
9593
"zustand": "^4.5.1"
@@ -100,24 +98,23 @@
10098
"@types/eslint": "^8.56.2",
10199
"@types/node": "^20.11.19",
102100
"@types/nprogress": "^0.2.3",
103-
"@types/react": "^18.2.56",
101+
"@types/react": "^18.2.57",
104102
"@types/react-dom": "^18.2.19",
105103
"@types/react-syntax-highlighter": "^15.5.11",
106104
"@types/wicg-file-system-access": "^2023.10.4",
107-
"@typescript-eslint/eslint-plugin": "^7.0.1",
108-
"@typescript-eslint/parser": "^7.0.1",
105+
"@typescript-eslint/eslint-plugin": "^7.0.2",
106+
"@typescript-eslint/parser": "^7.0.2",
109107
"@vitejs/plugin-react": "^4.2.1",
110108
"autoprefixer": "^10.4.17",
111109
"cssnano": "^6.0.3",
112110
"eslint": "^8.56.0",
113-
"eslint-plugin-import": "^2.29.1",
114-
"eslint-plugin-react": "^7.33.2",
115111
"eslint-plugin-react-hooks": "^4.6.0",
116112
"eslint-plugin-react-jsx": "^1.0.0",
117113
"eslint-plugin-react-refresh": "^0.4.5",
118114
"eslint-plugin-simple-import-sort": "^12.0.0",
119115
"eslint-plugin-tailwindcss": "^3.14.2",
120116
"eslint-plugin-unused-imports": "^3.1.0",
117+
"knip": "^5.0.1",
121118
"postcss": "^8.4.35",
122119
"prettier": "^3.2.5",
123120
"prettier-plugin-tailwindcss": "^0.5.11",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { useEffect, useState } from "react";
2+
3+
type OnCopyToClipboardProps = {
4+
value: string;
5+
timeout?: number;
6+
};
7+
8+
export default function CopyToClipboard(props: OnCopyToClipboardProps) {
9+
const [copied, setCopied] = useState(false);
10+
11+
const timeout = props.timeout || 2000;
12+
13+
useEffect(() => {
14+
let timerId: NodeJS.Timeout | undefined;
15+
if (copied) {
16+
timerId = setTimeout(() => {
17+
setCopied(false);
18+
}, timeout);
19+
}
20+
return () => {
21+
if (timerId) clearTimeout(timerId);
22+
};
23+
}, [copied, timeout]);
24+
25+
const onCopy = async () => {
26+
try {
27+
await navigator.clipboard.writeText(props.value);
28+
setCopied(true);
29+
} catch (error) {
30+
console.error("Failed to copy: ", error);
31+
}
32+
};
33+
34+
return (
35+
<button
36+
type="button"
37+
onClick={onCopy}
38+
className="group flex h-auto w-16 cursor-pointer flex-col items-center justify-center rounded-md border border-neutral-200/60 bg-white px-3 pb-1.5 pt-2 text-[0.65rem] font-medium uppercase text-neutral-500 hover:bg-neutral-100 hover:text-neutral-600 focus:bg-white focus:outline-none active:bg-white"
39+
>
40+
{copied ? (
41+
// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>
42+
<svg
43+
className="mb-1 size-5 shrink-0 stroke-current"
44+
xmlns="http://www.w3.org/2000/svg"
45+
fill="none"
46+
viewBox="0 0 24 24"
47+
strokeWidth="1.5"
48+
stroke="currentColor"
49+
>
50+
<path
51+
strokeLinecap="round"
52+
strokeLinejoin="round"
53+
d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z"
54+
/>
55+
</svg>
56+
) : (
57+
<span>Copy</span>
58+
)}
59+
{copied && (
60+
// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>
61+
<svg
62+
className="mb-1 size-5 shrink-0 stroke-current text-green-500"
63+
xmlns="http://www.w3.org/2000/svg"
64+
fill="none"
65+
viewBox="0 0 24 24"
66+
strokeWidth="1.5"
67+
stroke="currentColor"
68+
>
69+
<path
70+
strokeLinecap="round"
71+
strokeLinejoin="round"
72+
d="M11.35 3.836c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m8.9-4.414c.376.023.75.05 1.124.08 1.131.094 1.976 1.057 1.976 2.192V16.5A2.25 2.25 0 0118 18.75h-2.25m-7.5-10.5H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V18.75m-7.5-10.5h6.375c.621 0 1.125.504 1.125 1.125v9.375m-8.25-3l1.5 1.5 3-3.75"
73+
/>
74+
</svg>
75+
)}
76+
{copied && <span className="tracking-tight text-green-500">Copied</span>}
77+
</button>
78+
);
79+
}

packages/web/src/components/mode-toggle.tsx

-38
This file was deleted.

0 commit comments

Comments
 (0)