hydrousdb 2.0.0 → 2.0.3

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.
@@ -1,185 +0,0 @@
1
- import { a9 as HttpClient, c as AnalyticsQuery, V as RequestOptions, e as AnalyticsResponse, D as DateRange, C as CountResult, p as DistributionItem, a1 as SumResult, a2 as TimeSeriesPoint, r as FieldTimeSeriesPoint, a3 as TopNItem, F as FieldStatsResult, s as Filter, u as FilteredRecordsResult, M as MultiMetricItem, a0 as StorageStatsResult } from '../http-DTukpdAU.mjs';
2
- export { d as AnalyticsQueryType } from '../http-DTukpdAU.mjs';
3
-
4
- type AnalyticsResult<T> = Omit<AnalyticsResponse, 'data'> & {
5
- data: T;
6
- queryType: string;
7
- bucketKey: string | null;
8
- projectId: string;
9
- };
10
- /** Options accepted by every analytics method */
11
- interface BucketOptions {
12
- /**
13
- * The bucket to run the analytics query against.
14
- * Required on all analytics calls.
15
- *
16
- * @example
17
- * const { data } = await db.analytics.count({ bucketKey: 'orders' });
18
- */
19
- bucketKey: string;
20
- }
21
- declare class AnalyticsClient {
22
- private readonly http;
23
- constructor(http: HttpClient);
24
- /** Builds the path for a given bucket: /api/analytics/:bucketKey/:securityKey */
25
- private path;
26
- /**
27
- * Run any analytics query with full control over the payload.
28
- * Prefer the typed convenience methods below for everyday use.
29
- */
30
- query<T = unknown>(payload: AnalyticsQuery, options: BucketOptions & RequestOptions): Promise<AnalyticsResult<T>>;
31
- /**
32
- * Total record count, optionally scoped to a date range.
33
- *
34
- * @example
35
- * const { data } = await db.analytics.count({ bucketKey: 'orders' });
36
- * console.log(data.count);
37
- *
38
- * const { data } = await db.analytics.count({
39
- * bucketKey: 'orders',
40
- * dateRange: { startDate: '2025-01-01', endDate: '2025-12-31' },
41
- * });
42
- */
43
- count(options: {
44
- dateRange?: DateRange;
45
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<CountResult>>;
46
- /**
47
- * Value distribution (histogram) for a field.
48
- *
49
- * @example
50
- * const { data } = await db.analytics.distribution('status', { bucketKey: 'orders' });
51
- * // [{ value: 'active', count: 80 }, { value: 'archived', count: 20 }]
52
- */
53
- distribution(field: string, options: {
54
- limit?: number;
55
- order?: 'asc' | 'desc';
56
- dateRange?: DateRange;
57
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<DistributionItem[]>>;
58
- /**
59
- * Sum a numeric field, with optional group-by.
60
- *
61
- * @example
62
- * const { data } = await db.analytics.sum('revenue', { bucketKey: 'orders', groupBy: 'region' });
63
- */
64
- sum(field: string, options: {
65
- groupBy?: string;
66
- limit?: number;
67
- dateRange?: DateRange;
68
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<SumResult>>;
69
- /**
70
- * Record count grouped over time.
71
- *
72
- * @example
73
- * const { data } = await db.analytics.timeSeries({ bucketKey: 'orders', granularity: 'day' });
74
- * // [{ date: '2025-01-01', count: 42 }, ...]
75
- */
76
- timeSeries(options: {
77
- granularity?: 'hour' | 'day' | 'week' | 'month';
78
- dateRange?: DateRange;
79
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<TimeSeriesPoint[]>>;
80
- /**
81
- * Aggregate a numeric field over time.
82
- *
83
- * @example
84
- * const { data } = await db.analytics.fieldTimeSeries('revenue', {
85
- * bucketKey: 'orders',
86
- * granularity: 'month',
87
- * aggregation: 'sum',
88
- * });
89
- */
90
- fieldTimeSeries(field: string, options: {
91
- aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';
92
- granularity?: 'hour' | 'day' | 'week' | 'month';
93
- dateRange?: DateRange;
94
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<FieldTimeSeriesPoint[]>>;
95
- /**
96
- * Top N most frequent values for a field.
97
- *
98
- * @example
99
- * const { data } = await db.analytics.topN('country', 5, { bucketKey: 'users' });
100
- * // [{ label: 'US', value: 'US', count: 500 }, ...]
101
- */
102
- topN(field: string, n: number | undefined, options: {
103
- labelField?: string;
104
- order?: 'asc' | 'desc';
105
- dateRange?: DateRange;
106
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<TopNItem[]>>;
107
- /**
108
- * Statistical summary for a numeric field: min, max, avg, stddev, p50, p90, p99.
109
- *
110
- * @example
111
- * const { data } = await db.analytics.stats('score', { bucketKey: 'users' });
112
- * console.log(data.avg, data.p99);
113
- */
114
- stats(field: string, options: {
115
- dateRange?: DateRange;
116
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<FieldStatsResult>>;
117
- /**
118
- * Filtered, paginated raw records with optional field projection.
119
- * Supports filter ops: == != > < >= <= CONTAINS
120
- *
121
- * @example
122
- * const { data } = await db.analytics.records({
123
- * bucketKey: 'users',
124
- * filters: [{ field: 'role', op: '==', value: 'admin' }],
125
- * selectFields: ['email', 'createdAt'],
126
- * limit: 25,
127
- * });
128
- */
129
- records(options: {
130
- filters?: Filter[];
131
- selectFields?: string[];
132
- limit?: number;
133
- offset?: number;
134
- orderBy?: string;
135
- order?: 'asc' | 'desc';
136
- dateRange?: DateRange;
137
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<FilteredRecordsResult>>;
138
- /**
139
- * Multiple aggregations in a single call — ideal for dashboard stat cards.
140
- *
141
- * @example
142
- * const { data } = await db.analytics.multiMetric(
143
- * [
144
- * { name: 'totalRevenue', field: 'amount', aggregation: 'sum' },
145
- * { name: 'avgScore', field: 'score', aggregation: 'avg' },
146
- * ],
147
- * { bucketKey: 'orders' }
148
- * );
149
- * console.log(data.totalRevenue, data.avgScore);
150
- */
151
- multiMetric(metrics: MultiMetricItem[], options: {
152
- dateRange?: DateRange;
153
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<Record<string, number>>>;
154
- /**
155
- * Storage statistics for a bucket — total records, bytes, avg/min/max size.
156
- *
157
- * @example
158
- * const { data } = await db.analytics.storageStats({ bucketKey: 'orders' });
159
- * console.log(data.totalRecords, data.totalBytes);
160
- */
161
- storageStats(options: {
162
- dateRange?: DateRange;
163
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<StorageStatsResult>>;
164
- /**
165
- * Compare a metric across multiple buckets in one query.
166
- * Note: `bucketKey` here is used only for auth — the actual buckets
167
- * compared are specified via `bucketKeys`.
168
- *
169
- * @example
170
- * const { data } = await db.analytics.crossBucket({
171
- * bucketKey: 'sales-2025', // auth bucket
172
- * bucketKeys: ['sales-2024', 'sales-2025'],
173
- * field: 'amount',
174
- * aggregation: 'sum',
175
- * });
176
- */
177
- crossBucket(options: {
178
- bucketKeys: string[];
179
- field: string;
180
- aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';
181
- dateRange?: DateRange;
182
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<unknown>>;
183
- }
184
-
185
- export { AnalyticsClient, AnalyticsQuery, AnalyticsResponse, type BucketOptions, CountResult, DateRange, DistributionItem, FieldStatsResult, FieldTimeSeriesPoint, Filter, FilteredRecordsResult, MultiMetricItem, StorageStatsResult, SumResult, TimeSeriesPoint, TopNItem };
@@ -1,185 +0,0 @@
1
- import { a9 as HttpClient, c as AnalyticsQuery, V as RequestOptions, e as AnalyticsResponse, D as DateRange, C as CountResult, p as DistributionItem, a1 as SumResult, a2 as TimeSeriesPoint, r as FieldTimeSeriesPoint, a3 as TopNItem, F as FieldStatsResult, s as Filter, u as FilteredRecordsResult, M as MultiMetricItem, a0 as StorageStatsResult } from '../http-DTukpdAU.js';
2
- export { d as AnalyticsQueryType } from '../http-DTukpdAU.js';
3
-
4
- type AnalyticsResult<T> = Omit<AnalyticsResponse, 'data'> & {
5
- data: T;
6
- queryType: string;
7
- bucketKey: string | null;
8
- projectId: string;
9
- };
10
- /** Options accepted by every analytics method */
11
- interface BucketOptions {
12
- /**
13
- * The bucket to run the analytics query against.
14
- * Required on all analytics calls.
15
- *
16
- * @example
17
- * const { data } = await db.analytics.count({ bucketKey: 'orders' });
18
- */
19
- bucketKey: string;
20
- }
21
- declare class AnalyticsClient {
22
- private readonly http;
23
- constructor(http: HttpClient);
24
- /** Builds the path for a given bucket: /api/analytics/:bucketKey/:securityKey */
25
- private path;
26
- /**
27
- * Run any analytics query with full control over the payload.
28
- * Prefer the typed convenience methods below for everyday use.
29
- */
30
- query<T = unknown>(payload: AnalyticsQuery, options: BucketOptions & RequestOptions): Promise<AnalyticsResult<T>>;
31
- /**
32
- * Total record count, optionally scoped to a date range.
33
- *
34
- * @example
35
- * const { data } = await db.analytics.count({ bucketKey: 'orders' });
36
- * console.log(data.count);
37
- *
38
- * const { data } = await db.analytics.count({
39
- * bucketKey: 'orders',
40
- * dateRange: { startDate: '2025-01-01', endDate: '2025-12-31' },
41
- * });
42
- */
43
- count(options: {
44
- dateRange?: DateRange;
45
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<CountResult>>;
46
- /**
47
- * Value distribution (histogram) for a field.
48
- *
49
- * @example
50
- * const { data } = await db.analytics.distribution('status', { bucketKey: 'orders' });
51
- * // [{ value: 'active', count: 80 }, { value: 'archived', count: 20 }]
52
- */
53
- distribution(field: string, options: {
54
- limit?: number;
55
- order?: 'asc' | 'desc';
56
- dateRange?: DateRange;
57
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<DistributionItem[]>>;
58
- /**
59
- * Sum a numeric field, with optional group-by.
60
- *
61
- * @example
62
- * const { data } = await db.analytics.sum('revenue', { bucketKey: 'orders', groupBy: 'region' });
63
- */
64
- sum(field: string, options: {
65
- groupBy?: string;
66
- limit?: number;
67
- dateRange?: DateRange;
68
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<SumResult>>;
69
- /**
70
- * Record count grouped over time.
71
- *
72
- * @example
73
- * const { data } = await db.analytics.timeSeries({ bucketKey: 'orders', granularity: 'day' });
74
- * // [{ date: '2025-01-01', count: 42 }, ...]
75
- */
76
- timeSeries(options: {
77
- granularity?: 'hour' | 'day' | 'week' | 'month';
78
- dateRange?: DateRange;
79
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<TimeSeriesPoint[]>>;
80
- /**
81
- * Aggregate a numeric field over time.
82
- *
83
- * @example
84
- * const { data } = await db.analytics.fieldTimeSeries('revenue', {
85
- * bucketKey: 'orders',
86
- * granularity: 'month',
87
- * aggregation: 'sum',
88
- * });
89
- */
90
- fieldTimeSeries(field: string, options: {
91
- aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';
92
- granularity?: 'hour' | 'day' | 'week' | 'month';
93
- dateRange?: DateRange;
94
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<FieldTimeSeriesPoint[]>>;
95
- /**
96
- * Top N most frequent values for a field.
97
- *
98
- * @example
99
- * const { data } = await db.analytics.topN('country', 5, { bucketKey: 'users' });
100
- * // [{ label: 'US', value: 'US', count: 500 }, ...]
101
- */
102
- topN(field: string, n: number | undefined, options: {
103
- labelField?: string;
104
- order?: 'asc' | 'desc';
105
- dateRange?: DateRange;
106
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<TopNItem[]>>;
107
- /**
108
- * Statistical summary for a numeric field: min, max, avg, stddev, p50, p90, p99.
109
- *
110
- * @example
111
- * const { data } = await db.analytics.stats('score', { bucketKey: 'users' });
112
- * console.log(data.avg, data.p99);
113
- */
114
- stats(field: string, options: {
115
- dateRange?: DateRange;
116
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<FieldStatsResult>>;
117
- /**
118
- * Filtered, paginated raw records with optional field projection.
119
- * Supports filter ops: == != > < >= <= CONTAINS
120
- *
121
- * @example
122
- * const { data } = await db.analytics.records({
123
- * bucketKey: 'users',
124
- * filters: [{ field: 'role', op: '==', value: 'admin' }],
125
- * selectFields: ['email', 'createdAt'],
126
- * limit: 25,
127
- * });
128
- */
129
- records(options: {
130
- filters?: Filter[];
131
- selectFields?: string[];
132
- limit?: number;
133
- offset?: number;
134
- orderBy?: string;
135
- order?: 'asc' | 'desc';
136
- dateRange?: DateRange;
137
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<FilteredRecordsResult>>;
138
- /**
139
- * Multiple aggregations in a single call — ideal for dashboard stat cards.
140
- *
141
- * @example
142
- * const { data } = await db.analytics.multiMetric(
143
- * [
144
- * { name: 'totalRevenue', field: 'amount', aggregation: 'sum' },
145
- * { name: 'avgScore', field: 'score', aggregation: 'avg' },
146
- * ],
147
- * { bucketKey: 'orders' }
148
- * );
149
- * console.log(data.totalRevenue, data.avgScore);
150
- */
151
- multiMetric(metrics: MultiMetricItem[], options: {
152
- dateRange?: DateRange;
153
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<Record<string, number>>>;
154
- /**
155
- * Storage statistics for a bucket — total records, bytes, avg/min/max size.
156
- *
157
- * @example
158
- * const { data } = await db.analytics.storageStats({ bucketKey: 'orders' });
159
- * console.log(data.totalRecords, data.totalBytes);
160
- */
161
- storageStats(options: {
162
- dateRange?: DateRange;
163
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<StorageStatsResult>>;
164
- /**
165
- * Compare a metric across multiple buckets in one query.
166
- * Note: `bucketKey` here is used only for auth — the actual buckets
167
- * compared are specified via `bucketKeys`.
168
- *
169
- * @example
170
- * const { data } = await db.analytics.crossBucket({
171
- * bucketKey: 'sales-2025', // auth bucket
172
- * bucketKeys: ['sales-2024', 'sales-2025'],
173
- * field: 'amount',
174
- * aggregation: 'sum',
175
- * });
176
- */
177
- crossBucket(options: {
178
- bucketKeys: string[];
179
- field: string;
180
- aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';
181
- dateRange?: DateRange;
182
- } & BucketOptions & RequestOptions): Promise<AnalyticsResult<unknown>>;
183
- }
184
-
185
- export { AnalyticsClient, AnalyticsQuery, AnalyticsResponse, type BucketOptions, CountResult, DateRange, DistributionItem, FieldStatsResult, FieldTimeSeriesPoint, Filter, FilteredRecordsResult, MultiMetricItem, StorageStatsResult, SumResult, TimeSeriesPoint, TopNItem };
@@ -1,184 +0,0 @@
1
- 'use strict';
2
-
3
- // src/analytics/client.ts
4
- var AnalyticsClient = class {
5
- constructor(http) {
6
- this.http = http;
7
- }
8
- /** Builds the path for a given bucket: /api/analytics/:bucketKey/:securityKey */
9
- path(bucketKey) {
10
- return `/api/analytics/${bucketKey}/${this.http.securityKey}`;
11
- }
12
- // ── Raw query ─────────────────────────────────────────────────────────────
13
- /**
14
- * Run any analytics query with full control over the payload.
15
- * Prefer the typed convenience methods below for everyday use.
16
- */
17
- async query(payload, options) {
18
- const { bucketKey, ...rest } = options;
19
- return this.http.post(this.path(bucketKey), payload, rest);
20
- }
21
- // ── count ──────────────────────────────────────────────────────────────────
22
- /**
23
- * Total record count, optionally scoped to a date range.
24
- *
25
- * @example
26
- * const { data } = await db.analytics.count({ bucketKey: 'orders' });
27
- * console.log(data.count);
28
- *
29
- * const { data } = await db.analytics.count({
30
- * bucketKey: 'orders',
31
- * dateRange: { startDate: '2025-01-01', endDate: '2025-12-31' },
32
- * });
33
- */
34
- async count(options) {
35
- const { dateRange, ...rest } = options;
36
- return this.query({ queryType: "count", dateRange }, rest);
37
- }
38
- // ── distribution ───────────────────────────────────────────────────────────
39
- /**
40
- * Value distribution (histogram) for a field.
41
- *
42
- * @example
43
- * const { data } = await db.analytics.distribution('status', { bucketKey: 'orders' });
44
- * // [{ value: 'active', count: 80 }, { value: 'archived', count: 20 }]
45
- */
46
- async distribution(field, options) {
47
- const { limit, order, dateRange, ...rest } = options;
48
- return this.query({ queryType: "distribution", field, limit, order, dateRange }, rest);
49
- }
50
- // ── sum ────────────────────────────────────────────────────────────────────
51
- /**
52
- * Sum a numeric field, with optional group-by.
53
- *
54
- * @example
55
- * const { data } = await db.analytics.sum('revenue', { bucketKey: 'orders', groupBy: 'region' });
56
- */
57
- async sum(field, options) {
58
- const { groupBy, limit, dateRange, ...rest } = options;
59
- return this.query({ queryType: "sum", field, groupBy, limit, dateRange }, rest);
60
- }
61
- // ── timeSeries ─────────────────────────────────────────────────────────────
62
- /**
63
- * Record count grouped over time.
64
- *
65
- * @example
66
- * const { data } = await db.analytics.timeSeries({ bucketKey: 'orders', granularity: 'day' });
67
- * // [{ date: '2025-01-01', count: 42 }, ...]
68
- */
69
- async timeSeries(options) {
70
- const { granularity, dateRange, ...rest } = options;
71
- return this.query({ queryType: "timeSeries", granularity, dateRange }, rest);
72
- }
73
- // ── fieldTimeSeries ────────────────────────────────────────────────────────
74
- /**
75
- * Aggregate a numeric field over time.
76
- *
77
- * @example
78
- * const { data } = await db.analytics.fieldTimeSeries('revenue', {
79
- * bucketKey: 'orders',
80
- * granularity: 'month',
81
- * aggregation: 'sum',
82
- * });
83
- */
84
- async fieldTimeSeries(field, options) {
85
- const { aggregation, granularity, dateRange, ...rest } = options;
86
- return this.query({ queryType: "fieldTimeSeries", field, aggregation, granularity, dateRange }, rest);
87
- }
88
- // ── topN ───────────────────────────────────────────────────────────────────
89
- /**
90
- * Top N most frequent values for a field.
91
- *
92
- * @example
93
- * const { data } = await db.analytics.topN('country', 5, { bucketKey: 'users' });
94
- * // [{ label: 'US', value: 'US', count: 500 }, ...]
95
- */
96
- async topN(field, n = 10, options) {
97
- const { labelField, order, dateRange, ...rest } = options;
98
- return this.query({ queryType: "topN", field, n, labelField, order, dateRange }, rest);
99
- }
100
- // ── stats ──────────────────────────────────────────────────────────────────
101
- /**
102
- * Statistical summary for a numeric field: min, max, avg, stddev, p50, p90, p99.
103
- *
104
- * @example
105
- * const { data } = await db.analytics.stats('score', { bucketKey: 'users' });
106
- * console.log(data.avg, data.p99);
107
- */
108
- async stats(field, options) {
109
- const { dateRange, ...rest } = options;
110
- return this.query({ queryType: "stats", field, dateRange }, rest);
111
- }
112
- // ── records ────────────────────────────────────────────────────────────────
113
- /**
114
- * Filtered, paginated raw records with optional field projection.
115
- * Supports filter ops: == != > < >= <= CONTAINS
116
- *
117
- * @example
118
- * const { data } = await db.analytics.records({
119
- * bucketKey: 'users',
120
- * filters: [{ field: 'role', op: '==', value: 'admin' }],
121
- * selectFields: ['email', 'createdAt'],
122
- * limit: 25,
123
- * });
124
- */
125
- async records(options) {
126
- const { filters, selectFields, limit, offset, orderBy, order, dateRange, ...rest } = options;
127
- return this.query(
128
- { queryType: "records", filters, selectFields, limit, offset, orderBy, order, dateRange },
129
- rest
130
- );
131
- }
132
- // ── multiMetric ────────────────────────────────────────────────────────────
133
- /**
134
- * Multiple aggregations in a single call — ideal for dashboard stat cards.
135
- *
136
- * @example
137
- * const { data } = await db.analytics.multiMetric(
138
- * [
139
- * { name: 'totalRevenue', field: 'amount', aggregation: 'sum' },
140
- * { name: 'avgScore', field: 'score', aggregation: 'avg' },
141
- * ],
142
- * { bucketKey: 'orders' }
143
- * );
144
- * console.log(data.totalRevenue, data.avgScore);
145
- */
146
- async multiMetric(metrics, options) {
147
- const { dateRange, ...rest } = options;
148
- return this.query({ queryType: "multiMetric", metrics, dateRange }, rest);
149
- }
150
- // ── storageStats ───────────────────────────────────────────────────────────
151
- /**
152
- * Storage statistics for a bucket — total records, bytes, avg/min/max size.
153
- *
154
- * @example
155
- * const { data } = await db.analytics.storageStats({ bucketKey: 'orders' });
156
- * console.log(data.totalRecords, data.totalBytes);
157
- */
158
- async storageStats(options) {
159
- const { dateRange, ...rest } = options;
160
- return this.query({ queryType: "storageStats", dateRange }, rest);
161
- }
162
- // ── crossBucket ────────────────────────────────────────────────────────────
163
- /**
164
- * Compare a metric across multiple buckets in one query.
165
- * Note: `bucketKey` here is used only for auth — the actual buckets
166
- * compared are specified via `bucketKeys`.
167
- *
168
- * @example
169
- * const { data } = await db.analytics.crossBucket({
170
- * bucketKey: 'sales-2025', // auth bucket
171
- * bucketKeys: ['sales-2024', 'sales-2025'],
172
- * field: 'amount',
173
- * aggregation: 'sum',
174
- * });
175
- */
176
- async crossBucket(options) {
177
- const { bucketKeys, field, aggregation, dateRange, ...rest } = options;
178
- return this.query({ queryType: "crossBucket", bucketKeys, field, aggregation, dateRange }, rest);
179
- }
180
- };
181
-
182
- exports.AnalyticsClient = AnalyticsClient;
183
- //# sourceMappingURL=index.js.map
184
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/analytics/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { HttpClient } from '../utils/http.js';\nimport type {\n AnalyticsQuery,\n AnalyticsResponse,\n DateRange,\n Filter,\n MultiMetricItem,\n RequestOptions,\n CountResult,\n DistributionItem,\n SumResult,\n TimeSeriesPoint,\n FieldTimeSeriesPoint,\n TopNItem,\n FieldStatsResult,\n FilteredRecordsResult,\n StorageStatsResult,\n} from '../types/index.js';\n\n// Typed wrapper so callers get proper return types\ntype AnalyticsResult<T> = Omit<AnalyticsResponse, 'data'> & {\n data: T;\n queryType: string;\n bucketKey: string | null;\n projectId: string;\n};\n\n/** Options accepted by every analytics method */\nexport interface BucketOptions {\n /**\n * The bucket to run the analytics query against.\n * Required on all analytics calls.\n *\n * @example\n * const { data } = await db.analytics.count({ bucketKey: 'orders' });\n */\n bucketKey: string;\n}\n\nexport class AnalyticsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Builds the path for a given bucket: /api/analytics/:bucketKey/:securityKey */\n private path(bucketKey: string): string {\n return `/api/analytics/${bucketKey}/${this.http.securityKey}`;\n }\n\n // ── Raw query ─────────────────────────────────────────────────────────────\n\n /**\n * Run any analytics query with full control over the payload.\n * Prefer the typed convenience methods below for everyday use.\n */\n async query<T = unknown>(\n payload: AnalyticsQuery,\n options: BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<T>> {\n const { bucketKey, ...rest } = options;\n return this.http.post<AnalyticsResult<T>>(this.path(bucketKey), payload, rest);\n }\n\n // ── count ──────────────────────────────────────────────────────────────────\n\n /**\n * Total record count, optionally scoped to a date range.\n *\n * @example\n * const { data } = await db.analytics.count({ bucketKey: 'orders' });\n * console.log(data.count);\n *\n * const { data } = await db.analytics.count({\n * bucketKey: 'orders',\n * dateRange: { startDate: '2025-01-01', endDate: '2025-12-31' },\n * });\n */\n async count(\n options: { dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<CountResult>> {\n const { dateRange, ...rest } = options;\n return this.query<CountResult>({ queryType: 'count', dateRange }, rest);\n }\n\n // ── distribution ───────────────────────────────────────────────────────────\n\n /**\n * Value distribution (histogram) for a field.\n *\n * @example\n * const { data } = await db.analytics.distribution('status', { bucketKey: 'orders' });\n * // [{ value: 'active', count: 80 }, { value: 'archived', count: 20 }]\n */\n async distribution(\n field: string,\n options: { limit?: number; order?: 'asc' | 'desc'; dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<DistributionItem[]>> {\n const { limit, order, dateRange, ...rest } = options;\n return this.query<DistributionItem[]>({ queryType: 'distribution', field, limit, order, dateRange }, rest);\n }\n\n // ── sum ────────────────────────────────────────────────────────────────────\n\n /**\n * Sum a numeric field, with optional group-by.\n *\n * @example\n * const { data } = await db.analytics.sum('revenue', { bucketKey: 'orders', groupBy: 'region' });\n */\n async sum(\n field: string,\n options: { groupBy?: string; limit?: number; dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<SumResult>> {\n const { groupBy, limit, dateRange, ...rest } = options;\n return this.query<SumResult>({ queryType: 'sum', field, groupBy, limit, dateRange }, rest);\n }\n\n // ── timeSeries ─────────────────────────────────────────────────────────────\n\n /**\n * Record count grouped over time.\n *\n * @example\n * const { data } = await db.analytics.timeSeries({ bucketKey: 'orders', granularity: 'day' });\n * // [{ date: '2025-01-01', count: 42 }, ...]\n */\n async timeSeries(\n options: { granularity?: 'hour' | 'day' | 'week' | 'month'; dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<TimeSeriesPoint[]>> {\n const { granularity, dateRange, ...rest } = options;\n return this.query<TimeSeriesPoint[]>({ queryType: 'timeSeries', granularity, dateRange }, rest);\n }\n\n // ── fieldTimeSeries ────────────────────────────────────────────────────────\n\n /**\n * Aggregate a numeric field over time.\n *\n * @example\n * const { data } = await db.analytics.fieldTimeSeries('revenue', {\n * bucketKey: 'orders',\n * granularity: 'month',\n * aggregation: 'sum',\n * });\n */\n async fieldTimeSeries(\n field: string,\n options: {\n aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';\n granularity?: 'hour' | 'day' | 'week' | 'month';\n dateRange?: DateRange;\n } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<FieldTimeSeriesPoint[]>> {\n const { aggregation, granularity, dateRange, ...rest } = options;\n return this.query<FieldTimeSeriesPoint[]>({ queryType: 'fieldTimeSeries', field, aggregation, granularity, dateRange }, rest);\n }\n\n // ── topN ───────────────────────────────────────────────────────────────────\n\n /**\n * Top N most frequent values for a field.\n *\n * @example\n * const { data } = await db.analytics.topN('country', 5, { bucketKey: 'users' });\n * // [{ label: 'US', value: 'US', count: 500 }, ...]\n */\n async topN(\n field: string,\n n = 10,\n options: { labelField?: string; order?: 'asc' | 'desc'; dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<TopNItem[]>> {\n const { labelField, order, dateRange, ...rest } = options;\n return this.query<TopNItem[]>({ queryType: 'topN', field, n, labelField, order, dateRange }, rest);\n }\n\n // ── stats ──────────────────────────────────────────────────────────────────\n\n /**\n * Statistical summary for a numeric field: min, max, avg, stddev, p50, p90, p99.\n *\n * @example\n * const { data } = await db.analytics.stats('score', { bucketKey: 'users' });\n * console.log(data.avg, data.p99);\n */\n async stats(\n field: string,\n options: { dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<FieldStatsResult>> {\n const { dateRange, ...rest } = options;\n return this.query<FieldStatsResult>({ queryType: 'stats', field, dateRange }, rest);\n }\n\n // ── records ────────────────────────────────────────────────────────────────\n\n /**\n * Filtered, paginated raw records with optional field projection.\n * Supports filter ops: == != > < >= <= CONTAINS\n *\n * @example\n * const { data } = await db.analytics.records({\n * bucketKey: 'users',\n * filters: [{ field: 'role', op: '==', value: 'admin' }],\n * selectFields: ['email', 'createdAt'],\n * limit: 25,\n * });\n */\n async records(\n options: {\n filters?: Filter[];\n selectFields?: string[];\n limit?: number;\n offset?: number;\n orderBy?: string;\n order?: 'asc' | 'desc';\n dateRange?: DateRange;\n } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<FilteredRecordsResult>> {\n const { filters, selectFields, limit, offset, orderBy, order, dateRange, ...rest } = options;\n return this.query<FilteredRecordsResult>(\n { queryType: 'records', filters, selectFields, limit, offset, orderBy, order, dateRange },\n rest\n );\n }\n\n // ── multiMetric ────────────────────────────────────────────────────────────\n\n /**\n * Multiple aggregations in a single call — ideal for dashboard stat cards.\n *\n * @example\n * const { data } = await db.analytics.multiMetric(\n * [\n * { name: 'totalRevenue', field: 'amount', aggregation: 'sum' },\n * { name: 'avgScore', field: 'score', aggregation: 'avg' },\n * ],\n * { bucketKey: 'orders' }\n * );\n * console.log(data.totalRevenue, data.avgScore);\n */\n async multiMetric(\n metrics: MultiMetricItem[],\n options: { dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<Record<string, number>>> {\n const { dateRange, ...rest } = options;\n return this.query<Record<string, number>>({ queryType: 'multiMetric', metrics, dateRange }, rest);\n }\n\n // ── storageStats ───────────────────────────────────────────────────────────\n\n /**\n * Storage statistics for a bucket — total records, bytes, avg/min/max size.\n *\n * @example\n * const { data } = await db.analytics.storageStats({ bucketKey: 'orders' });\n * console.log(data.totalRecords, data.totalBytes);\n */\n async storageStats(\n options: { dateRange?: DateRange } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<StorageStatsResult>> {\n const { dateRange, ...rest } = options;\n return this.query<StorageStatsResult>({ queryType: 'storageStats', dateRange }, rest);\n }\n\n // ── crossBucket ────────────────────────────────────────────────────────────\n\n /**\n * Compare a metric across multiple buckets in one query.\n * Note: `bucketKey` here is used only for auth — the actual buckets\n * compared are specified via `bucketKeys`.\n *\n * @example\n * const { data } = await db.analytics.crossBucket({\n * bucketKey: 'sales-2025', // auth bucket\n * bucketKeys: ['sales-2024', 'sales-2025'],\n * field: 'amount',\n * aggregation: 'sum',\n * });\n */\n async crossBucket(\n options: {\n bucketKeys: string[];\n field: string;\n aggregation?: 'sum' | 'avg' | 'min' | 'max' | 'count';\n dateRange?: DateRange;\n } & BucketOptions & RequestOptions\n ): Promise<AnalyticsResult<unknown>> {\n const { bucketKeys, field, aggregation, dateRange, ...rest } = options;\n return this.query<unknown>({ queryType: 'crossBucket', bucketKeys, field, aggregation, dateRange }, rest);\n }\n}\n"]}