metrickit 0.1.2

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 (50) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +379 -0
  4. package/dist/cache-redis.d.ts +10 -0
  5. package/dist/cache-redis.js +24 -0
  6. package/dist/cache-utils.d.ts +5 -0
  7. package/dist/cache.d.ts +18 -0
  8. package/dist/catalog.d.ts +12 -0
  9. package/dist/define-metric.d.ts +37 -0
  10. package/dist/engine.d.ts +200 -0
  11. package/dist/filters/default-metadata.d.ts +28 -0
  12. package/dist/filters/index.d.ts +3 -0
  13. package/dist/filters/parse.d.ts +7 -0
  14. package/dist/filters/types.d.ts +19 -0
  15. package/dist/frontend/catalog.d.ts +24 -0
  16. package/dist/frontend/dashboard.d.ts +12 -0
  17. package/dist/frontend/format.d.ts +10 -0
  18. package/dist/frontend/index.d.ts +10 -0
  19. package/dist/frontend/markers.d.ts +19 -0
  20. package/dist/frontend/renderers.d.ts +14 -0
  21. package/dist/frontend/requests.d.ts +17 -0
  22. package/dist/frontend/stream-state.d.ts +14 -0
  23. package/dist/frontend/time.d.ts +5 -0
  24. package/dist/frontend/transport.d.ts +19 -0
  25. package/dist/frontend/types.d.ts +108 -0
  26. package/dist/frontend.d.ts +1 -0
  27. package/dist/frontend.js +752 -0
  28. package/dist/helpers/clickhouse.d.ts +27 -0
  29. package/dist/helpers/distribution.d.ts +15 -0
  30. package/dist/helpers/index.d.ts +6 -0
  31. package/dist/helpers/metric-type.d.ts +21 -0
  32. package/dist/helpers/pivot.d.ts +15 -0
  33. package/dist/helpers/prisma.d.ts +20 -0
  34. package/dist/helpers/timeseries.d.ts +6 -0
  35. package/dist/helpers.d.ts +1 -0
  36. package/dist/helpers.js +668 -0
  37. package/dist/index.d.ts +11 -0
  38. package/dist/index.js +1322 -0
  39. package/dist/orpc.d.ts +36 -0
  40. package/dist/orpc.js +1157 -0
  41. package/dist/registry.d.ts +269 -0
  42. package/dist/run-metrics.d.ts +14 -0
  43. package/dist/schemas/index.d.ts +4 -0
  44. package/dist/schemas/inputs.d.ts +19 -0
  45. package/dist/schemas/metric-type.d.ts +7 -0
  46. package/dist/schemas/output.d.ts +842 -0
  47. package/dist/schemas/time.d.ts +24 -0
  48. package/dist/time.d.ts +6 -0
  49. package/dist/type-guards.d.ts +7 -0
  50. package/package.json +91 -0
@@ -0,0 +1,269 @@
1
+ import { z } from 'zod';
2
+ import type { AnyMetricDefinition } from './define-metric.ts';
3
+ import { getOutputSchema as getOutputSchemaImpl } from './define-metric.ts';
4
+ import type { MetricCatalogMetadata } from './catalog.ts';
5
+ import type { BaseFilters, MetricResult, TimeGranularity, TimeSeriesOutput } from './schemas/index.ts';
6
+ import { OutputSchemaMap } from './schemas/index.ts';
7
+ export interface RegistryOptions<TBaseFilters extends BaseFilters = BaseFilters, TKindSchemas extends Record<string, z.ZodTypeAny> = typeof OutputSchemaMap> {
8
+ baseFilterSchema?: z.ZodType<TBaseFilters>;
9
+ kindSchemas?: TKindSchemas;
10
+ }
11
+ export declare function createRegistry<const TMetrics extends readonly AnyMetricDefinition[], TBaseFilters extends BaseFilters = BaseFilters, TKindSchemas extends Record<string, z.ZodTypeAny> = typeof OutputSchemaMap>(metrics: TMetrics, options?: RegistryOptions<TBaseFilters, TKindSchemas>): {
12
+ readonly metrics: TMetrics;
13
+ readonly baseFilterSchema: z.ZodType<TBaseFilters, unknown, z.core.$ZodTypeInternals<TBaseFilters, unknown>>;
14
+ readonly kindSchemas: TKindSchemas & {
15
+ readonly kpi: z.ZodObject<{
16
+ kind: z.ZodLiteral<"kpi">;
17
+ value: z.ZodNumber;
18
+ label: z.ZodOptional<z.ZodString>;
19
+ unit: z.ZodOptional<z.ZodEnum<{
20
+ DKK: "DKK";
21
+ EUR: "EUR";
22
+ USD: "USD";
23
+ GBP: "GBP";
24
+ SEK: "SEK";
25
+ NOK: "NOK";
26
+ PERCENTAGE: "PERCENTAGE";
27
+ }>>;
28
+ prefix: z.ZodOptional<z.ZodString>;
29
+ suffix: z.ZodOptional<z.ZodString>;
30
+ trend: z.ZodOptional<z.ZodEnum<{
31
+ up: "up";
32
+ down: "down";
33
+ flat: "flat";
34
+ }>>;
35
+ }, z.core.$strip>;
36
+ readonly timeseries: z.ZodObject<{
37
+ kind: z.ZodLiteral<"timeseries">;
38
+ granularity: z.ZodEnum<{
39
+ hour: "hour";
40
+ day: "day";
41
+ week: "week";
42
+ month: "month";
43
+ quarter: "quarter";
44
+ year: "year";
45
+ }>;
46
+ series: z.ZodArray<z.ZodObject<{
47
+ key: z.ZodString;
48
+ label: z.ZodOptional<z.ZodString>;
49
+ points: z.ZodArray<z.ZodObject<{
50
+ ts: z.ZodDate;
51
+ value: z.ZodNumber;
52
+ label: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strip>>;
54
+ chartType: z.ZodOptional<z.ZodEnum<{
55
+ line: "line";
56
+ bar: "bar";
57
+ }>>;
58
+ axis: z.ZodOptional<z.ZodEnum<{
59
+ left: "left";
60
+ right: "right";
61
+ }>>;
62
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
63
+ }, z.core.$strip>>;
64
+ }, z.core.$strip>;
65
+ readonly distribution: z.ZodObject<{
66
+ kind: z.ZodLiteral<"distribution">;
67
+ total: z.ZodNumber;
68
+ segments: z.ZodArray<z.ZodObject<{
69
+ key: z.ZodString;
70
+ label: z.ZodString;
71
+ value: z.ZodNumber;
72
+ percent: z.ZodOptional<z.ZodNumber>;
73
+ }, z.core.$strip>>;
74
+ chartType: z.ZodOptional<z.ZodEnum<{
75
+ bar: "bar";
76
+ donut: "donut";
77
+ pie: "pie";
78
+ funnel: "funnel";
79
+ }>>;
80
+ }, z.core.$strip>;
81
+ readonly table: z.ZodObject<{
82
+ kind: z.ZodLiteral<"table">;
83
+ columns: z.ZodArray<z.ZodObject<{
84
+ key: z.ZodString;
85
+ label: z.ZodString;
86
+ type: z.ZodOptional<z.ZodEnum<{
87
+ string: "string";
88
+ number: "number";
89
+ boolean: "boolean";
90
+ date: "date";
91
+ }>>;
92
+ nullable: z.ZodOptional<z.ZodBoolean>;
93
+ }, z.core.$strip>>;
94
+ rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
95
+ total: z.ZodOptional<z.ZodNumber>;
96
+ }, z.core.$strip>;
97
+ readonly leaderboard: z.ZodObject<{
98
+ kind: z.ZodLiteral<"leaderboard">;
99
+ items: z.ZodArray<z.ZodObject<{
100
+ rank: z.ZodNumber;
101
+ id: z.ZodString;
102
+ label: z.ZodString;
103
+ value: z.ZodNumber;
104
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
105
+ }, z.core.$strip>>;
106
+ total: z.ZodOptional<z.ZodNumber>;
107
+ }, z.core.$strip>;
108
+ readonly pivot: z.ZodObject<{
109
+ kind: z.ZodLiteral<"pivot">;
110
+ rowDimension: z.ZodObject<{
111
+ key: z.ZodString;
112
+ label: z.ZodString;
113
+ }, z.core.$strip>;
114
+ columnDimension: z.ZodObject<{
115
+ key: z.ZodString;
116
+ label: z.ZodString;
117
+ }, z.core.$strip>;
118
+ rows: z.ZodArray<z.ZodString>;
119
+ columns: z.ZodArray<z.ZodString>;
120
+ values: z.ZodArray<z.ZodArray<z.ZodNumber>>;
121
+ cellTooltips: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
122
+ totals: z.ZodOptional<z.ZodObject<{
123
+ rowTotals: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
124
+ columnTotals: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
125
+ grandTotal: z.ZodOptional<z.ZodNumber>;
126
+ }, z.core.$strip>>;
127
+ }, z.core.$strip>;
128
+ };
129
+ readonly metricKeys: [TMetrics[number]["key"], ...TMetrics[number]["key"][]];
130
+ readonly MetricKeySchema: z.ZodEnum<{ [k_1 in TMetrics[number]["key"]]: k_1; } extends infer T ? { [k in keyof T]: T[k]; } : never>;
131
+ readonly MetricRequestSchema: z.ZodObject<{
132
+ key: z.ZodEnum<{ [k_1 in TMetrics[number]["key"]]: k_1; } extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never>;
133
+ requestKey: z.ZodOptional<z.ZodString>;
134
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
135
+ }, z.core.$strip>;
136
+ readonly MetricsRequestSchema: z.ZodObject<{
137
+ metrics: z.ZodArray<z.ZodObject<{
138
+ key: z.ZodEnum<{ [k_1 in TMetrics[number]["key"]]: k_1; } extends infer T_2 ? { [k in keyof T_2]: T_2[k]; } : never>;
139
+ requestKey: z.ZodOptional<z.ZodString>;
140
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
141
+ }, z.core.$strip>>;
142
+ granularity: z.ZodOptional<z.ZodEnum<{
143
+ hour: "hour";
144
+ day: "day";
145
+ week: "week";
146
+ month: "month";
147
+ quarter: "quarter";
148
+ year: "year";
149
+ }>>;
150
+ from: z.ZodOptional<z.ZodDate>;
151
+ to: z.ZodOptional<z.ZodDate>;
152
+ compareToPrevious: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
153
+ disableCache: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
154
+ }, z.core.$strip>;
155
+ readonly metricsByKey: Record<TMetrics[number]["key"], AnyMetricDefinition>;
156
+ readonly getMetricByKey: {
157
+ <K extends TMetrics[number]["key"]>(key: K): Extract<TMetrics[number], {
158
+ key: K;
159
+ }>;
160
+ (key: string): AnyMetricDefinition | undefined;
161
+ };
162
+ readonly parseMetricRequestInput: <K extends TMetrics[number]["key"], TRequestKey extends string | undefined = string | undefined>(metricRequest: {
163
+ key: K;
164
+ requestKey?: TRequestKey;
165
+ filters?: Partial<Omit<z.infer<Extract<TMetrics[number], {
166
+ key: K;
167
+ }>["filterSchema"]>, "from" | "to">>;
168
+ }, options?: {
169
+ from?: Date;
170
+ to?: Date;
171
+ }) => {
172
+ metric: Extract<TMetrics[number], {
173
+ key: K;
174
+ }>;
175
+ requestKey: K;
176
+ filters: z.infer<Extract<TMetrics[number], {
177
+ key: K;
178
+ }>["filterSchema"]>;
179
+ };
180
+ readonly getOutputSchema: typeof getOutputSchemaImpl;
181
+ };
182
+ export type AnyRegistry = ReturnType<typeof createRegistry<any>>;
183
+ export type InferRegistryMetrics<R extends AnyRegistry> = R['metrics'];
184
+ export type InferBaseFilters<R extends AnyRegistry> = z.infer<R['baseFilterSchema']>;
185
+ export type InferAvailableMetricKey<R extends AnyRegistry> = InferRegistryMetrics<R>[number]['key'];
186
+ export type GetMetricByKey<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = Extract<InferRegistryMetrics<R>[number], {
187
+ key: K;
188
+ }>;
189
+ export type MetricOutputFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = Awaited<ReturnType<GetMetricByKey<R, K>['resolve']>>;
190
+ export type MetricFiltersFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = z.infer<GetMetricByKey<R, K>['filterSchema']>;
191
+ export type MetricCatalogFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = GetMetricByKey<R, K>['catalog'] extends MetricCatalogMetadata | undefined ? GetMetricByKey<R, K>['catalog'] : MetricCatalogMetadata | undefined;
192
+ type GlobalRequestFilterKeys = 'from' | 'to';
193
+ export type MetricRequestFiltersFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = Omit<MetricFiltersFor<R, K>, GlobalRequestFilterKeys>;
194
+ export type MetricKindFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = GetMetricByKey<R, K>['kind'];
195
+ export type MetricSeriesKeysFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = MetricOutputFor<R, K> extends TimeSeriesOutput<infer SeriesKey> ? SeriesKey : never;
196
+ export type MetricKeyToOutput<R extends AnyRegistry> = {
197
+ [K in InferAvailableMetricKey<R>]: MetricOutputFor<R, K>;
198
+ };
199
+ export type MetricKeyToFilters<R extends AnyRegistry> = {
200
+ [K in InferAvailableMetricKey<R>]: MetricFiltersFor<R, K>;
201
+ };
202
+ export type MetricKeyToKind<R extends AnyRegistry> = {
203
+ [K in InferAvailableMetricKey<R>]: MetricKindFor<R, K>;
204
+ };
205
+ export type MetricRequestFor<R extends AnyRegistry, K extends InferAvailableMetricKey<R> = InferAvailableMetricKey<R>, TRequestKey extends string | undefined = string | undefined> = K extends InferAvailableMetricKey<R> ? {
206
+ key: K;
207
+ requestKey?: TRequestKey;
208
+ filters?: Partial<MetricRequestFiltersFor<R, K>>;
209
+ } : never;
210
+ export interface MetricsRequestFor<R extends AnyRegistry> {
211
+ metrics: readonly MetricRequestFor<R>[];
212
+ granularity?: TimeGranularity;
213
+ from?: Date;
214
+ to?: Date;
215
+ compareToPrevious?: boolean;
216
+ disableCache?: boolean;
217
+ }
218
+ export type IsValidMetricKey<R extends AnyRegistry, K extends string> = K extends InferAvailableMetricKey<R> ? true : false;
219
+ export type MetricKeysOfKind<R extends AnyRegistry, Kind extends InferRegistryMetrics<R>[number]['kind']> = {
220
+ [K in InferAvailableMetricKey<R>]: MetricKindFor<R, K> extends Kind ? K : never;
221
+ }[InferAvailableMetricKey<R>];
222
+ export type TypedMetricResult<R extends AnyRegistry, K extends InferAvailableMetricKey<R>> = MetricResult<MetricOutputFor<R, K>>;
223
+ export type TypedMetricsResult<R extends AnyRegistry, Keys extends readonly InferAvailableMetricKey<R>[]> = {
224
+ metrics: {
225
+ [K in Keys[number]]?: TypedMetricResult<R, K>;
226
+ };
227
+ errors: Partial<Record<Keys[number], string>>;
228
+ };
229
+ type RequestedMetricResultKey<TMetricRequest> = TMetricRequest extends {
230
+ requestKey: infer TRequestKey extends string;
231
+ } ? TRequestKey : TMetricRequest extends {
232
+ key: infer TMetricKey extends string;
233
+ } ? TMetricKey : never;
234
+ export type MetricRequestResultKey<TMetricRequest> = RequestedMetricResultKey<TMetricRequest>;
235
+ export declare function getMetricResultKey<TMetricRequest extends {
236
+ key: string;
237
+ requestKey?: string;
238
+ }>(metricRequest: TMetricRequest): MetricRequestResultKey<TMetricRequest>;
239
+ export type RequestedMetricKeys<R extends AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[]> = RequestedMetricResultKey<TMetricRequests[number]>;
240
+ export type MetricRequestForResultKey<R extends AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[], TResultKey extends RequestedMetricKeys<R, TMetricRequests>> = Extract<TMetricRequests[number], {
241
+ requestKey: TResultKey;
242
+ }> extends never ? Extract<TMetricRequests[number], {
243
+ key: TResultKey;
244
+ }> : Extract<TMetricRequests[number], {
245
+ requestKey: TResultKey;
246
+ }>;
247
+ export type MetricResultForResultKey<R extends AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[], TResultKey extends RequestedMetricKeys<R, TMetricRequests>> = MetricRequestForResultKey<R, TMetricRequests, TResultKey> extends {
248
+ key: infer TMetricKey extends InferAvailableMetricKey<R>;
249
+ } ? TypedMetricResult<R, TMetricKey> : never;
250
+ export type MetricsExecutionResult<R extends AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[]> = {
251
+ metrics: {
252
+ [TResultKey in RequestedMetricKeys<R, TMetricRequests>]?: MetricResultForResultKey<R, TMetricRequests, TResultKey>;
253
+ };
254
+ errors: Partial<Record<RequestedMetricKeys<R, TMetricRequests>, string>>;
255
+ };
256
+ export type MetricResultChunkFor<R extends AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[]> = TMetricRequests[number] extends infer TMetricRequest ? TMetricRequest extends {
257
+ key: infer TMetricKey extends InferAvailableMetricKey<R>;
258
+ } ? {
259
+ key: TMetricKey;
260
+ requestKey?: RequestedMetricResultKey<TMetricRequest>;
261
+ result?: TypedMetricResult<R, TMetricKey>;
262
+ error?: string;
263
+ done: boolean;
264
+ } : never : never;
265
+ export declare function getMetric<R extends AnyRegistry, Keys extends readonly InferAvailableMetricKey<R>[], K extends Keys[number]>(result: TypedMetricsResult<R, Keys>, key: K): {
266
+ current: MetricOutputFor<R, K>;
267
+ previous: MetricOutputFor<R, K> | undefined;
268
+ } | undefined;
269
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { CacheAdapter } from './cache.ts';
2
+ import type { AnyRegistry, InferRegistryMetrics, MetricRequestFor, MetricResultChunkFor, MetricsExecutionResult, MetricsRequestFor } from './registry.ts';
3
+ export type MetricsRequest<R extends AnyRegistry = AnyRegistry> = MetricsRequestFor<R>;
4
+ export type MetricsResult<R extends AnyRegistry = AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[] = readonly MetricRequestFor<R>[]> = MetricsExecutionResult<R, TMetricRequests>;
5
+ export type MetricResultChunk<R extends AnyRegistry = AnyRegistry, TMetricRequests extends readonly MetricRequestFor<R>[] = readonly MetricRequestFor<R>[]> = MetricResultChunkFor<R, TMetricRequests>;
6
+ export interface RunMetricsOptions<TContext = unknown, R extends AnyRegistry = AnyRegistry, TRequest extends MetricsRequest<R> = MetricsRequest<R>> {
7
+ registry: R;
8
+ request: TRequest;
9
+ createContext: () => TContext | Promise<TContext>;
10
+ cache?: CacheAdapter;
11
+ hasAccess?: (metric: InferRegistryMetrics<R>[number]) => boolean;
12
+ }
13
+ export declare function runMetrics<TContext, R extends AnyRegistry, TRequest extends MetricsRequest<R>>(options: RunMetricsOptions<TContext, R, TRequest>): Promise<MetricsResult<R, TRequest['metrics']>>;
14
+ export declare function runMetricsStream<TContext, R extends AnyRegistry, TRequest extends MetricsRequest<R>>(options: RunMetricsOptions<TContext, R, TRequest>): AsyncGenerator<MetricResultChunk<R, TRequest['metrics']>, void, unknown>;
@@ -0,0 +1,4 @@
1
+ export * from './time.ts';
2
+ export * from './output.ts';
3
+ export * from './inputs.ts';
4
+ export * from './metric-type.ts';
@@ -0,0 +1,19 @@
1
+ import { z } from 'zod';
2
+ export declare const BaseFiltersSchema: z.ZodObject<{
3
+ organizationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
4
+ from: z.ZodOptional<z.ZodDate>;
5
+ to: z.ZodOptional<z.ZodDate>;
6
+ }, z.core.$strip>;
7
+ export type BaseFilters = z.infer<typeof BaseFiltersSchema>;
8
+ export declare const TimeSeriesFiltersSchema: z.ZodObject<{
9
+ organizationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
10
+ from: z.ZodDate;
11
+ to: z.ZodDate;
12
+ }, z.core.$strip>;
13
+ export type TimeSeriesFilters = z.infer<typeof TimeSeriesFiltersSchema>;
14
+ export declare function extendBaseFilters<T extends z.ZodRawShape>(shape: T): z.ZodObject<typeof BaseFiltersSchema.shape & {
15
+ [K in keyof T]: z.ZodOptional<T[K]>;
16
+ }>;
17
+ export declare function extendTimeSeriesFilters<T extends z.ZodRawShape>(shape: T): z.ZodObject<typeof TimeSeriesFiltersSchema.shape & {
18
+ [K in keyof T]: z.ZodOptional<T[K]>;
19
+ }>;
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ export declare const MetricTypeSchema: z.ZodEnum<{
3
+ TOTAL: "TOTAL";
4
+ AVG: "AVG";
5
+ PER_BUCKET: "PER_BUCKET";
6
+ }>;
7
+ export type MetricType = z.infer<typeof MetricTypeSchema>;