dbxlite-ui 0.1.0

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 (112) hide show
  1. package/assets/assets/abap-CRCWOmpq.js +1 -0
  2. package/assets/assets/apex-DnsZk_dE.js +1 -0
  3. package/assets/assets/argon2-BUCifEKR.wasm +0 -0
  4. package/assets/assets/argon2-CtQQN5by.js +531 -0
  5. package/assets/assets/argon2-VsC-m8hX.js +38 -0
  6. package/assets/assets/azcli-1IWB1ccx.js +1 -0
  7. package/assets/assets/bat-DPkNLes8.js +1 -0
  8. package/assets/assets/bicep-Corcdgou.js +2 -0
  9. package/assets/assets/cameligo-CGrWLZr3.js +1 -0
  10. package/assets/assets/clojure-D9WOWImG.js +1 -0
  11. package/assets/assets/codicon-B_Z2XQ3P.ttf +0 -0
  12. package/assets/assets/coffee-B7EJu28W.js +1 -0
  13. package/assets/assets/cpp-SEyurbux.js +1 -0
  14. package/assets/assets/csharp-BoL64M5l.js +1 -0
  15. package/assets/assets/csp-C46ZqvIl.js +1 -0
  16. package/assets/assets/css-DQU6DXDx.js +3 -0
  17. package/assets/assets/cssMode-BwlhJ7iR.js +4 -0
  18. package/assets/assets/cypher-D84EuPTj.js +1 -0
  19. package/assets/assets/dart-D8lhlL1r.js +1 -0
  20. package/assets/assets/dockerfile-DLk6rpji.js +1 -0
  21. package/assets/assets/duckdb-browser-BSQM4t65.js +4 -0
  22. package/assets/assets/ecl-BO6FnfXk.js +1 -0
  23. package/assets/assets/elixir-BRjLKONM.js +1 -0
  24. package/assets/assets/flow9-Cac8vKd7.js +1 -0
  25. package/assets/assets/freemarker2-BkjRLolx.js +3 -0
  26. package/assets/assets/fsharp-fd1GTHhf.js +1 -0
  27. package/assets/assets/go-O9LJTZXk.js +1 -0
  28. package/assets/assets/graphql-LQdxqEYJ.js +1 -0
  29. package/assets/assets/handlebars-CBMLM90w.js +1 -0
  30. package/assets/assets/hcl-DxDQ3s82.js +1 -0
  31. package/assets/assets/html-CHZal9Bq.js +1 -0
  32. package/assets/assets/htmlMode-C9GZl6CA.js +4 -0
  33. package/assets/assets/index-B7kyXQsW.js +62964 -0
  34. package/assets/assets/index-Bls2JT31.css +1 -0
  35. package/assets/assets/ini-BvajGCUy.js +1 -0
  36. package/assets/assets/java-SYsfObOQ.js +1 -0
  37. package/assets/assets/javascript-3HFHugwg.js +1 -0
  38. package/assets/assets/jsonMode-uH9DvT2S.js +10 -0
  39. package/assets/assets/julia-DQXNmw_w.js +1 -0
  40. package/assets/assets/kotlin-qQ0MG-9I.js +1 -0
  41. package/assets/assets/less-GGFNNJHn.js +2 -0
  42. package/assets/assets/lexon-Canl7DCW.js +1 -0
  43. package/assets/assets/liquid-Ynp44jOk.js +1 -0
  44. package/assets/assets/lua-D28Ae8-K.js +1 -0
  45. package/assets/assets/m3-DPitgjJI.js +1 -0
  46. package/assets/assets/markdown-B811l8j2.js +1 -0
  47. package/assets/assets/mdx-B0LCS-Lw.js +1 -0
  48. package/assets/assets/mips-CdjsipkG.js +1 -0
  49. package/assets/assets/monaco-editor-DbSHhIAW.js +124636 -0
  50. package/assets/assets/monaco-editor-DvqauXKu.css +1 -0
  51. package/assets/assets/msdax-CYqgjx_P.js +1 -0
  52. package/assets/assets/mysql-BHd6q0vd.js +1 -0
  53. package/assets/assets/objective-c-B1aVtJYH.js +1 -0
  54. package/assets/assets/pascal-BhNW15KB.js +1 -0
  55. package/assets/assets/pascaligo-5jv8CcQD.js +1 -0
  56. package/assets/assets/perl-DlYyT36c.js +1 -0
  57. package/assets/assets/pgsql-Dy0bjov7.js +1 -0
  58. package/assets/assets/php-120yhfDK.js +1 -0
  59. package/assets/assets/pla-CjnFlu4u.js +1 -0
  60. package/assets/assets/postiats-CQpG440k.js +1 -0
  61. package/assets/assets/powerquery-DdJtto1Z.js +1 -0
  62. package/assets/assets/powershell-Bu_VLpJB.js +1 -0
  63. package/assets/assets/protobuf-IBS6jZEB.js +2 -0
  64. package/assets/assets/pug-kFxLfcjb.js +1 -0
  65. package/assets/assets/python-BLbP2FhE.js +1 -0
  66. package/assets/assets/qsharp-q7JyzKFN.js +1 -0
  67. package/assets/assets/r-BIFz-_sK.js +1 -0
  68. package/assets/assets/razor-CrzRfK-c.js +1 -0
  69. package/assets/assets/react-vendor-CJNQXC79.js +8 -0
  70. package/assets/assets/redis-CHOsPHWR.js +1 -0
  71. package/assets/assets/redshift-CBifECDb.js +1 -0
  72. package/assets/assets/restructuredtext-CghPJEOS.js +1 -0
  73. package/assets/assets/ruby-CYWGW-b1.js +1 -0
  74. package/assets/assets/rust-DMDD0SHb.js +1 -0
  75. package/assets/assets/sb-BYAiYHFx.js +1 -0
  76. package/assets/assets/scala-Bqvq8jcR.js +1 -0
  77. package/assets/assets/scheme-Dhb-2j9p.js +1 -0
  78. package/assets/assets/scss-CTwUZ5N7.js +3 -0
  79. package/assets/assets/shell-CsDZo4DB.js +1 -0
  80. package/assets/assets/solidity-CME5AdoB.js +1 -0
  81. package/assets/assets/sophia-RYC1BQQz.js +1 -0
  82. package/assets/assets/sparql-KEyrF7De.js +1 -0
  83. package/assets/assets/sql-BdTr02Mf.js +1 -0
  84. package/assets/assets/st-C7iG7M4S.js +1 -0
  85. package/assets/assets/swift-D7IUmUK8.js +1 -0
  86. package/assets/assets/systemverilog-DgMryOEJ.js +1 -0
  87. package/assets/assets/tcl-PloMZuKG.js +1 -0
  88. package/assets/assets/tsMode-B-o6MNSg.js +11 -0
  89. package/assets/assets/twig-BfRIq3la.js +1 -0
  90. package/assets/assets/typescript-nABxf5PW.js +1 -0
  91. package/assets/assets/typespec-CzxlYoT_.js +1 -0
  92. package/assets/assets/vb-BwAE3J76.js +1 -0
  93. package/assets/assets/wgsl-Dksx_ONF.js +298 -0
  94. package/assets/assets/worker-D4TW6ZaR.js +5 -0
  95. package/assets/assets/xml-BOnVlNcs.js +1 -0
  96. package/assets/assets/yaml-Yl61aKaY.js +1 -0
  97. package/assets/duckdb/.gitignore +8 -0
  98. package/assets/duckdb/README.md +24 -0
  99. package/assets/index.html +26 -0
  100. package/assets/logo/favicon.svg +44 -0
  101. package/assets/logo/logo-icon.svg +44 -0
  102. package/assets/logo/logo.svg +44 -0
  103. package/assets/screenshots/excel-query-any-sheet.png +0 -0
  104. package/assets/screenshots/explorer-multi-themes.png +0 -0
  105. package/assets/screenshots/export-status.png +0 -0
  106. package/assets/screenshots/main-interface-dark.png +0 -0
  107. package/assets/screenshots/query-remote-files.png +0 -0
  108. package/assets/screenshots/share-links.png +0 -0
  109. package/assets/sql-templates/initial-tab.sql +11 -0
  110. package/assets/sql-templates/new-tab.sql +0 -0
  111. package/dist/cli.js +311 -0
  112. package/package.json +37 -0
package/dist/cli.js ADDED
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * dbxlite-ui CLI
5
+ *
6
+ * Three modes of operation:
7
+ *
8
+ * 1. Hosted (recommended):
9
+ * export ui_remote_url="https://sql.dbxlite.com"
10
+ * duckdb -unsigned -ui
11
+ *
12
+ * 2. Local asset server:
13
+ * npx dbxlite-ui --serve # Runs server, user runs duckdb separately
14
+ *
15
+ * 3. All-in-one:
16
+ * npx dbxlite-ui # Starts server + duckdb + opens browser
17
+ * npx dbxlite-ui mydata.duckdb # With specific database
18
+ */
19
+
20
+ import { createServer } from 'http';
21
+ import { spawn } from 'child_process';
22
+ import { readFileSync, existsSync, statSync } from 'fs';
23
+ import { join, dirname, extname } from 'path';
24
+ import { fileURLToPath } from 'url';
25
+
26
+ const __dirname = dirname(fileURLToPath(import.meta.url));
27
+
28
+ const HOSTED_URL = 'https://sql.dbxlite.com';
29
+ const DEFAULT_PORT = 8080;
30
+
31
+ // Parse command line arguments
32
+ const args = process.argv.slice(2);
33
+ let databasePath = null;
34
+ let assetPort = DEFAULT_PORT; // Default to 8080
35
+ let noBrowser = false;
36
+ let launchDuckDB = false; // --launch flag to also start DuckDB
37
+ let showInfo = false;
38
+
39
+ for (let i = 0; i < args.length; i++) {
40
+ const arg = args[i];
41
+ if (arg === '--port' && args[i + 1]) {
42
+ assetPort = parseInt(args[i + 1], 10);
43
+ i++;
44
+ } else if (arg === '--no-browser') {
45
+ noBrowser = true;
46
+ } else if (arg === '--launch' || arg === '-l') {
47
+ launchDuckDB = true;
48
+ } else if (arg === '--info' || arg === '-i') {
49
+ showInfo = true;
50
+ } else if (arg === '--help' || arg === '-h') {
51
+ console.log(`
52
+ dbxlite-ui - Local UI for DuckDB
53
+
54
+ USAGE:
55
+
56
+ npx dbxlite-ui Start asset server on port 8080
57
+ Then run: duckdb -unsigned -ui
58
+
59
+ npx dbxlite-ui --launch Start server + DuckDB + open browser
60
+
61
+ ALTERNATIVE (no install):
62
+
63
+ export ui_remote_url="${HOSTED_URL}"
64
+ duckdb -unsigned -ui
65
+
66
+ OPTIONS:
67
+
68
+ --port <port> Asset server port (default: ${DEFAULT_PORT})
69
+ --launch, -l Also start DuckDB and open browser
70
+ --no-browser Don't open browser (with --launch)
71
+ --info, -i Show setup instructions
72
+ -h, --help Show this help
73
+
74
+ EXAMPLES:
75
+
76
+ dbxlite-ui Start asset server on :8080
77
+ dbxlite-ui --port 9000 Start on custom port
78
+ dbxlite-ui --launch Start server + DuckDB + browser
79
+ dbxlite-ui --launch data.duckdb With specific database
80
+ `);
81
+ process.exit(0);
82
+ } else if (!arg.startsWith('-')) {
83
+ databasePath = arg;
84
+ launchDuckDB = true; // If database provided, assume --launch
85
+ }
86
+ }
87
+
88
+ // Show info/setup instructions
89
+ if (showInfo) {
90
+ console.log(`
91
+ dbxlite-ui - Setup Instructions
92
+
93
+ OPTION 1: Use hosted version (easiest)
94
+ ─────────────────────────────────────
95
+ Add to your shell config (~/.zshrc or ~/.bashrc):
96
+
97
+ export ui_remote_url="${HOSTED_URL}"
98
+
99
+ Then run:
100
+
101
+ duckdb -unsigned -ui
102
+
103
+
104
+ OPTION 2: Run local asset server
105
+ ────────────────────────────────
106
+ Terminal 1 - Start server:
107
+
108
+ npx dbxlite-ui --serve
109
+
110
+ Terminal 2 - Use DuckDB:
111
+
112
+ export ui_remote_url="http://127.0.0.1:8080"
113
+ duckdb -unsigned -ui
114
+
115
+
116
+ OPTION 3: All-in-one command
117
+ ────────────────────────────
118
+ npx dbxlite-ui [database.duckdb]
119
+
120
+ This starts the asset server, DuckDB, and opens your browser.
121
+ `);
122
+ process.exit(0);
123
+ }
124
+
125
+ // MIME types for serving assets
126
+ const MIME_TYPES = {
127
+ '.html': 'text/html',
128
+ '.js': 'application/javascript',
129
+ '.css': 'text/css',
130
+ '.json': 'application/json',
131
+ '.wasm': 'application/wasm',
132
+ '.svg': 'image/svg+xml',
133
+ '.png': 'image/png',
134
+ '.jpg': 'image/jpeg',
135
+ '.ico': 'image/x-icon',
136
+ '.ttf': 'font/ttf',
137
+ '.woff': 'font/woff',
138
+ '.woff2': 'font/woff2',
139
+ };
140
+
141
+ // Find assets directory (in dev: ../web-client/dist, in published: ./assets)
142
+ function findAssetsDir() {
143
+ // Check for published package structure
144
+ const publishedPath = join(__dirname, '..', 'assets');
145
+ if (existsSync(publishedPath)) {
146
+ return publishedPath;
147
+ }
148
+
149
+ // Check for dev structure (sibling web-client)
150
+ const devPath = join(__dirname, '..', '..', 'web-client', 'dist');
151
+ if (existsSync(devPath)) {
152
+ return devPath;
153
+ }
154
+
155
+ console.error('Error: Could not find assets directory.');
156
+ console.error('Run "pnpm build" in apps/web-client first.');
157
+ process.exit(1);
158
+ }
159
+
160
+ const ASSETS_DIR = findAssetsDir();
161
+ console.log(`Assets directory: ${ASSETS_DIR}`);
162
+
163
+ // Create asset server
164
+ const server = createServer((req, res) => {
165
+ let urlPath = req.url.split('?')[0];
166
+ if (urlPath === '/') urlPath = '/index.html';
167
+
168
+ const filePath = join(ASSETS_DIR, urlPath);
169
+
170
+ // Security: prevent directory traversal
171
+ if (!filePath.startsWith(ASSETS_DIR)) {
172
+ res.writeHead(403);
173
+ res.end('Forbidden');
174
+ return;
175
+ }
176
+
177
+ try {
178
+ if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
179
+ res.writeHead(404, { 'Content-Type': 'text/plain', 'Content-Length': 9 });
180
+ res.end('Not found');
181
+ return;
182
+ }
183
+
184
+ const content = readFileSync(filePath);
185
+ const ext = extname(filePath).toLowerCase();
186
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
187
+
188
+ res.writeHead(200, {
189
+ 'Content-Type': contentType,
190
+ 'Content-Length': content.length,
191
+ 'Cache-Control': 'no-cache',
192
+ });
193
+ res.end(content);
194
+ } catch (err) {
195
+ console.error(`Error serving ${urlPath}:`, err.message);
196
+ res.writeHead(500);
197
+ res.end('Internal Server Error');
198
+ }
199
+ });
200
+
201
+ // Start server (and optionally DuckDB)
202
+ server.listen(assetPort, '127.0.0.1', async () => {
203
+ const port = server.address().port;
204
+
205
+ // Default mode: just run the asset server
206
+ if (!launchDuckDB) {
207
+ console.log(`
208
+ dbxlite asset server running on http://127.0.0.1:${port}
209
+
210
+ Next step - run DuckDB with dbxlite UI:
211
+
212
+ export ui_remote_url="http://127.0.0.1:${port}"
213
+ duckdb -unsigned -ui
214
+
215
+ Tip: Add to ~/.zshrc or ~/.bashrc for permanent setup:
216
+
217
+ export ui_remote_url="http://127.0.0.1:${port}"
218
+
219
+ Press Ctrl+C to stop the server.
220
+ `);
221
+
222
+ // Handle graceful shutdown
223
+ process.on('SIGINT', () => {
224
+ console.log('\nShutting down asset server...');
225
+ server.close();
226
+ process.exit(0);
227
+ });
228
+
229
+ return; // Don't start DuckDB
230
+ }
231
+
232
+ // Launch mode: start DuckDB too
233
+ console.log(`Asset server running on http://127.0.0.1:${port}`);
234
+
235
+ // Check if duckdb is available
236
+ const duckdbPath = 'duckdb'; // Assume it's in PATH
237
+
238
+ // Build DuckDB command
239
+ // Use -cmd to load UI and start it, keeping DuckDB in interactive mode
240
+ const duckdbArgs = ['-unsigned'];
241
+ if (databasePath) {
242
+ duckdbArgs.unshift(databasePath);
243
+ }
244
+
245
+ // Add commands to load UI extension and start it
246
+ duckdbArgs.push('-cmd', 'LOAD ui; CALL start_ui();');
247
+
248
+ console.log(`Starting DuckDB with dbxlite UI...`);
249
+ if (databasePath) {
250
+ console.log(`Database: ${databasePath}`);
251
+ }
252
+
253
+ // Start DuckDB with ui_remote_url pointing to our server
254
+ // Use stdio 'inherit' for interactive mode
255
+ const duckdb = spawn(duckdbPath, duckdbArgs, {
256
+ env: {
257
+ ...process.env,
258
+ ui_remote_url: `http://127.0.0.1:${port}`,
259
+ },
260
+ stdio: 'inherit',
261
+ // Ensure DuckDB gets a proper TTY for interactive mode
262
+ detached: false,
263
+ });
264
+
265
+ duckdb.on('error', (err) => {
266
+ if (err.code === 'ENOENT') {
267
+ console.error('\nError: DuckDB not found in PATH');
268
+ console.error('Install DuckDB: https://duckdb.org/docs/installation/');
269
+ } else {
270
+ console.error('Failed to start DuckDB:', err.message);
271
+ }
272
+ server.close();
273
+ process.exit(1);
274
+ });
275
+
276
+ duckdb.on('close', (code) => {
277
+ console.log(`\nDuckDB exited with code ${code}`);
278
+ server.close();
279
+ process.exit(code || 0);
280
+ });
281
+
282
+ // Open browser after a short delay
283
+ if (!noBrowser) {
284
+ setTimeout(async () => {
285
+ try {
286
+ const open = (await import('open')).default;
287
+ await open('http://localhost:4213');
288
+ console.log('Opened browser at http://localhost:4213');
289
+ } catch (err) {
290
+ console.log('Open http://localhost:4213 in your browser');
291
+ }
292
+ }, 1000);
293
+ } else {
294
+ console.log('Open http://localhost:4213 in your browser');
295
+ }
296
+
297
+ // Handle graceful shutdown
298
+ process.on('SIGINT', () => {
299
+ console.log('\nShutting down...');
300
+ duckdb.kill('SIGINT');
301
+ });
302
+
303
+ process.on('SIGTERM', () => {
304
+ duckdb.kill('SIGTERM');
305
+ });
306
+ });
307
+
308
+ server.on('error', (err) => {
309
+ console.error('Failed to start asset server:', err.message);
310
+ process.exit(1);
311
+ });
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "dbxlite-ui",
3
+ "version": "0.1.0",
4
+ "description": "Local UI for DuckDB - replaces duckdb -ui with dbxlite",
5
+ "type": "module",
6
+ "bin": {
7
+ "dbxlite-ui": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "assets"
12
+ ],
13
+ "scripts": {
14
+ "build": "node scripts/build.js",
15
+ "dev": "node src/cli.js",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "keywords": [
19
+ "duckdb",
20
+ "sql",
21
+ "database",
22
+ "ui",
23
+ "browser"
24
+ ],
25
+ "author": "",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/hfmio/dbxlite"
30
+ },
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "dependencies": {
35
+ "open": "^10.1.0"
36
+ }
37
+ }