@vibedash/client 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.
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/provider.d.ts +5 -0
- package/dist/provider.js +14 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.js +1 -0
- package/dist/use-query.d.ts +14 -0
- package/dist/use-query.js +61 -0
- package/package.json +20 -0
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { VibeDashConfig } from "./types";
|
|
2
|
+
export declare function VibeDashProvider({ apiUrl, projectSlug, apiKey, children, }: VibeDashConfig & {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function useVibeDash(): VibeDashConfig;
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
const VibeDashContext = createContext(null);
|
|
4
|
+
export function VibeDashProvider({ apiUrl, projectSlug, apiKey, children, }) {
|
|
5
|
+
return (_jsx(VibeDashContext.Provider, { value: { apiUrl, projectSlug, apiKey }, children: children }));
|
|
6
|
+
}
|
|
7
|
+
export function useVibeDash() {
|
|
8
|
+
const ctx = useContext(VibeDashContext);
|
|
9
|
+
if (!ctx) {
|
|
10
|
+
throw new Error("useVibeDash must be used within a <VibeDashProvider>. " +
|
|
11
|
+
"Wrap your app in <VibeDashProvider apiUrl=\"...\" projectSlug=\"...\">.");
|
|
12
|
+
}
|
|
13
|
+
return ctx;
|
|
14
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface VibeDashConfig {
|
|
2
|
+
/** The Vibe Dash API URL (defaults to https://hub.vibedash.xyz/api) */
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
/** The project slug (e.g. "data-man") */
|
|
5
|
+
projectSlug: string;
|
|
6
|
+
/** API key for authentication (used in local dev, read from env) */
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface UseQueryOptions {
|
|
10
|
+
/** Whether to fetch immediately (default: true) */
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface UseQueryResult<T = Record<string, unknown>[]> {
|
|
14
|
+
/** The query result data */
|
|
15
|
+
data: T | null;
|
|
16
|
+
/** Whether the query is currently loading */
|
|
17
|
+
loading: boolean;
|
|
18
|
+
/** Error message if the query failed */
|
|
19
|
+
error: string | null;
|
|
20
|
+
/** Re-run the query manually */
|
|
21
|
+
refetch: () => Promise<void>;
|
|
22
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { UseQueryOptions, UseQueryResult } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Fetches data from a registered query by name.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* ```tsx
|
|
7
|
+
* const { data, loading, error } = useQuery("monthly_revenue");
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* The query must be registered at deploy time. The browser never sends raw SQL —
|
|
11
|
+
* only the query name. Vibe Dash looks up the SQL server-side, runs it against
|
|
12
|
+
* your BigQuery warehouse using stored credentials, and returns the results.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useQuery<T = Record<string, unknown>[]>(queryName: string, options?: UseQueryOptions): UseQueryResult<T>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { useVibeDash } from "./provider";
|
|
3
|
+
/**
|
|
4
|
+
* Fetches data from a registered query by name.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```tsx
|
|
8
|
+
* const { data, loading, error } = useQuery("monthly_revenue");
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* The query must be registered at deploy time. The browser never sends raw SQL —
|
|
12
|
+
* only the query name. Vibe Dash looks up the SQL server-side, runs it against
|
|
13
|
+
* your BigQuery warehouse using stored credentials, and returns the results.
|
|
14
|
+
*/
|
|
15
|
+
export function useQuery(queryName, options) {
|
|
16
|
+
const { apiUrl, projectSlug, apiKey } = useVibeDash();
|
|
17
|
+
const [data, setData] = useState(null);
|
|
18
|
+
const [loading, setLoading] = useState(false);
|
|
19
|
+
const [error, setError] = useState(null);
|
|
20
|
+
const enabled = options?.enabled !== false;
|
|
21
|
+
const fetchData = useCallback(async () => {
|
|
22
|
+
setLoading(true);
|
|
23
|
+
setError(null);
|
|
24
|
+
try {
|
|
25
|
+
const headers = {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
};
|
|
28
|
+
if (apiKey) {
|
|
29
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
30
|
+
}
|
|
31
|
+
const res = await fetch(`${apiUrl}/query`, {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers,
|
|
34
|
+
credentials: apiKey ? "omit" : "include",
|
|
35
|
+
body: JSON.stringify({
|
|
36
|
+
project_slug: projectSlug,
|
|
37
|
+
query_name: queryName,
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
const body = await res.json().catch(() => ({}));
|
|
42
|
+
throw new Error(body.error || `Query failed with status ${res.status}`);
|
|
43
|
+
}
|
|
44
|
+
const body = await res.json();
|
|
45
|
+
setData(body.data);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const message = err instanceof Error ? err.message : "Failed to fetch data";
|
|
49
|
+
setError(message);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
setLoading(false);
|
|
53
|
+
}
|
|
54
|
+
}, [apiUrl, projectSlug, queryName]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (enabled) {
|
|
57
|
+
fetchData();
|
|
58
|
+
}
|
|
59
|
+
}, [enabled, fetchData]);
|
|
60
|
+
return { data, loading, error, refetch: fetchData };
|
|
61
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vibedash/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React hooks for Vibe Dash dashboards — useQuery() for data fetching",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": ["dist"],
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsc --watch"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"react": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/react": "^19",
|
|
17
|
+
"react": "^19",
|
|
18
|
+
"typescript": "^5"
|
|
19
|
+
}
|
|
20
|
+
}
|