@oxy-hq/sdk 0.1.5 → 0.2.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.
- package/README.md +288 -157
- package/dist/index.cjs +592 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +424 -40
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +424 -40
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +588 -96
- package/dist/index.mjs.map +1 -1
- package/dist/{postMessage-CufWf9ji.cjs → postMessage-B1J0jDRN.cjs} +15 -11
- package/dist/postMessage-B1J0jDRN.cjs.map +1 -0
- package/dist/{postMessage-CVS3MsL5.cjs → postMessage-BSNS3ccd.cjs} +1 -1
- package/dist/{postMessage-DLGITn0e.mjs → postMessage-BxdgtX8j.mjs} +15 -11
- package/dist/postMessage-BxdgtX8j.mjs.map +1 -0
- package/dist/{postMessage-DwfY0HM5.mjs → postMessage-D5wWgwcO.mjs} +1 -1
- package/package.json +12 -7
- package/dist/postMessage-CufWf9ji.cjs.map +0 -1
- package/dist/postMessage-DLGITn0e.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -28,264 +28,397 @@ npm install @duckdb/duckdb-wasm
|
|
|
28
28
|
|
|
29
29
|
## Quick Start
|
|
30
30
|
|
|
31
|
-
###
|
|
31
|
+
### Basic Usage
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
```typescript
|
|
34
|
+
import { OxySDK } from "@oxy/sdk";
|
|
35
|
+
|
|
36
|
+
// Create SDK instance
|
|
37
|
+
const sdk = new OxySDK({
|
|
38
|
+
apiKey: "your-api-key",
|
|
39
|
+
projectId: "your-project-id",
|
|
40
|
+
baseUrl: "https://api.oxy.tech"
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Load parquet files and query them
|
|
44
|
+
await sdk.loadFile('data/sales.parquet', 'sales');
|
|
45
|
+
await sdk.loadFile('data/customers.parquet', 'customers');
|
|
46
|
+
|
|
47
|
+
// Query with SQL - supports joins across multiple tables
|
|
48
|
+
const result = await sdk.query(`
|
|
49
|
+
SELECT s.product, s.amount, c.name as customer_name
|
|
50
|
+
FROM sales s
|
|
51
|
+
JOIN customers c ON s.customer_id = c.id
|
|
52
|
+
WHERE s.amount > 1000
|
|
53
|
+
ORDER BY s.amount DESC
|
|
54
|
+
`);
|
|
55
|
+
|
|
56
|
+
console.log(result.rows);
|
|
57
|
+
await sdk.close();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Load App Data Automatically
|
|
34
61
|
|
|
35
62
|
```typescript
|
|
36
|
-
import {
|
|
63
|
+
import { OxySDK, createConfig } from "@oxy/sdk";
|
|
64
|
+
|
|
65
|
+
const sdk = new OxySDK(createConfig());
|
|
66
|
+
|
|
67
|
+
// Loads all data from the app and registers tables
|
|
68
|
+
await sdk.loadAppData('dashboard.app.yml');
|
|
69
|
+
|
|
70
|
+
// Query the loaded tables
|
|
71
|
+
const result = await sdk.query('SELECT * FROM my_table LIMIT 10');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Iframe Usage (PostMessage Authentication)
|
|
75
|
+
|
|
76
|
+
For embedding in iframes (e.g., v0.dev, sandboxed environments):
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { OxySDK } from "@oxy/sdk";
|
|
37
80
|
|
|
38
81
|
// SDK automatically requests API key from parent window
|
|
39
|
-
const
|
|
40
|
-
parentOrigin:
|
|
41
|
-
projectId:
|
|
42
|
-
baseUrl: 'https://api.oxy.tech'
|
|
82
|
+
const sdk = await OxySDK.create({
|
|
83
|
+
parentOrigin: "https://app.example.com",
|
|
84
|
+
projectId: "your-project-uuid"
|
|
43
85
|
});
|
|
44
86
|
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
console.log('Available apps:', apps);
|
|
87
|
+
await sdk.loadAppData('dashboard.app.yml');
|
|
88
|
+
const result = await sdk.query('SELECT * FROM my_table LIMIT 10');
|
|
48
89
|
```
|
|
49
90
|
|
|
50
|
-
**Parent window setup
|
|
51
|
-
```typescript
|
|
52
|
-
// In parent window that hosts the iframe
|
|
53
|
-
window.addEventListener('message', (event) => {
|
|
54
|
-
if (event.data.type !== 'OXY_AUTH_REQUEST') return;
|
|
91
|
+
**Parent window setup:**
|
|
55
92
|
|
|
56
|
-
|
|
57
|
-
|
|
93
|
+
```typescript
|
|
94
|
+
window.addEventListener("message", (event) => {
|
|
95
|
+
if (event.data.type !== "OXY_AUTH_REQUEST") return;
|
|
96
|
+
if (event.origin !== "https://your-iframe-app.com") return;
|
|
58
97
|
|
|
59
|
-
// Send user's API key to iframe
|
|
60
98
|
event.source.postMessage({
|
|
61
|
-
type:
|
|
62
|
-
version:
|
|
99
|
+
type: "OXY_AUTH_RESPONSE",
|
|
100
|
+
version: "1.0",
|
|
63
101
|
requestId: event.data.requestId,
|
|
64
|
-
apiKey: getUserApiKey(),
|
|
65
|
-
projectId:
|
|
66
|
-
baseUrl:
|
|
102
|
+
apiKey: getUserApiKey(),
|
|
103
|
+
projectId: "your-project-uuid",
|
|
104
|
+
baseUrl: "https://api.oxy.tech"
|
|
67
105
|
}, event.origin);
|
|
68
106
|
});
|
|
69
107
|
```
|
|
70
108
|
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
Set up environment variables:
|
|
109
|
+
### Environment Variables
|
|
74
110
|
|
|
75
111
|
```bash
|
|
76
|
-
export OXY_URL="https://api.oxy.tech"
|
|
112
|
+
export OXY_URL="https://api.oxy.tech"
|
|
77
113
|
export OXY_API_KEY="your-api-key"
|
|
78
114
|
export OXY_PROJECT_ID="your-project-uuid"
|
|
79
115
|
export OXY_BRANCH="main" # optional
|
|
80
116
|
```
|
|
81
117
|
|
|
82
|
-
|
|
118
|
+
Use `createConfig()` to load from environment:
|
|
83
119
|
|
|
84
120
|
```typescript
|
|
85
|
-
import {
|
|
86
|
-
|
|
87
|
-
// Create configuration from environment variables
|
|
88
|
-
const config = createConfig();
|
|
89
|
-
|
|
90
|
-
// Initialize the client
|
|
91
|
-
const client = new OxyClient(config);
|
|
121
|
+
import { OxySDK, createConfig } from "@oxy/sdk";
|
|
92
122
|
|
|
93
|
-
|
|
94
|
-
const apps = await client.listApps();
|
|
95
|
-
console.log('Available apps:', apps);
|
|
96
|
-
|
|
97
|
-
// Get app data
|
|
98
|
-
const data = await client.getAppData('dashboard.app.yml');
|
|
99
|
-
if (!data.error) {
|
|
100
|
-
console.log('App data:', data.data);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Fetch a file (e.g., chart image)
|
|
104
|
-
const blob = await client.getFile('charts/sales-chart.png');
|
|
105
|
-
const url = URL.createObjectURL(blob);
|
|
106
|
-
// Use the URL in an <img> tag
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Reading Parquet Files
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
import { OxyClient, createConfig, readParquet, ParquetReader } from '@oxy/sdk';
|
|
113
|
-
|
|
114
|
-
const config = createConfig();
|
|
115
|
-
const client = new OxyClient(config);
|
|
116
|
-
|
|
117
|
-
// Quick read - get all data
|
|
118
|
-
const blob = await client.getFile('data/sales.parquet');
|
|
119
|
-
const data = await readParquet(blob, 1000); // Read first 1000 rows
|
|
120
|
-
console.log(data.columns);
|
|
121
|
-
console.log(data.rows);
|
|
122
|
-
|
|
123
|
-
// Advanced - query with SQL
|
|
124
|
-
const reader = new ParquetReader('sales');
|
|
125
|
-
await reader.registerParquet(blob);
|
|
126
|
-
|
|
127
|
-
const result = await reader.query(`
|
|
128
|
-
SELECT product, SUM(amount) as total_sales
|
|
129
|
-
FROM sales
|
|
130
|
-
GROUP BY product
|
|
131
|
-
ORDER BY total_sales DESC
|
|
132
|
-
LIMIT 10
|
|
133
|
-
`);
|
|
134
|
-
|
|
135
|
-
console.log('Top 10 products:', result.rows);
|
|
136
|
-
await reader.close();
|
|
123
|
+
const sdk = new OxySDK(createConfig());
|
|
137
124
|
```
|
|
138
125
|
|
|
139
126
|
## React Integration
|
|
140
127
|
|
|
141
|
-
###
|
|
128
|
+
### Using React Context (Recommended)
|
|
142
129
|
|
|
143
|
-
|
|
144
|
-
|
|
130
|
+
The SDK provides `OxyProvider` and `useOxy` hooks for easy integration:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import { OxyProvider, useOxy, createConfig } from '@oxy/sdk';
|
|
145
134
|
import { useEffect, useState } from 'react';
|
|
146
135
|
|
|
147
|
-
|
|
136
|
+
// Wrap your app with OxyProvider
|
|
137
|
+
function App() {
|
|
138
|
+
return (
|
|
139
|
+
<OxyProvider config={createConfig()}>
|
|
140
|
+
<Dashboard />
|
|
141
|
+
</OxyProvider>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
148
144
|
|
|
145
|
+
// Access SDK in child components
|
|
149
146
|
function Dashboard() {
|
|
147
|
+
const { sdk, isLoading, error } = useOxy();
|
|
150
148
|
const [data, setData] = useState(null);
|
|
151
149
|
|
|
152
150
|
useEffect(() => {
|
|
153
|
-
|
|
154
|
-
.
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
if (sdk) {
|
|
152
|
+
sdk.loadAppData('dashboard.app.yml')
|
|
153
|
+
.then(() => sdk.query('SELECT * FROM my_table LIMIT 100'))
|
|
154
|
+
.then(setData);
|
|
155
|
+
}
|
|
156
|
+
}, [sdk]);
|
|
157
157
|
|
|
158
|
-
if (
|
|
158
|
+
if (isLoading) return <div>Initializing SDK...</div>;
|
|
159
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
160
|
+
if (!data) return <div>Loading data...</div>;
|
|
159
161
|
|
|
160
162
|
return (
|
|
161
163
|
<div>
|
|
162
164
|
<h1>Dashboard</h1>
|
|
163
|
-
|
|
165
|
+
<table>
|
|
166
|
+
<thead>
|
|
167
|
+
<tr>
|
|
168
|
+
{data.columns.map(col => <th key={col}>{col}</th>)}
|
|
169
|
+
</tr>
|
|
170
|
+
</thead>
|
|
171
|
+
<tbody>
|
|
172
|
+
{data.rows.map((row, i) => (
|
|
173
|
+
<tr key={i}>
|
|
174
|
+
{row.map((cell, j) => <td key={j}>{String(cell)}</td>)}
|
|
175
|
+
</tr>
|
|
176
|
+
))}
|
|
177
|
+
</tbody>
|
|
178
|
+
</table>
|
|
164
179
|
</div>
|
|
165
180
|
);
|
|
166
181
|
}
|
|
167
182
|
```
|
|
168
183
|
|
|
169
|
-
###
|
|
184
|
+
### Iframe with PostMessage Auth
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import { OxyProvider, useOxySDK } from '@oxy/sdk';
|
|
188
|
+
|
|
189
|
+
function App() {
|
|
190
|
+
return (
|
|
191
|
+
<OxyProvider
|
|
192
|
+
useAsync
|
|
193
|
+
config={{ parentOrigin: 'https://app.example.com' }}
|
|
194
|
+
>
|
|
195
|
+
<Dashboard />
|
|
196
|
+
</OxyProvider>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function Dashboard() {
|
|
201
|
+
const sdk = useOxySDK(); // Throws if not ready
|
|
202
|
+
const [data, setData] = useState(null);
|
|
203
|
+
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
sdk.loadFile('data/sales.parquet', 'sales')
|
|
206
|
+
.then(() => sdk.query('SELECT * FROM sales LIMIT 100'))
|
|
207
|
+
.then(setData);
|
|
208
|
+
}, [sdk]);
|
|
209
|
+
|
|
210
|
+
return <div>{/* render data */}</div>;
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Without Context (Alternative)
|
|
170
215
|
|
|
171
216
|
```typescript
|
|
172
|
-
import {
|
|
217
|
+
import { OxySDK, createConfig } from '@oxy/sdk';
|
|
218
|
+
import { useEffect, useState } from 'react';
|
|
173
219
|
|
|
174
|
-
|
|
220
|
+
const sdk = new OxySDK(createConfig());
|
|
221
|
+
|
|
222
|
+
function Dashboard() {
|
|
175
223
|
const [data, setData] = useState(null);
|
|
176
224
|
|
|
177
225
|
useEffect(() => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const result = await reader.getAll(100);
|
|
183
|
-
setData(result);
|
|
184
|
-
await reader.close();
|
|
185
|
-
}
|
|
186
|
-
loadData();
|
|
187
|
-
}, [filePath]);
|
|
226
|
+
sdk.loadAppData('dashboard.app.yml')
|
|
227
|
+
.then(() => sdk.query('SELECT * FROM my_table LIMIT 100'))
|
|
228
|
+
.then(setData);
|
|
229
|
+
}, []);
|
|
188
230
|
|
|
189
|
-
|
|
231
|
+
return <div>{/* render data */}</div>;
|
|
190
232
|
}
|
|
191
233
|
```
|
|
192
234
|
|
|
193
|
-
## Use with v0 and
|
|
235
|
+
## Use with v0 and Sandbox Services
|
|
194
236
|
|
|
195
|
-
|
|
237
|
+
**For AI Assistants (v0.dev, Cursor, etc.):** See [.v0/rules.md](.v0/rules.md) and [.cursorrules](.cursorrules) for integration guidelines.
|
|
196
238
|
|
|
197
239
|
```typescript
|
|
198
|
-
|
|
199
|
-
import { OxyClient, createConfig, readParquet } from '@oxy/sdk';
|
|
240
|
+
import { OxySDK, createConfig } from "@oxy/sdk";
|
|
200
241
|
|
|
201
|
-
|
|
202
|
-
const client = new OxyClient(createConfig());
|
|
242
|
+
const sdk = new OxySDK(createConfig());
|
|
203
243
|
|
|
204
|
-
export async function
|
|
205
|
-
|
|
206
|
-
client.getAppData('apps/sales.app.yml'),
|
|
207
|
-
client.getAppData('apps/customers.app.yml'),
|
|
208
|
-
]);
|
|
244
|
+
export async function getDashboardData() {
|
|
245
|
+
await sdk.loadAppData("dashboard.app.yml");
|
|
209
246
|
|
|
210
|
-
return
|
|
247
|
+
return await sdk.query(`
|
|
248
|
+
SELECT s.*, c.name as customer_name
|
|
249
|
+
FROM sales s
|
|
250
|
+
LEFT JOIN customers c ON s.customer_id = c.id
|
|
251
|
+
ORDER BY s.date DESC
|
|
252
|
+
LIMIT 100
|
|
253
|
+
`);
|
|
211
254
|
}
|
|
212
255
|
|
|
213
|
-
export function
|
|
214
|
-
return
|
|
256
|
+
export function getChartUrl() {
|
|
257
|
+
return sdk.getClient().getFileUrl("charts/sales-overview.png");
|
|
215
258
|
}
|
|
216
259
|
```
|
|
217
260
|
|
|
218
261
|
## API Reference
|
|
219
262
|
|
|
220
|
-
###
|
|
263
|
+
### OxySDK (Unified Interface)
|
|
264
|
+
|
|
265
|
+
The `OxySDK` class combines `OxyClient` and `ParquetReader` into a single, easy-to-use interface.
|
|
221
266
|
|
|
222
267
|
#### `constructor(config: OxyConfig)`
|
|
223
268
|
|
|
224
|
-
Creates a new
|
|
269
|
+
Creates a new SDK instance.
|
|
270
|
+
|
|
271
|
+
#### `static async create(config?: Partial<OxyConfig>): Promise<OxySDK>`
|
|
272
|
+
|
|
273
|
+
Creates an SDK instance with async configuration (supports postMessage auth).
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
const sdk = await OxySDK.create({
|
|
277
|
+
parentOrigin: 'https://app.example.com',
|
|
278
|
+
projectId: 'your-project-id'
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### `async loadFile(filePath: string, tableName: string): Promise<void>`
|
|
283
|
+
|
|
284
|
+
Loads a Parquet file from Oxy and registers it for SQL queries.
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
await sdk.loadFile('data/sales.parquet', 'sales');
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### `async loadFiles(files: Array<{filePath: string, tableName: string}>): Promise<void>`
|
|
291
|
+
|
|
292
|
+
Loads multiple Parquet files at once.
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
await sdk.loadFiles([
|
|
296
|
+
{ filePath: 'data/sales.parquet', tableName: 'sales' },
|
|
297
|
+
{ filePath: 'data/customers.parquet', tableName: 'customers' }
|
|
298
|
+
]);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### `async loadAppData(appPath: string): Promise<DataContainer | null>`
|
|
302
|
+
|
|
303
|
+
Loads all data from an app's data container. Uses container keys as table names.
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
const data = await sdk.loadAppData('dashboard.app.yml');
|
|
307
|
+
// Now query the tables using their container keys
|
|
308
|
+
const result = await sdk.query('SELECT * FROM my_table');
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
#### `async query(sql: string): Promise<QueryResult>`
|
|
312
|
+
|
|
313
|
+
Executes a SQL query against loaded data.
|
|
225
314
|
|
|
226
|
-
|
|
315
|
+
```typescript
|
|
316
|
+
const result = await sdk.query('SELECT * FROM sales WHERE amount > 1000');
|
|
317
|
+
```
|
|
227
318
|
|
|
228
|
-
|
|
319
|
+
#### `async getAll(tableName: string, limit?: number): Promise<QueryResult>`
|
|
229
320
|
|
|
230
|
-
|
|
321
|
+
Gets all data from a loaded table.
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
const data = await sdk.getAll('sales', 100);
|
|
325
|
+
```
|
|
231
326
|
|
|
232
|
-
|
|
327
|
+
#### `async getSchema(tableName: string): Promise<QueryResult>`
|
|
233
328
|
|
|
234
|
-
|
|
329
|
+
Gets schema information for a loaded table.
|
|
235
330
|
|
|
236
|
-
|
|
331
|
+
#### `async count(tableName: string): Promise<number>`
|
|
332
|
+
|
|
333
|
+
Gets row count for a loaded table.
|
|
334
|
+
|
|
335
|
+
#### `getClient(): OxyClient`
|
|
336
|
+
|
|
337
|
+
Returns the underlying `OxyClient` for advanced operations.
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
const apps = await sdk.getClient().listApps();
|
|
341
|
+
```
|
|
237
342
|
|
|
238
|
-
#### `
|
|
343
|
+
#### `getReader(): ParquetReader`
|
|
239
344
|
|
|
240
|
-
|
|
345
|
+
Returns the underlying `ParquetReader` for advanced operations.
|
|
241
346
|
|
|
242
|
-
#### `
|
|
347
|
+
#### `async close(): Promise<void>`
|
|
243
348
|
|
|
244
|
-
|
|
349
|
+
Closes and cleans up all resources.
|
|
245
350
|
|
|
246
|
-
|
|
351
|
+
### React Hooks
|
|
247
352
|
|
|
248
|
-
|
|
353
|
+
#### `OxyProvider`
|
|
249
354
|
|
|
250
|
-
|
|
355
|
+
Provider component that initializes and provides OxySDK to child components.
|
|
251
356
|
|
|
252
|
-
|
|
357
|
+
**Props:**
|
|
358
|
+
- `config?: Partial<OxyConfig>` - SDK configuration
|
|
359
|
+
- `useAsync?: boolean` - If true, uses async initialization (supports postMessage auth)
|
|
360
|
+
- `onReady?: (sdk: OxySDK) => void` - Called when SDK is initialized
|
|
361
|
+
- `onError?: (error: Error) => void` - Called on initialization error
|
|
253
362
|
|
|
254
|
-
|
|
363
|
+
```tsx
|
|
364
|
+
<OxyProvider config={createConfig()}>
|
|
365
|
+
<YourApp />
|
|
366
|
+
</OxyProvider>
|
|
367
|
+
```
|
|
255
368
|
|
|
256
|
-
#### `
|
|
369
|
+
#### `useOxy()`
|
|
257
370
|
|
|
258
|
-
|
|
371
|
+
Hook to access SDK, loading state, and errors.
|
|
259
372
|
|
|
260
|
-
|
|
373
|
+
```tsx
|
|
374
|
+
const { sdk, isLoading, error } = useOxy();
|
|
375
|
+
```
|
|
261
376
|
|
|
262
|
-
|
|
377
|
+
Returns:
|
|
378
|
+
- `sdk: OxySDK | null` - The SDK instance (null if not ready)
|
|
379
|
+
- `isLoading: boolean` - True while initializing
|
|
380
|
+
- `error: Error | null` - Initialization error if any
|
|
263
381
|
|
|
264
|
-
#### `
|
|
382
|
+
#### `useOxySDK()`
|
|
265
383
|
|
|
266
|
-
|
|
384
|
+
Hook that returns SDK directly or throws if not ready. Useful when you know SDK should be initialized.
|
|
267
385
|
|
|
268
|
-
|
|
386
|
+
```tsx
|
|
387
|
+
const sdk = useOxySDK(); // Throws if not ready
|
|
388
|
+
```
|
|
269
389
|
|
|
270
|
-
|
|
390
|
+
### Advanced: OxyClient
|
|
271
391
|
|
|
272
|
-
|
|
392
|
+
For advanced use cases, access the underlying client via `sdk.getClient()`:
|
|
273
393
|
|
|
274
|
-
|
|
394
|
+
```typescript
|
|
395
|
+
const client = sdk.getClient();
|
|
396
|
+
await client.listApps();
|
|
397
|
+
await client.getDisplays('my-app.app.yml');
|
|
398
|
+
const blob = await client.getFile('path/to/file.parquet');
|
|
399
|
+
```
|
|
275
400
|
|
|
276
|
-
###
|
|
401
|
+
### Advanced: ParquetReader
|
|
277
402
|
|
|
278
|
-
|
|
403
|
+
For advanced use cases, access the underlying reader via `sdk.getReader()`:
|
|
279
404
|
|
|
280
|
-
|
|
405
|
+
```typescript
|
|
406
|
+
const reader = sdk.getReader();
|
|
407
|
+
await reader.registerParquet(customBlob, 'custom_table');
|
|
408
|
+
```
|
|
281
409
|
|
|
282
|
-
|
|
410
|
+
Or use standalone:
|
|
283
411
|
|
|
284
|
-
|
|
412
|
+
```typescript
|
|
413
|
+
import { ParquetReader } from "@oxy/sdk";
|
|
285
414
|
|
|
286
|
-
|
|
415
|
+
const reader = new ParquetReader();
|
|
416
|
+
await reader.registerParquet(blob1, 'table1');
|
|
417
|
+
await reader.registerParquet(blob2, 'table2');
|
|
287
418
|
|
|
288
|
-
|
|
419
|
+
const result = await reader.query('SELECT * FROM table1 JOIN table2 ON ...');
|
|
420
|
+
await reader.close();
|
|
421
|
+
```
|
|
289
422
|
|
|
290
423
|
## Environment Variables
|
|
291
424
|
|
|
@@ -298,12 +431,6 @@ Quick helper to read all data from a Parquet blob.
|
|
|
298
431
|
|
|
299
432
|
See the [examples](./examples) directory for more detailed examples:
|
|
300
433
|
|
|
301
|
-
- [basic-usage.ts](./examples/basic-usage.ts) - Basic SDK usage
|
|
302
|
-
- [parquet-usage.ts](./examples/parquet-usage.ts) - Parquet file reading
|
|
303
|
-
- [react-example.tsx](./examples/react-example.tsx) - React integration
|
|
304
|
-
- [react-parquet.tsx](./examples/react-parquet.tsx) - React with Parquet
|
|
305
|
-
- [v0-integration.ts](./examples/v0-integration.ts) - v0 sandbox integration
|
|
306
|
-
|
|
307
434
|
## Building and Publishing
|
|
308
435
|
|
|
309
436
|
```bash
|
|
@@ -333,3 +460,7 @@ MIT
|
|
|
333
460
|
## Support
|
|
334
461
|
|
|
335
462
|
For issues and questions, please visit [GitHub Issues](https://github.com/dataframehq/oxy-internal/issues).
|
|
463
|
+
|
|
464
|
+
### Local development with v0 or cloud service
|
|
465
|
+
|
|
466
|
+
- Disable the local network access check [flag](chrome ://flags/#local-network-access-check)
|