@hypequery/react 0.4.0 → 0.5.1
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 +37 -267
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +25 -4
package/README.md
CHANGED
|
@@ -1,307 +1,77 @@
|
|
|
1
1
|
# @hypequery/react
|
|
2
2
|
|
|
3
|
-
React hooks for
|
|
3
|
+
Typed React hooks for ClickHouse analytics, powered by TanStack Query.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@hypequery/react` carries `@hypequery/serve` contracts into React and Next.js. Query names, inputs, metrics, dataset fields, and response rows stay inferred from the server, so frontend analytics do not drift into a second set of hand-written types.
|
|
6
|
+
|
|
7
|
+
Use it for product dashboards, embedded analytics, customer reporting, and multi-tenant SaaS metrics.
|
|
6
8
|
|
|
7
9
|
## Install
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npm install @hypequery/react @tanstack/react-query
|
|
11
|
-
# or
|
|
12
|
-
pnpm add @hypequery/react @tanstack/react-query
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
Given a serve API:
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
// server/api.ts
|
|
21
|
-
import { initServe } from '@hypequery/serve';
|
|
22
|
-
import { z } from 'zod';
|
|
23
|
-
import { db } from './db.js';
|
|
24
|
-
|
|
25
|
-
const { query, serve } = initServe({
|
|
26
|
-
context: () => ({ db }),
|
|
27
|
-
basePath: '/api/analytics',
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const weeklyRevenue = query({
|
|
31
|
-
description: 'Weekly revenue',
|
|
32
|
-
input: z.object({ startDate: z.string() }),
|
|
33
|
-
query: ({ ctx, input }) =>
|
|
34
|
-
ctx.db
|
|
35
|
-
.table('orders')
|
|
36
|
-
.where('created_at', 'gte', input.startDate)
|
|
37
|
-
.sum('total', 'revenue')
|
|
38
|
-
.execute(),
|
|
39
|
-
});
|
|
15
|
+
## Create hooks from your API
|
|
40
16
|
|
|
41
|
-
|
|
42
|
-
queries: { weeklyRevenue },
|
|
43
|
-
});
|
|
17
|
+
Generate a small route manifest during the build:
|
|
44
18
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
19
|
+
```bash
|
|
20
|
+
npx hypequery generate:manifest analytics/api.ts \
|
|
21
|
+
--output src/generated/hypequery-manifest.json
|
|
48
22
|
```
|
|
49
23
|
|
|
50
|
-
Create hooks on the client:
|
|
51
|
-
|
|
52
24
|
```tsx
|
|
53
|
-
|
|
54
|
-
import { createHooks } from '@hypequery/react';
|
|
25
|
+
import { createAnalyticsHooks } from '@hypequery/react';
|
|
55
26
|
import type { AnalyticsApi } from '../server/api.js';
|
|
27
|
+
import manifest from '../generated/hypequery-manifest.json';
|
|
56
28
|
|
|
57
|
-
export const {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Use them inside a component:
|
|
64
|
-
|
|
65
|
-
```tsx
|
|
66
|
-
function RevenuePanel() {
|
|
67
|
-
const revenue = useQuery('weeklyRevenue', {
|
|
68
|
-
startDate: '2026-01-01',
|
|
29
|
+
export const { useMetric, useDataset } =
|
|
30
|
+
createAnalyticsHooks<AnalyticsApi>({
|
|
31
|
+
baseUrl: '/api/analytics',
|
|
32
|
+
manifest,
|
|
33
|
+
metrics: ['revenue'] as const,
|
|
69
34
|
});
|
|
70
|
-
|
|
71
|
-
if (revenue.isLoading) return <p>Loading...</p>;
|
|
72
|
-
if (revenue.error) return <p>{revenue.error.message}</p>;
|
|
73
|
-
|
|
74
|
-
return <pre>{JSON.stringify(revenue.data, null, 2)}</pre>;
|
|
75
|
-
}
|
|
76
35
|
```
|
|
77
36
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
`createAnalyticsHooks` adds convenience wrappers for semantic endpoint names. Metrics use their endpoint name directly. Dataset endpoints are addressed as `dataset:<name>` in the API type and exposed through `useDataset(name, ...)`.
|
|
37
|
+
## Build the dashboard
|
|
81
38
|
|
|
82
39
|
```tsx
|
|
83
|
-
|
|
84
|
-
import type { InferApiType } from '@hypequery/serve';
|
|
85
|
-
import type { api } from '../server/api.js';
|
|
86
|
-
|
|
87
|
-
import manifest from './hypequery-manifest.json';
|
|
88
|
-
|
|
89
|
-
type AnalyticsApi = InferApiType<typeof api>;
|
|
90
|
-
|
|
91
|
-
export const { useMetric, useDataset } = createAnalyticsHooks<AnalyticsApi>({
|
|
92
|
-
baseUrl: '/api/analytics',
|
|
93
|
-
manifest,
|
|
94
|
-
metrics: ['revenue', 'averageOrderValue'] as const,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
function Dashboard() {
|
|
40
|
+
function RevenueByRegion() {
|
|
98
41
|
const revenue = useMetric('revenue', {
|
|
99
|
-
dimensions: ['
|
|
100
|
-
filters: [{ field: 'status', operator: 'eq', value: 'completed' }],
|
|
42
|
+
dimensions: ['region'],
|
|
101
43
|
orderBy: [{ field: 'revenue', direction: 'desc' }],
|
|
102
44
|
limit: 10,
|
|
103
45
|
});
|
|
104
46
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
measures: ['revenue', 'orderCount'],
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<pre>
|
|
112
|
-
{JSON.stringify({ revenue: revenue.data, orders: orders.data }, null, 2)}
|
|
113
|
-
</pre>
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Pagination
|
|
119
|
-
|
|
120
|
-
Semantic queries that set a `limit` return `meta.pagination = { limit, offset, hasMore }`
|
|
121
|
-
(`hasMore` is exact — the server over-fetches one row rather than running a count query).
|
|
122
|
-
`useInfiniteQuery`, and the `useInfiniteMetric` / `useInfiniteDataset` wrappers, build on
|
|
123
|
-
this to page through results. They advance the offset automatically and request meta for you.
|
|
124
|
-
|
|
125
|
-
```tsx
|
|
126
|
-
function OrdersTable() {
|
|
127
|
-
const orders = useInfiniteDataset('orders', {
|
|
128
|
-
dimensions: ['status'],
|
|
129
|
-
measures: ['revenue'],
|
|
130
|
-
limit: 50,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
return (
|
|
134
|
-
<>
|
|
135
|
-
{orders.data?.pages.flatMap((page) => page.data).map((row, i) => (
|
|
136
|
-
<Row key={i} row={row} />
|
|
137
|
-
))}
|
|
138
|
-
<button
|
|
139
|
-
onClick={() => orders.fetchNextPage()}
|
|
140
|
-
disabled={!orders.hasNextPage || orders.isFetchingNextPage}
|
|
141
|
-
>
|
|
142
|
-
Load more
|
|
143
|
-
</button>
|
|
144
|
-
</>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
`input.limit` is the page size; `input.offset`, if provided, is the starting offset.
|
|
150
|
-
|
|
151
|
-
## Route Configuration
|
|
152
|
-
|
|
153
|
-
Hooks need to know each endpoint's HTTP method and path. There are three ways to
|
|
154
|
-
supply that, in increasing precedence: a route manifest, a runtime `api` object,
|
|
155
|
-
or explicit `config`.
|
|
156
|
-
|
|
157
|
-
### Route manifest (recommended)
|
|
158
|
-
|
|
159
|
-
`@hypequery/serve`'s `api.manifest()` returns a serializable map of every
|
|
160
|
-
query/metric/dataset key to its `{ method, path }`. Export it from a server-only
|
|
161
|
-
module and pass it to the hooks — this avoids importing server code into the
|
|
162
|
-
browser bundle while keeping client routes in sync with the server.
|
|
163
|
-
|
|
164
|
-
```ts
|
|
165
|
-
// server side (server-only module)
|
|
166
|
-
export const manifest = api.manifest();
|
|
167
|
-
|
|
168
|
-
// client side
|
|
169
|
-
const { useQuery } = createHooks<AnalyticsApi>({
|
|
170
|
-
baseUrl: '/api/analytics',
|
|
171
|
-
manifest,
|
|
172
|
-
});
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
> Metric and dataset endpoints are POST routes whose paths differ from their map
|
|
176
|
-
> keys (e.g. `dataset:orders` → `POST /api/analytics/datasets/orders/query`). They
|
|
177
|
-
> require a `manifest` (or explicit `config`); calling them without one throws a
|
|
178
|
-
> clear error rather than hitting the wrong URL.
|
|
179
|
-
|
|
180
|
-
#### Generating the manifest at build time
|
|
181
|
-
|
|
182
|
-
The cleanest way to keep server code out of the browser bundle is to generate a
|
|
183
|
-
JSON file at build time and import that on the client.
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
npx hypequery generate:manifest analytics/api.ts --output src/generated/hypequery-manifest.json
|
|
187
|
-
```
|
|
47
|
+
if (revenue.isLoading) return <p>Loading revenue…</p>;
|
|
48
|
+
if (revenue.error) return <p>{revenue.error.message}</p>;
|
|
188
49
|
|
|
189
|
-
|
|
190
|
-
// package.json
|
|
191
|
-
{
|
|
192
|
-
"scripts": {
|
|
193
|
-
"gen:manifest": "hypequery generate:manifest analytics/api.ts --output src/generated/hypequery-manifest.json",
|
|
194
|
-
"build": "npm run gen:manifest && <your client build>"
|
|
195
|
-
}
|
|
50
|
+
return <RevenueChart rows={revenue.data?.data ?? []} />;
|
|
196
51
|
}
|
|
197
52
|
```
|
|
198
53
|
|
|
199
|
-
|
|
200
|
-
// client side — imports plain JSON, no server code in the bundle
|
|
201
|
-
import { createAnalyticsHooks } from '@hypequery/react';
|
|
202
|
-
import type { InferApiType } from '@hypequery/serve';
|
|
203
|
-
import type { api } from '../analytics/api.js';
|
|
204
|
-
import manifest from './generated/hypequery-manifest.json';
|
|
205
|
-
|
|
206
|
-
type AnalyticsApi = InferApiType<typeof api>;
|
|
207
|
-
|
|
208
|
-
const { useMetric, useDataset } = createAnalyticsHooks<AnalyticsApi>({
|
|
209
|
-
baseUrl: '/api/analytics',
|
|
210
|
-
manifest,
|
|
211
|
-
});
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
The manifest is derived entirely from your serve config (`basePath`, route keys,
|
|
215
|
-
and `semanticPaths`), so the generated file is deterministic and only changes when
|
|
216
|
-
your API shape does — commit it or regenerate it on every build.
|
|
217
|
-
|
|
218
|
-
> `baseUrl` supplies the origin/host; the per-endpoint path comes from the
|
|
219
|
-
> manifest (it already includes the server's `basePath`), so there's no
|
|
220
|
-
> double-prefixing. Keep `baseUrl` aligned with where the API is mounted.
|
|
221
|
-
|
|
222
|
-
### Explicit config
|
|
223
|
-
|
|
224
|
-
If a manifest is not available at runtime, pass route config explicitly. This
|
|
225
|
-
overrides any manifest entry.
|
|
226
|
-
|
|
227
|
-
```ts
|
|
228
|
-
const { useQuery } = createHooks<AnalyticsApi>({
|
|
229
|
-
baseUrl: '/api/analytics',
|
|
230
|
-
config: {
|
|
231
|
-
weeklyRevenue: { method: 'POST', path: '/weeklyRevenue' },
|
|
232
|
-
},
|
|
233
|
-
});
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
`path` may be relative to `baseUrl`, absolute within the same origin, or an absolute HTTP URL.
|
|
237
|
-
|
|
238
|
-
## Headers & auth
|
|
239
|
-
|
|
240
|
-
Pass static headers, or a function (sync or async) invoked per request — handy for
|
|
241
|
-
attaching a fresh/short-lived token.
|
|
242
|
-
|
|
243
|
-
```ts
|
|
244
|
-
const hooks = createHooks<AnalyticsApi>({
|
|
245
|
-
baseUrl: '/api/analytics',
|
|
246
|
-
headers: async () => ({
|
|
247
|
-
authorization: `Bearer ${await getAccessToken()}`,
|
|
248
|
-
}),
|
|
249
|
-
});
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
Provide `onUnauthorized` to refresh credentials on a `401` and retry the request once
|
|
253
|
-
with freshly resolved headers:
|
|
254
|
-
|
|
255
|
-
```ts
|
|
256
|
-
const hooks = createHooks<AnalyticsApi>({
|
|
257
|
-
baseUrl: '/api/analytics',
|
|
258
|
-
headers: () => ({ authorization: `Bearer ${tokenStore.access}` }),
|
|
259
|
-
onUnauthorized: async () => {
|
|
260
|
-
await tokenStore.refresh(); // throw to abort; resolve to retry once
|
|
261
|
-
},
|
|
262
|
-
});
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## Query Options
|
|
266
|
-
|
|
267
|
-
TanStack Query options can be passed as the final argument.
|
|
268
|
-
|
|
269
|
-
```tsx
|
|
270
|
-
const result = useQuery(
|
|
271
|
-
'weeklyRevenue',
|
|
272
|
-
{ startDate: '2026-01-01' },
|
|
273
|
-
{
|
|
274
|
-
staleTime: 60_000,
|
|
275
|
-
refetchOnWindowFocus: false,
|
|
276
|
-
},
|
|
277
|
-
);
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
For no-input queries, use `queryOptions()` when an options object might look like input.
|
|
281
|
-
|
|
282
|
-
```tsx
|
|
283
|
-
import { queryOptions } from '@hypequery/react';
|
|
54
|
+
Change the server contract and TypeScript points to the components that need updating.
|
|
284
55
|
|
|
285
|
-
|
|
286
|
-
staleTime: 30_000,
|
|
287
|
-
}));
|
|
288
|
-
```
|
|
56
|
+
## Included
|
|
289
57
|
|
|
290
|
-
|
|
58
|
+
- named query hooks and mutations;
|
|
59
|
+
- metric and dataset hooks with selected-field inference;
|
|
60
|
+
- infinite queries with semantic pagination metadata;
|
|
61
|
+
- TanStack Query caching, retries, and refresh behavior;
|
|
62
|
+
- static route manifests that keep server code out of browser bundles;
|
|
63
|
+
- per-request auth headers and one-time `401` refresh.
|
|
291
64
|
|
|
292
|
-
|
|
65
|
+
## Why it matters
|
|
293
66
|
|
|
294
|
-
|
|
295
|
-
const refresh = useMutation('refreshReport');
|
|
296
|
-
|
|
297
|
-
refresh.mutate({ reportId: 'revenue' });
|
|
298
|
-
```
|
|
67
|
+
The ClickHouse query, semantic metric, HTTP schema, and React component share one contract. That means fewer casts, fewer mismatched route types, and no frontend rewrite when a dashboard graduates from a prototype into a governed multi-tenant product surface.
|
|
299
68
|
|
|
300
|
-
##
|
|
69
|
+
## Learn more
|
|
301
70
|
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
-
|
|
71
|
+
- [React quick start](https://hypequery.com/docs/react/getting-started)
|
|
72
|
+
- [Using queries](https://hypequery.com/docs/react/using-queries)
|
|
73
|
+
- [Advanced patterns](https://hypequery.com/docs/react/advanced-patterns)
|
|
74
|
+
- [Current capabilities](https://hypequery.com/docs/capabilities)
|
|
305
75
|
|
|
306
76
|
## License
|
|
307
77
|
|
package/dist/types.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ type DatasetOutputForInput<TInfo, TInput, TFallback> = TInfo extends {
|
|
|
42
42
|
} ? WithTypedData<TFallback, {
|
|
43
43
|
[K in SelectedDimensions<TDimensions, TInput>]?: DimensionValue<TDimensions[K]>;
|
|
44
44
|
} & {
|
|
45
|
-
[K in SelectedMeasures<TMeasures, TInput>]?:
|
|
45
|
+
[K in SelectedMeasures<TMeasures, TInput>]?: string;
|
|
46
46
|
} & PeriodSelection<TInput>> : TFallback;
|
|
47
47
|
type MetricOutputForInput<TInfo, TInput, TFallback> = TInfo extends {
|
|
48
48
|
kind: 'metric';
|
|
@@ -51,7 +51,7 @@ type MetricOutputForInput<TInfo, TInput, TFallback> = TInfo extends {
|
|
|
51
51
|
} ? WithTypedData<TFallback, {
|
|
52
52
|
[K in SelectedDimensions<TDimensions, TInput>]?: DimensionValue<TDimensions[K]>;
|
|
53
53
|
} & {
|
|
54
|
-
[K in TMetricName]?:
|
|
54
|
+
[K in TMetricName]?: string;
|
|
55
55
|
} & PeriodSelection<TInput>> : TFallback;
|
|
56
56
|
export type QueryOutputForInput<Api, Name extends ExtractNames<Api>, TInput> = SemanticInfo<Api, Name> extends infer Info ? Info extends {
|
|
57
57
|
kind: 'dataset';
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;KAC9B,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,GAAG,KAAK,GAAG,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK;CACxE,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,MAAM,MAAM,YAAY,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAClE,OAAO,CAAC,MAAM,GAAG,EAAE,MAAM,CAAC,GAC1B,eAAe,CAAC,GAAG,CAAC,CAAC;AAEzB,MAAM,MAAM,UAAU,CACpB,GAAG,EACH,IAAI,SAAS,YAAY,CAAC,GAAG,CAAC,IAC5B,GAAG,CAAC,IAAI,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,KAAK,CAAA;CAAE,GAAG,KAAK,GAAG,KAAK,CAAC;AAE7D,MAAM,MAAM,WAAW,CACrB,GAAG,EACH,IAAI,SAAS,YAAY,CAAC,GAAG,CAAC,IAC5B,GAAG,CAAC,IAAI,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,KAAK,CAAC;AAEhE,KAAK,YAAY,CAAC,GAAG,EAAE,IAAI,SAAS,YAAY,CAAC,GAAG,CAAC,IACnD,GAAG,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,GAC3D,WAAW,CAAC,IAAI,CAAC,GACjB,KAAK,CAAC;AAEZ,KAAK,cAAc,CAAC,WAAW,IAC7B,WAAW,SAAS;IAAE,SAAS,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,GACpD,WAAW,SAAS;IAAE,SAAS,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,GACpD,WAAW,SAAS;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,GACtD,WAAW,SAAS;IAAE,SAAS,EAAE,WAAW,CAAA;CAAE,GAAG,MAAM,GACvD,OAAO,CAAC;AAEV,KAAK,kBAAkB,CAAC,WAAW,EAAE,MAAM,IACzC,MAAM,SAAS;IAAE,UAAU,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAA;CAAE,GACnD,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,GAC5C,KAAK,CAAC;AAEZ,KAAK,gBAAgB,CAAC,SAAS,EAAE,MAAM,IACrC,MAAM,SAAS;IAAE,QAAQ,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAA;CAAE,GACjD,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,GAC1C,eAAe,CAAC,SAAS,CAAC,CAAC;AAEjC,KAAK,eAAe,CAAC,MAAM,IAAI,MAAM,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACnB,EAAE,CAAC;AAEP,KAAK,aAAa,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;IAC1D,IAAI,EAAE,IAAI,EAAE,CAAC;CACd,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/react",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "React hooks for
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "Type-safe React and TanStack Query hooks for ClickHouse analytics, metrics, and datasets",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"tanstack-query",
|
|
8
|
+
"clickhouse",
|
|
9
|
+
"analytics",
|
|
10
|
+
"semantic-layer",
|
|
11
|
+
"typescript",
|
|
12
|
+
"query-builder",
|
|
13
|
+
"orm",
|
|
14
|
+
"dashboard",
|
|
15
|
+
"embedded-analytics"
|
|
16
|
+
],
|
|
5
17
|
"type": "module",
|
|
6
18
|
"main": "./dist/index.js",
|
|
7
19
|
"exports": {
|
|
@@ -30,8 +42,17 @@
|
|
|
30
42
|
"react-dom": "^18.2.0",
|
|
31
43
|
"typescript": "^5.7.3",
|
|
32
44
|
"vitest": "^3.2.6",
|
|
33
|
-
"@hypequery/
|
|
34
|
-
"@hypequery/
|
|
45
|
+
"@hypequery/serve": "0.15.2",
|
|
46
|
+
"@hypequery/datasets": "0.13.3"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/hypequery/hypequery.git",
|
|
51
|
+
"directory": "packages/react"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://hypequery.com",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/hypequery/hypequery/issues"
|
|
35
56
|
},
|
|
36
57
|
"publishConfig": {
|
|
37
58
|
"access": "public"
|